Center for Research in Electronic Art Technology (CREATE)
Dept. of Music, UC Santa Barbara


Squeak Smalltalk Mailing List Archive

Send mail to majordomo@create.ucsb.edu to join.

Send mail to squeak@create.ucsb.edu to post.

Index


Date:	97 May 01 5:58:17 am
From:	"Andreas Raab" <raab@isg.cs.uni-magdeburg.de>
To:		squeak@create.ucsb.edu
Subject:	[Windows] Changes files

Hello Squeakers,

I have finally found the reason for the problems with the changes 
files on Windows systems. When starting Squeak you have generally two 
choices:
a) Double click the image. This works fine.
b) Drag the image onto the Squeak application.
The latter method has a very strange behaviour. Rather than using 
the full name (i.e. squeak-1.XX.image) the 8.3 dos file name is used,
resulting in names like squeak~1.ima. The 1.19 version of squeak 
looks for those strange names and tries to find an appropriate 
changes file (such as squeak~1.cha), however, this can easily fail 
because the 8.3 file name is stored separately. 
The following sequence of operations will show what happens:

Initally we may have
squeak1-19.image       dos name    squeak~1.ima
squeak1-19.changes     dos name    squeak~1.cha

Now, we're copying the changes to a new name, say squeak1-19d.image
We have
squeak1-19.image       dos name    squeak~1.ima
squeak1-19.changes     dos name    squeak~1.cha
squeak1-19d.changes    dos name    squeak~2.cha

If the image is now MOVED to reflect the new version this results in
squeak1-19d.image      dos name    squeak~1.ima
squeak1-19.changes     dos name    squeak~1.cha
squeak1-19d.changes    dos name    squeak~2.cha

and, after deleting the old changes
squeak1-19d.image      dos name    squeak~1.ima
squeak1-19d.changes    dos name    squeak~2.cha

I'm right now hacking a function detecting the long file name for a 
given dos file name (it's strange enough that there is a win32 
function giving the dos version of the long file name but not the 
other way around). Until then, I strongly recommend starting the 
image by double-clicking.

Andreas
--
Linear algebra is your friend - Trigonometry is your enemy.
+===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+
I Department of Simulation and Graphics      Phone: +49 391 671 8065  I
I University of Magdeburg, Germany           Fax:   +49 391 671 1164  I
+=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+


Post a reply.

Go back to index.



Date: 97 May 01 7:33:14 am From: "Andreas Raab" <raab@isg.cs.uni-magdeburg.de> To: squeak@create.ucsb.edu Subject: 1.19d and Windows Hello Squeakers, the updated VM for Windows is now ready. New or updated features include: * 32 bit color support now works * TCP support in the network primitives * Reduced cpu load during idle times (from 100% to < 5%) Thanks to Blair McGlashan for pointing me to MsgWaitForMultipleObjects! * Improved crash debug handling (If the VM crashes a log containing some information about the system will be written) * Fixed problems with changes and sources (In addition to finding the correct names you will be warned if either changes or sources can't be found during startup) * The sources are now searched in the startup directory and the image directory. As usual, the files can be found at http://simsrv.cs.uni-magdeburg.de/~raab/squeak ftp://ftp.cs.uni-magdeburg.de/pub/Smalltalk/free/squeak/win32 A final note to VM recompilers: I've decided NOT to put a makefile on the server anymore because of the problems with different versions of VC++. The file README in the image/1.19d/ directory of the above contains information relevant for this. Hope you'll like it, Andreas -- Linear algebra is your friend - Trigonometry is your enemy. +===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+ I Department of Simulation and Graphics Phone: +49 391 671 8065 I I University of Magdeburg, Germany Fax: +49 391 671 1164 I +=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+

Post a reply.

Go back to index.



Date: 97 May 01 8:44:48 am From: Ranjan Bagchi <ranjan.bagchi@pobox.com> To: Squeak <squeak@create.ucsb.edu> Subject: Question of encapsulation.. Hi squeakers-- I'm curious if anyone's considered encapsulating the squeak VM into a struct (or class, if anyone wants to compile it under C++). By this I'd mean moving the symbols from a number of globals into potentially just one. This would open up the possibility of having two separate VM's running within the same application -- I don't know the system issues that'll bring up -- I'm not going to claim to understand how the exception-handling of the memory portion works, for instance, but they're likely solvable -- I hope. Curious about people's opinions.. -rj

Post a reply.

Go back to index.



Date: 97 May 01 9:22:48 am From: Paul Fernhout <kfsoft@netins.net> To: Squeak <squeak@create.ucsb.edu> Subject: Re: Question of encapsulation.. Ranjan Bagchi wrote: > I'm curious if anyone's considered encapsulating the > squeak VM into a struct (or class, if anyone wants to > compile it under C++). By this I'd mean moving the > symbols from a number of globals into potentially just > one. > > This would open up the possibility of having two separate > VM's running within the same application -- I don't know the system > issues that'll bring up -- I'm not going to claim to understand how the > exception-handling of the memory portion works, for instance, but > they're likely > solvable -- I hope. The port to the Newton is going to require this since from what I have been told the Newton C++ compiler does not allow globals. I am in the process of acquiring the Newton C++ compiler and I plan to do some work on this issue starting in a few weeks (after another project winds down). I'd be happy to build on someone else's work if they have already built such a structure. I like your idea in general too for other reasons; it would be a way to provide "sandboxes" for running downloadable Squeak applets. -Paul Fernhout Kurtz-Fernhout Software kfsoft@netins.net ======================================== Download a public beta release of our garden simulator at: http://www.gardenwithinsight.com

Post a reply.

Go back to index.



Date: 97 May 01 9:25:32 am From: James McCartney <james@clyde.as.utexas.edu> To: <squeak@create.ucsb.edu> In-Reply-To: <3368BFD3.4FECC113@pobox.com> Subject: Re: Question of encapsulation.. At 9:07 AM -0700 5/1/97, Ranjan Bagchi wrote: >Hi squeakers-- > >I'm curious if anyone's considered encapsulating the >squeak VM into a struct (or class, if anyone wants to >compile it under C++). By this I'd mean moving the >symbols from a number of globals into potentially just >one. > >This would open up the possibility of having two separate >VM's running within the same application -- I don't know the system >issues that'll bring up -- I'm not going to claim to understand how the >exception-handling of the memory portion works, for instance, but >they're likely >solvable -- I hope. The virtual machine I'm writing (not Squeak) allows multiple VMs. This requires passing a pointer to a VM's globals to any implementation routines that need them. I decided on multiple VMs to support multiprocessing rather than making VM threads = OS threads. The latter would have required getting into really experimental territory to support real time operation. I've only found one non blocking, real time, incremental, multithreadable GC algorithm and it requires copying an object every time it is written to as well as traversing a list in order to access an object. So, not too good for high performance. The question this leaves is inter-VM communication, which I'm going to do with flattening/unflattening deep copies of objects, unless someone has a better idea. --- james mccartney james@clyde.as.utexas.edu james@lcsaudio.com If you have a PowerMac check out SuperCollider, a real time synth program: ftp://mirror.apple.com//mirrors/Info-Mac.Archive/gst/snd/super-collider-demo.hqx

Post a reply.

Go back to index.



Date: 97 May 02 2:47:44 pm From: Jecel Assumpcao Jr <jecel@lsi.usp.br> To: Maloney <johnm@wdi.disney.com> Cc: squeak@create.ucsb.edu Subject: benchmarks and license (was: InterpreterSimulation) Maloney wrote: > Did you try translating our benchmark into Self and timing it > on the same machines? It would be interesting to know how it > really compares (on this one benchmark, at least). Good idea - I'll try it on Monday. Too bad I can't just cut and paste between Squeak and Self (they don't seem to be very X Window clipboard friendly...) because Mario's Smalltalk would probably handle the code with no loss of performance. Since I'll have to retype it anyway, I might as well rewrite it in Self style. > >[tinySelf 2 - persistent object store] > > Glphic CodeWorks uses such a scheme. Neat! I never saw any details on their web site. (http://www.glyphic.com/glyphic/codeworks/intro.html) > >BTW, it might be interesting to use this memory system and > >other parts of tinySelf with Squeak as well. Does releasing > >code for Squeak place any kind of restriction on using the > >same code in a commercial product? > > Nope. The license says you have to publish the source code of bug > fixes and ports of the Squeak system, but not new apps built > on top of Squeak. And you can always use it in commercial > products without paying any royalties. But all these things I am doing are changes to the VM, not applications. I will always release all the sources to my system (as I have been doing) and it will be freely distributed. It is a commercial system, however, as I will charge for its use. -- Jecel

Post a reply.

Go back to index.



Date: 97 May 02 4:43:35 pm From: lnotarfr@dc.uba.ar (Luciano Esteban Notarfrancesco) To: squeak@create.ucsb.edu Subject: changes, questions and suggestions Hi Squeakers! The folowing are some changes (bug fixes?) I made, and some questions and suggestions: 1) Cursor could be implemented as subclass of MaskedForm instead of Form... if every plataform supports that. 2) Set implements #= in 1.19d but they forgot to implement #hash, and the same happens with SequenceableCollection. The message category for #= and #hash was wrong in a couple of clases... it was 'testing' when it should be 'comparing'. 3) I changed Dictionary>>collect: to return a Bag, as the Purple Book says, and not an OrderedCollection. If this is wrong please tell me. I added Dictionary>>includesAssociation:. 4) Bags don't implement #= (nor #hash) in 1.19d, so I fixed that too. 5) I changed Bag>>add:withOccurrences: extending it to negative values of occurrences; probably this is wrong, but it resulted useful to me. Tell me what do you think. 6) Evaluate: #hola = 'hola' it answers false... and now evaluate: 'hola' = #hola it anwers true! I think #hola = 'hola' should answer true too... but in such case we should change also the hash method (both #hola and 'hola' should have the same hash code). What do you think? --- Luciano The folowing are the changes: 'From Squeak 1.19d of April 13, 1997 on 2 May 1997 at 12:05:25 pm'! !Bag reorganize! ('accessing' at: at:put: size sortedCounts sortedElements) ('testing' includes: occurrencesOf:) ('converting' asBag asSet) ('comparing' = hash) ('adding' add: add:withOccurrences:) ('removing' remove:ifAbsent:) ('enumerating' do:) ('private' contents setDictionary) ! !Bag methodsFor: 'converting'! asBag self class == Bag ifFalse: [^super asBag]! asSet ^contents keys "I assume there are no 0 values in the contents dictionary."! ! !Bag methodsFor: 'comparing'! = aBag | otherContents | (aBag isKindOf: Bag) ifFalse: [^false]. contents size = (otherContents _ aBag contents) size ifFalse: [^false]. contents associationsDo: [ :assoc | (otherContents at: assoc key ifAbsent: [^false]) = assoc value ifFalse: [^false] ]. ^true! hash ^self contents hash! ! !Bag methodsFor: 'adding'! add: anObject withOccurrences: anInteger "Add the element anObject to the receiver. Do so as though the element were added anInteger number of times. Answer newObject. Note: if anInteger is negative, anObject is removed 0-anInteger times." | newCount | newCount _ (contents at: anObject ifAbsent: [0]) + anInteger. newCount = 0 ifTrue: [ contents removeKey: anObject ifAbsent: [] ] ifFalse: [ newCount < 0 ifTrue: [self errorNotFound] ifFalse: [contents at: anObject put: newCount] ]. ^anObject! ! !Bag methodsFor: 'private'! contents ^contents ! ! !SequenceableCollection methodsFor: 'comparing'! hash ^self inject: 0 into: [ :hashValue :each | hashValue + each hash]! ! !Set reorganize! ('testing' includes: occurrencesOf:) ('comparing' = hash) ('adding' add:) ('removing' remove:ifAbsent:) ('enumerating' collect: do: doWithIndex:) ('private' array atNewIndex:put: copy findElementOrNil: fixCollisionsFrom: fullCheck grow growSize init: keyAt: noCheckAdd: rehash scanFor: size swap:with: withArray:) ('accessing' asArray someElement) ('objects from disk' readDataFrom:size:) ! !Set methodsFor: 'comparing'! hash "Answer the hash code for the members of the set. Since order is unimportant, we use a commutative operator to compute the hash value." ^self inject: self size into: [ :hashValue :each | hashValue + each hash]! ! !Dictionary methodsFor: 'testing'! includesAssociation: anAssociation ^anAssociation value = (self associationAt: anAssociation key ifAbsent: [^false]) value! ! !Dictionary methodsFor: 'enumerating'! collect: aBlock "Evaluate aBlock with each of my values as the argument. Collect the resulting values into a collection that is like me. Answer with the new collection." | newCollection | newCollection _ Bag new: self size. self do: [:each | newCollection add: (aBlock value: each)]. ^ newCollection! !

Post a reply.

Go back to index.



Date: 97 May 03 7:02:52 pm From: dave <drs@cs.wisc.edu> To: squeak@create.ucsb.edu Subject: How do I regenerate the VM source code? Greetings Squeak Gurus, How do I regenerate the VM source code, and is it possible to do this such that the result is not inlined? Ideally I'd like to end up with a bunch of small pieces I could individually test-bed. Maybe someone has already done this? Thanks very much in advance, dave [please mail replies, as I am not currently on the list] drs@cs.wisc.edu

Post a reply.

Go back to index.



Date: 97 May 03 7:32:13 pm From: Maloney <johnm@wdi.disney.com> To: drs@cs.wisc.edu Cc: squeak@create.ucsb.edu In-Reply-To: <336BF3DC.75BB@cs.wisc.edu> Subject: Re: How do I regenerate the VM source code? >Greetings Squeak Gurus, > >How do I regenerate the VM source code, and is it possible to do this >such that the result is not inlined? Ideally I'd like to end up with >a bunch of small pieces I could individually test-bed. Maybe someone >has already done this? In a Squeak workspace, evaluate the following: Interpreter translate: 'Interp.c' doInlining: false If you look at the implementation of this method, you can also figure out how to translate, say, just the object memory or BitBlt or the interpreter. -- John

Post a reply.

Go back to index.



Date: 97 May 04 7:46:24 am From: Ranjan Bagchi <ranjan.bagchi@pobox.com> To: squeak@create.ucsb.edu Subject: Re: How do I regenerate the VM source code? Maloney wrote: > >Greetings Squeak Gurus, > > > >How do I regenerate the VM source code, and is it possible to do > this > >such that the result is not inlined? Ideally I'd like to end up > with > >a bunch of small pieces I could individually test-bed. Maybe > someone > >has already done this? > > In a Squeak workspace, evaluate the following: > > Interpreter translate: 'Interp.c' doInlining: false > > If you look at the implementation of this method, you can also > figure out how to translate, say, just the object memory or > BitBlt or the interpreter. > > -- John I just did this for the first time yesterday (with inlining on). Some notes: *) It takes a long time to run.. on my P120/16M laptop it ran for several hours. I'm not sure if its because it built up some mongo data structures and the PC was paging, or not, but it was surprising.. gave me plenty of time to read old posting to the squeak mailing list, though.. :-) *) The code that it produces doesn't have linefeeds.. this matters only if you're running on a Windows box, I guess.. I'm going to stick my FilteringStream object in there so I don't have to convert the source after the fact. *) The produced code is identical (or at least was with the inlined run I did yesterday) to that which produced squeak. Which is the way it's supposed to be, but I still think it's cool that the only thing that's different is the timestamp and the lack of linefeeds. *) The thing I'm playing with now -- The code it produces will utterly fail to compile under C++. Mainly because K&R C doesn't have a problem with the int-declared functions not returning anything -- I think the default return is 0, but I need to check. I'm curious what people think the issues would be in modifying the C-Generating classes to generate good C++. The 'right thing' might be to have a bunch of the functions which don't return anything declare themselves as void, but I suppose a kludge would be to have them stick a 'return 0' line at the end of every int-declared function. I'm not sure how this would effect code generation -- certainly compiler-dependent, I'd guess. By the way, what test-objects do people who've worked with the code generator use to verify correctness? It'd certainly be useful if I only needed to check a few pages of code and a run would take a few seconds as opposed to the time needed to regenerate the system. Anyway.. thanks, -rj

Post a reply.

Go back to index.



Date: 97 May 04 9:40:01 am From: Ian Piumarta <piumarta@prof.inria.fr> To: ranjan.bagchi@pobox.com, squeak@create.ucsb.edu Subject: Re: How do I regenerate the VM source code? > *) It takes a long time to run.. on my P120/16M laptop it > ran for several hours. It shouldn't take that long. On my 133MHz pentium laptop it takes less than ten minutes. Ian

Post a reply.

Go back to index.



Date: 97 May 04 10:07:20 am From: Dan Ingalls <DanI@wdi.disney.com> To: Ranjan Bagchi <ranjan.bagchi@pobox.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <336CA694.6934DAB0@pobox.com> Subject: Re: How do I regenerate the VM source code? >> In a Squeak workspace, evaluate the following: >> >> Interpreter translate: 'Interp.c' doInlining: false > >*) It takes a long time to run.. on my P120/16M laptop it >ran for several hours. I'm not sure if its because it built up some >mongo data structures and the PC was paging, >or not, but it was surprising.. gave me plenty of time to >read old posting to the squeak mailing list, though.. :-) There's something really wrong with this. It runs on my Mac (8500/180) in= 56 seconds. With inlining it takes about 4 times as long. It does make up= some data structures, but nothing truly mongo -- I think it will run to= completion with only 2M of free space to begin with.

Post a reply.

Go back to index.



Date: 97 May 05 2:28:11 am From: "Andreas Raab" <raab@isg.cs.uni-magdeburg.de> To: Ranjan Bagchi <ranjan.bagchi@pobox.com> Cc: squeak@create.ucsb.edu Subject: Re: How do I regenerate the VM source code? > I just did this for the first time yesterday (with inlining > on). Some notes: > > *) It takes a long time to run.. on my P120/16M laptop it > ran for several hours. I'm not sure if its because it built up some > mongo data structures and the PC was paging, > or not, but it was surprising.. gave me plenty of time to > read old posting to the squeak mailing list, though.. :-) It must not take that long. Even on my 486DX2/66 :-( at work it takes not more than an hour. Perhaps you have a very low priority for background processes. I've found that these settings are not very suited for running active apps in the background. > *) The code that it produces doesn't have linefeeds.. this matters only > if you're running on a Windows box, I guess.. > I'm going to stick my FilteringStream object in there so I don't have to > convert the source after the fact. I've always used Ians cr2lf converter for this. > *) The thing I'm playing with now -- The code it produces will utterly > fail to compile under C++. Mainly because K&R C doesn't have a problem > with the int-declared functions not returning anything -- I think the Depends on your compiler. MS VC++ accepts this issuing a warning about it (I've explicitly turned this off in the sq.h file). > default return is 0, but I need to check. I'm curious what people think > the issues would be in modifying the C-Generating classes to generate > good C++. What is "good C++" ? The idea - as far as I understand it - is to have the complete VM written in Smalltalk and the generated C code to be fast. Creating C++ classes (what I suspect you mean with good C++) would probably introduce a significant overhead. However, I would like the idea of merging the globals into a structure - this would allow me to put the whole VM into a DLL and let several images being run by the same VM. Andreas -- Linear algebra is your friend - Trigonometry is your enemy. +===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+ I Department of Simulation and Graphics Phone: +49 391 671 8065 I I University of Magdeburg, Germany Fax: +49 391 671 1164 I +=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+

Post a reply.

Go back to index.



Date: 97 May 05 2:52:21 am From: Hans-Martin Mosner <hm.mosner@cww.de> To: Squeak Mailing List <squeak@create.ucsb.edu> Subject: Block Closures - state of affairs Hi Squeakers, my Block closure efforts are getting somewhere. I've succeeded to compile blocks with closure semantics and execute them. The compiler changes are not complete yet, but the initial ideas work out quite well. I did not yet do anything on the debugger and decompiler, and I'm not absolutely sure whether the C translator will work with the compiler changes (but I think it should). Here's how my code currently works: A new class 'Block' represents block closures. Blocks have 2 instance variables: method <CompiledMethod> the method executed by the block home <MethodContext> the context in which the block is defined, may be nil for clean blocks Block temporaries are possible, and block args are handles just like method args now. The interpreter changes are very moderate: only the #primitiveValue and #primitivaValueWithArguments methods are significantly modified, and there are 2 additional class vars for the inst var indices of the 2 Block variables. Like the VisualWorks BlockClosure, a Block is the receiver in the context of its method. Accesses to self, inst vars and outer temporaries or arguments are done with messages sent to the Block. (At the moment, accesses to outer temps are not yet implemented). The #blockCopy: mechanism is not used for creation, instead a message #newBlock: is sent to the block's method, with the containing context as parameter (#newBlock without a parameter is sent for clean blocks). Similarly, the block return is replaced by a normal message return. Method returns from blocks are not yet implemented, but will be done using messages sent to the Block. The class BlockContext will be completely obsoleted, as the block method's activations are normal MethodContexts. I did not yet look where in the bytecode set instructions to access outer temps etc. could fit. My gut feeling is that this should be decided really late, when the whole mechanism works nicely with message sends. My current transition plan is as follows: 1. Create a VM which can handle old blocks as well as new blocks (mostly done) 2. Change the image to use only new blocks. 3. Create a VM that can handle only new blocks (cleaning up any residues of the old BlockContext stuff) 4. Clean up the image to remove any references to old block stuff. 5. Streamline image and VM with bytecodes for outer variable access etc. and change the SpecialObjects and SpecialSelectors to account for the removal of old blocks. It will take quite some weeks as I can only do it in scarce free time... If someone is willing to invest some work into the debugger and/or decompiler to understand new blocks I would be very grateful. I have not yet decided whether I should make the current work-in-progress available to other developers, as it is quite incomplete. Maybe at the end of this week... So long, Hans-Martin

Post a reply.

Go back to index.



Date: 97 May 05 2:51:46 am From: Hans-Martin Mosner <hm.mosner@cww.de> To: Squeak Mailing List <squeak@create.ucsb.edu> Subject: Block Closures - state of affairs Hi Squeakers, my Block closure efforts are getting somewhere. I've succeeded to compile blocks with closure semantics and execute them. The compiler changes are not complete yet, but the initial ideas work out quite well. I did not yet do anything on the debugger and decompiler, and I'm not absolutely sure whether the C translator will work with the compiler changes (but I think it should). Here's how my code currently works: A new class 'Block' represents block closures. Blocks have 2 instance variables: method <CompiledMethod> the method executed by the block home <MethodContext> the context in which the block is defined, may be nil for clean blocks Block temporaries are possible, and block args are handles just like method args now. The interpreter changes are very moderate: only the #primitiveValue and #primitivaValueWithArguments methods are significantly modified, and there are 2 additional class vars for the inst var indices of the 2 Block variables. Like the VisualWorks BlockClosure, a Block is the receiver in the context of its method. Accesses to self, inst vars and outer temporaries or arguments are done with messages sent to the Block. (At the moment, accesses to outer temps are not yet implemented). The #blockCopy: mechanism is not used for creation, instead a message #newBlock: is sent to the block's method, with the containing context as parameter (#newBlock without a parameter is sent for clean blocks). Similarly, the block return is replaced by a normal message return. Method returns from blocks are not yet implemented, but will be done using messages sent to the Block. The class BlockContext will be completely obsoleted, as the block method's activations are normal MethodContexts. I did not yet look where in the bytecode set instructions to access outer temps etc. could fit. My gut feeling is that this should be decided really late, when the whole mechanism works nicely with message sends. My current transition plan is as follows: 1. Create a VM which can handle old blocks as well as new blocks (mostly done) 2. Change the image to use only new blocks. 3. Create a VM that can handle only new blocks (cleaning up any residues of the old BlockContext stuff) 4. Clean up the image to remove any references to old block stuff. 5. Streamline image and VM with bytecodes for outer variable access etc. and change the SpecialObjects and SpecialSelectors to account for the removal of old blocks. It will take quite some weeks as I can only do it in scarce free time... If someone is willing to invest some work into the debugger and/or decompiler to understand new blocks I would be very grateful. I have not yet decided whether I should make the current work-in-progress available to other developers, as it is quite incomplete. Maybe at the end of this week... So long, Hans-Martin

Post a reply.

Go back to index.



Date: 97 May 05 7:15:10 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: Dan Ingalls <DanI@wdi.disney.com> Cc: Ranjan Bagchi <ranjan.bagchi@pobox.com>, Squeak@create.ucsb.edu In-Reply-To: <v03007803af9286bc47fa@[206.16.10.79]> Subject: Re: How do I regenerate the VM source code? At 14:38 -0400 5/4/97, Dan Ingalls wrote: >>> In a Squeak workspace, evaluate the following: >>> >>> Interpreter translate: 'Interp.c' doInlining: false >> >>*) It takes a long time to run.. on my P120/16M laptop it >>ran for several hours. I'm not sure if its because it built up some >>mongo data structures and the PC was paging, >>or not, but it was surprising.. gave me plenty of time to >>read old posting to the squeak mailing list, though.. :-) > >There's something really wrong with this. It runs on my Mac (8500/180) in >56 seconds. With inlining it takes about 4 times as long. It does make >up some data structures, but nothing truly mongo -- I think it will run to >completion with only 2M of free space to begin with. On my 9500/200 using 1.19d it takes about the same: Time millisecondsToRun: [ Interpreter translate: 'Interp.c' doInlining: false ] 48333 I give Squeak 15Megs though. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 05 8:43:56 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: lnotarfr@dc.uba.ar (Luciano Esteban Notarfrancesco) Cc: squeak@create.ucsb.edu In-Reply-To: <m0wNHP7-000j1fC@milagro.dc.uba.ar> Subject: Re: changes, questions and suggestions At 8:25 -0400 5/2/97, Luciano Esteban Notarfrancesco wrote: >Hi Squeakers! > >The folowing are some changes (bug fixes?) I made, and some questions >and suggestions: > >...SNIP... > >!Bag methodsFor: 'converting'! >asBag > self class == Bag ifFalse: [^super asBag]! Hi: I just skimmed your post but did note one thing. (I hope I'm not missing something obvious here :-). One doesn't typically test for class equality and this particular test is present just to force Bag to answer self, but let any potential future subclasses have access to the Bag superclass method of the same name. Since there are no Bag subclasses, it seems odd to assume that they will be ill designed and require such coding to work properly. asBag in Bag should simply be (but see below): asBag ^ self If potential future subclasses need to invoke the asBag in Bags parent, then they are ill designed (ie, in the wrong place). I admit that a similar situation does exist with Set, but then the subclasses of Set may well not belong where they are. Another issue, often ignored in other implementations, is whether an asZot method should sometimes answer the receiver and sometimes answer a different collection, making it hard to know if a copy is needed to get a fresh copy or if one already has a fresh copy. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 05 10:14:39 am From: Ranjan Bagchi <ranjan.bagchi@pobox.com> To: Ian Piumarta <piumarta@prof.inria.fr>, Dan Ingalls <DanI@wdi.disney.com>, "\"David N. Smith\"" <dnsmith@watson.ibm.com>, Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE> Cc: Squeak <squeak@create.ucsb.edu> Subject: Performance numbers Hi -- As everyone's pointed off, my report of several hours to generate an inlined source file is way out of line with everyone's experiences.. I ran it again, this time with only Squeak running, and I came across numbers roughly in line with others -- about 4 and a half minutes to produced noninlined source, and about 4x that for inlining. I'm not sure what caused the slowdown I reported.. I was running a debug build of 1-19d in VC++ which could do it, and I was running it in the background under windows with Netscape's mail reader in the foreground.. I only have 16 megs in here, so it certainly could have been paging wildly.. Hopefully I didn't cause anyone trouble with that report.. -rj

Post a reply.

Go back to index.



Date: 97 May 05 11:29:02 am From: gregory@eng.adaptec.com (Greg Gritton x2386) To: squeak@create.ucsb.edu Cc: gregory@eng.adaptec.com Subject: Accessing source code in 1.18 Hi, I am running the Suqeak version 1.18, using the distribution in ftp://ftp.create.ucsb.edu/pub/Smalltalk/Squeak/unix/ using the image and source files from the Squeak-1.18 subdirectory and the precompiled VM from precompiled/SqueakVM-1.18-i581-linux1.2 and precompiled/SqueakVM-1.18-sparc-sunos4.1. I have not modified any of the files. I placed all of the files in the same directory. My directory listing looks like: InterpTest.c Squeak1.18.changes.txt sq.h InterpTestInline.c SqueakV1.sources sqFilePrims.c Makefile SqueakV1.sources.txt sqSoundPrims.c Makefile.dec SqueakVM-1.18-i586-linux1.2 sqUnixConfig.h Makefile.linux SqueakVM-1.18-sparc-sunos4.1* sqUnixDirectory.c Makefile.orig clone.image sqUnixJoystick.c Makefile.sun cr2lf* sqUnixSound.c Squeak1.18.changes lf2cr* sqXWindow.c Unfortunately, when I am looking at the source code in the class browser, the correct source for many of the methods, such as "Squeak Interpreter / ObjectMemory / interpreter access / fetchClassOf:" is not found. Instead it regenerates the source, using argument and temporary names such as t1 and t2. On the other hands, it does find the source for many methods, such as: "Collections-Sequenceable / OrderedCollection / accessing / after:" The source for the methods does exist. I can find it manually in the Squeak1.18.changes.txt (.txt is after running cr2lf) file. Has anyone else experienced this problem or know of the solution? Greg Gritton

Post a reply.

Go back to index.



Date: 97 May 05 12:50:04 pm From: Tim Rowledge <rowledge@interval.com> To: Squeak mailinglist <squeak@create.ucsb.edu> Subject: 32bpp Forms problem on PC I've read of some problems with using 32bpp Forms on the PC, where the form comes out all-black. There is no problem on the Mac or Acorn. Andreas suggested explicitly checking for pixeldepth == 32, and indeed it seems to work. I was puzzl ed though, since it looked like his fix code was redundant. It turns out that the culprit is a piece of C code that reads mask = (1 << pixeldepth) -1; which in the case of pixeldepth == 32, we would reasonably expect to result in mask == -1 . Sadly, on an x86, the shift of 1 by 32 places results in >1< not 0! Thus our mask is set to 0 and the form is displayed in black. Wrapping the fix in a suitable macro might be worth doing, since other machines would only be wasting time on the check. If anyone feels like changing the code, it would probably be worth altering the sourcePixMask _ (1 bitShift: ..... to sourcePixMask _ (1 << .... and avoid a bit more wasted work. tim -- Tim Rowledge: rowledge@interval.com (w) +1 (415) 856-7230 (w) tim@sumeru.stanford.edu (h) <http://sumeru.stanford.edu/tim>

Post a reply.

Go back to index.



Date: 97 May 06 9:55:01 am From: Dan Ingalls <DanI@wdi.disney.com> To: Jean Francois Veillette <jfv@hasc.com> Cc: Squeak@create.ucsb.edu Subject: Port to NeXTSTEP 3.3 / OPENSTEP 4.1, 4.2 / RHAPSODY M. Veillette - At this time, the core Squeak team is not working on a NextStep port. = However a number of other people are developing Squeak, and I will post= this reply to the more active Squeak mailing list so that others with a= similar interest may contact you. Glad to hear you are enjoying Squeak. - Dan Ingalls ----------------------------------------- >From: Jean Francois Veillette <jfv@hasc.com> >Date: Mon, 5 May 1997 17:59:36 -0400 >To: squeak@research.apple.com >Subject: Port to NeXTSTEP 3.3 / OPENSTEP 4.1, 4.2 / RHAPSODY > > >As a NEXTSTEP/OPENSTEP user, I would like to know if your team plan to port >Squeak on NEXTSTEP/OPENSTEP/RHAPSODY (all of them, or just one of them). = If not your team >, >do you know some porting efforts on thoses platform, and how to contact= them ? > >I currently use the Linux port and I'm very happy with it ! Except the= fact that I would prefer it to run on my NeXTSTation. > >You made a verry great job ! Continue you good work ! > >Thank's ! > >- jfv >Jean-Francois Veillette >Sherbrooke, Quebec, Canada >jfv@hasc.com

Post a reply.

Go back to index.



Date: 97 May 06 9:31:57 pm From: dave <drs@cs.wisc.edu> To: squeak@create.ucsb.edu Subject: Some Undeclared ID's in the Non-inlined Output of the Code Generator Greetings fellow Squeaks, With Inlining turned off, the C Code Generator outputs code for the Interpreter that contains a few undeclared variables, and this prevents recompilation. The other two portions ( the ObjectMemory and the BitBlitter) compile like champs. This is a partial list of the pseudo-code ids: SmallContextSize LargeContextSize ClassString ClassBlockContext ClassMethodContext SpecialSelectors Some of them seem to be fairly straightforward substitutions: contextEnd = newContext + SmallContextSize; becomes: contextEnd = newContext + 76; Others are more complex, and this is where my problem lies, e.g., success((rcvrClass == (splObj(ClassBlockContext))) || (rcvrClass == (splObj(ClassMethodContext)))); this appears to expand to: l25: /* begin success: */ t4 = (t2 == (longAt((specialObjectsOop + 4) + (11 * 4)))) || (t2 == (longAt((specialObjectsOop + 4) + (10 * 4)))); "specialObjectsOop" is an integer that appears only in the Inlined version. "t2" and "t4" are internal variables in the inlined interpret() function. Anyway, my question is how to safely substitute these identifiers in the non-inlined code with something that works. Hopefully it's fairly trivial... ;-) But of course it probably isn't. Best Regards, dave

Post a reply.

Go back to index.



Date: 97 May 07 9:49:10 am From: Maloney <johnm@wdi.disney.com> To: drs@cs.wisc.edu Cc: squeak@create.ucsb.edu In-Reply-To: <33700B3A.450D@cs.wisc.edu> Subject: Re: Some Undeclared ID's in the Non-inlined Output of the Code Generator --============_-1349093429==_============ Content-Type: text/plain; charset="us-ascii" Dave, Re: With Inlining turned off, the C Code Generator outputs code for the Interpreter that contains a few undeclared variables, and this prevents recompilation. The other two portions ( the ObjectMemory and the BitBlitter) compile like champs. Note: This is really a problem with translating the code for the modules of the VM separately, not with generating non-inlined code. The problem is just that the Interpreter depends on some of the constants (represented as class variables in Smalltalk) defined in the ObjectMemory. I'm enclosing two methods that allow you to file out just the interpreter. You'll also need to make up a header file with all the function prototypes included in the full translation plus the following imported variable declarations: /*** Imported Variables ***/ extern int endOfMemory; extern int falseObj; extern int freeBlock; extern int freeLargeContexts; extern int freeSmallContexts; extern int interruptCheckCounter; extern int lastHash; extern int lowSpaceThreshold; extern unsigned char *memory; extern int memoryLimit; extern int nilObj; extern int remapBuffer[26]; extern int remapBufferCount; extern int signalLowSpace; extern int specialObjectsOop; extern int trueObj; extern int youngStart; By doing this, I was able to get a clean compile of the Interpreter as a separate module. Good luck! -- John --============_-1349093429==_============ Content-Type: multipart/appledouble; boundary="============_-1349093429==_D============" --============_-1349093429==_D============ Content-Transfer-Encoding: base64 Content-Type: application/applefile; name="%SeparateInterpTranslation.cs" Content-Disposition: attachment; filename="%SeparateInterpTranslation.cs" AAUWBwACAAAAAAAAAAAAAAAAAAAAAAAAAAIAAAADAAAAMgAAABwAAAAJAAAATgAAACBT ZXBhcmF0ZUludGVycFRyYW5zbGF0aW9uLmNzVEVYVFIqY2gBAAEMA0iAEAAAAAAAAAAA AAAAAAAAAAA= --============_-1349093429==_D============ Content-Type: text/plain; name="SeparateInterpTranslation.cs"; charset="us-ascii" Content-Disposition: attachment; filename="SeparateInterpTranslation.cs" 'From Squeak 1.19d of April 13, 1997 on 7 May 1997 at 10:07:02 am'! !CCodeGenerator methodsFor: 'public'! addConstantsOfClass: aClass "Add the constants variables of the given class to the code base." self checkClassForNameConflicts: aClass. aClass classPool associationsDo: [ :assoc | constants at: assoc key put: (TConstantNode new setValue: assoc value)]. ! ! !Interpreter class methodsFor: 'translation'! translateInterpreterOnly: fileName doInlining: inlineFlag "Time millisecondsToRun: [ Interpreter translateInterpreterOnly: 'InterpTest.c' doInlining: false. Smalltalk beep]" | cg | BitBltSimulation initialize. Interpreter initialize. ObjectMemory initialize. cg _ CCodeGenerator new initialize. cg addClass: Interpreter. Interpreter declareCVarsIn: cg. cg addConstantsOfClass: BitBltSimulation. cg addConstantsOfClass: ObjectMemory. cg storeCodeOnFile: fileName doInlining: inlineFlag. ! ! --============_-1349093429==_D============-- --============_-1349093429==_============--

Post a reply.

Go back to index.



Date: 97 May 07 10:56:27 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: Float bug in Squeak All float fans: On my PPC I get these strange results; the first two are OK, but then things get very odd, with various bizare values of zero: 13r0.0e0 0.0 14r0.0e0 0.0 15r0.0e0 0.0622222222222223 16r0.0e0 0.0546875 17r0.0e0 0.0484429065743945 These don't work too well either: 16r1.0e0 1.0546875 16r1.0e1 1.054931640625 16r1.0e2 1.05517578125 16r1.0e3 1.055419921875 and even odder, these seem to work: 13r1.0e0 1.0 13r1.0e1 13.0 13r1.0e10 1.37858491849e11 "1.0 * (13 raisedToInteger: 10) = 1.37858491849e11" 10r1.0e10 9.99999999999997e9 It turns out that Squeak neither supports exponents in floats with a radix specification greater than 14 (oddly that's the digit value of $e) nor does it seem to issue an error message in these cases. But, note that in Float>>printOn: aStream base: base there is the code: digitCount := 2r1.0e52 2r1.0e52 evaluates to: 4.50359962737047e15 and: 2r1.0e52 printHex evaluates to:'1.0000000000000e34' which is correct since the 34 is in hex and is 50 in decimal. (printHex is not a part of the Squeak image.) Thus it is intended to work and is not accidental that it does. So, we have a sometimes it works, sometimes it doesn't situation. The code in question is Number>>readFrom:, and its friends in Number and Integer (and maybe other Number classes). Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 07 11:18:41 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: asFraction is cute but broken (LONG MESSAGE) All floating point fans: The asFraction method in Squeak tries to answer a 'cute' answer rather than a 'correct' one. It is slow and relatively useless. Float pi asFraction answers: (355/113) and: (355/113) asFloat answers: 3.14159292035398 BUT: Float pi answers: 3.14159265358979 which differs from the fractional version after the 5th digit. Not too cute. Now try: 0.12345678901234567890e-100 asFraction Go get coffee. After a while, on my PPC where Squeak has 15 megs, it runs out of memory. I find these kinds of answers (wrong and none) to be completely unsatisfactory. I suggest that asFraction be dropped (or renamed asApproximateFraction) and that a proper asFraction method be substituted. It is hard to do one in Smalltalk using portable floating point operations. Here is one that makes an assumption about byte ordering and that runs on my PPC. To run it on other platforms it may be necessary to reorder the bytes in shifty; the rest should work. asTrueFraction " Answer a fraction that EXACTLY represents self, a double precision IEEE floating point number. (It tears an IEEE float into its components; it assumes 'correct' byte ordering; runs on PPC.) " | shifty sign exp fraction | shifty := ((self at: 1) bitShift: 32) bitOr: (self at: 2). sign := (shifty bitShift: -63) = 0 ifTrue: [1] ifFalse: [-1]. exp := (shifty >> 52) bitAnd: 16r7FF. fraction := shifty bitAnd: 16r000FFFFFFFFFFFFF. (exp = 0) & (fraction = 0) ifTrue: [ ^ 0 ]. fraction := fraction bitOr: 16r0010000000000000. exp := exp - 16r3FF. " Validate that the dismemberment was correct " (sign * fraction / (2 raisedToInteger: 52 - exp)) asFloat = self ifFalse: [self error: 'asFraction validation failed' ]. ^ sign * fraction / (2 raisedToInteger: 52 - exp) It basically tears apart an IEEE float (and rebuilds it as a validation test), and then (last line) answers a fraction which exactly represents the float. The validation test can be removed with a non-trivial improvement in performance. The code should either test for endiness and reverse the bytes, or it should be implemented as a primitive. The later solution would allow ports to non-IEEE hardware without breaking (though there are other places in Float that make an assumption of IEEEness.) Float pi asTrueFraction answers: (884279719003555/281474976710656) That, converted using asFloat, answers: 3.14159265358979 which is exactly the answer from Float pi. Then: 0.12345678901234567890e-100 asTrueFraction does not run out of memory, but answers: (7783112265042257/63043209914231166739646464160229782088...snip...) with a very long denominator; the result, converted with asFloat, answers: 1.23456789012349e-101 Note that: 0.12345678901234567890e-100 evaluates to the same result: 1.23456789012349e-101 ======================================================================== Here are two longer tests, with their results: " A test using all digits in a double float " | x n | x := 0.1234567890123456789e11. n := 10. 30 timesRepeat: [ Transcript cr; show: n printString, ' ', x printString, ' ', x asTrueFraction printString, ' ', x asTrueFraction asFloat printString. x := x / 10. n := n - 1. ]. 10 1.23456789012345e10 (6472691299770469/524288) 1.23456789012345e10 9 1.23456789012345e9 (5178153039816375/4194304) 1.23456789012345e9 8 1.23456789012345e8 (1035630607963275/8388608) 1.23456789012345e8 7 1.23456789012346e7 (207126121592655/16777216) 1.23456789012346e7 6 1.23456789012346e6 (41425224318531/33554432) 1.23456789012346e6 5 123456.789012345 (8483885940435149/68719476736) 123456.789012345 4 12345.6789012346 (6787108752348119/549755813888) 12345.6789012346 3 1234.56789012346 (5429687001878495/4398046511104) 1234.56789012346 2 123.456789012346 (1085937400375699/8796093022208) 123.456789012346 1 12.3456789012346 (3474999681202237/281474976710656) 12.3456789012346 0 1.23456789012346 (5559999489923579/4503599627370496) 1.23456789012346 -1 0.123456789012346 (4447999591938863/36028797018963968) 0.123456789012346 -2 0.0123456789012346 (7116799347102181/576460752303423488) 0.0123456789012346 -3 0.00123456789012346 (5693439477681745/4611686018427387904) 0.00123456789012346 -4 1.23456789012346e-4 (1138687895536349/9223372036854775808) 1.23456789012346e-4 -5 1.23456789012346e-5 (3643801265716317/295147905179352825856) 1.23456789012346e-5 -6 1.23456789012346e-6 (5830082025146107/4722366482869645213696) 1.23456789012346e-6 -7 1.23456789012346e-7 (2332032810058443/18889465931478580854784) 1.23456789012346e-7 -8 1.23456789012346e-8 (3731252496093509/302231454903657293676544) 1.23456789012346e-8 -9 1.23456789012346e-9 (2985001996874807/2417851639229258349412352) 1.23456789012346e-9 -10 1.23456789012346e-10 (4776003194999691/38685626227668133590597632) 1.23456789012346e-10 -11 1.23456789012346e-11 (3820802555999753/309485009821345068724781056) 1.23456789012346e-11 -12 1.23456789012346e-12 (6113284089599605/4951760157141521099596496896) 1.23456789012346e-12 -13 1.23456789012346e-13 (1222656817919921/9903520314283042199192993792) 1.23456789012346e-13 -14 1.23456789012346e-14 (3912501817343747/316912650057057350374175801344) 1.23456789012346e-14 -15 1.23456789012346e-15 (6260002907749995/5070602400912917605986812821504) 1.23456789012346e-15 -16 1.23456789012346e-16 (1252000581549999/10141204801825835211973625643008) 1.23456789012346e-16 -17 1.23456789012346e-17 (4006401860959997/324518553658426726783156020576256) 1.23456789012346e-17 -18 1.23456789012346e-18 (6410242977535995/5192296858534827628530496329220096) 1.23456789012346e-18 -19 1.23456789012346e-19 (1282048595507199/10384593717069655257060992658440192) 1.23456789012346e-19 " a test of '1' to various exponents " | x n | x := 0.1e11. n := 10. 30 timesRepeat: [ Transcript cr; show: n printString, ' ', x printString, ' ', x asTrueFraction printString, ' ', x asTrueFraction asFloat printString. x := x / 10. n := n - 1. ]. 10 9.99999999999997e9 10000000000 9.99999999999997e9 9 9.99999999999998e8 1000000000 9.99999999999998e8 8 1.0e8 100000000 1.0e8 7 9.99999999999999e6 10000000 9.99999999999999e6 6 999999.999999998 1000000 999999.999999998 5 99999.9999999999 100000 99999.9999999999 4 10000.0 10000 10000.0 3 1000.0 1000 1000.0 2 100.0 100 100.0 1 10.0 10 10.0 0 1.0 1 1.0 -1 0.1 (3602879701896397/36028797018963968) 0.1 -2 0.01 (5764607523034235/576460752303423488) 0.01 -3 0.001 (1152921504606847/1152921504606846976) 0.001 -4 1.0e-4 (7378697629483821/73786976294838206464) 1.0e-4 -5 1.0e-5 (5902958103587057/590295810358705651712) 1.0e-5 -6 1.0e-6 (2361183241434823/2361183241434822606848) 1.0e-6 -7 1.0e-7 (3777893186295717/37778931862957161709568) 1.0e-7 -8 1.0e-8 (6044629098073147/604462909807314587353088) 1.0e-8 -9 1.0e-9 (2417851639229259/2417851639229258349412352) 1.0e-9 -10 1.0e-10 (7737125245533629/77371252455336267181195264) 1.0e-10 -11 1.0e-11 (6189700196426903/618970019642690137449562112) 1.0e-11 -12 1.0e-12 (2475880078570761/2475880078570760549798248448) 1.0e-12 -13 1.0e-13 (7922816251426435/79228162514264337593543950336) 1.0e-13 -14 1.0e-14 (1584563250285287/158456325028528675187087900672) 1.0e-14 -15 1.0e-15 (2535301200456459/2535301200456458802993406410752) 1.0e-15 -16 1.0e-16 (8112963841460669/81129638414606681695789005144064) 1.0e-16 -17 1.0e-17 (6490371073168535/649037107316853453566312041152512) 1.0e-17 -18 1.00000000000001e-18 (1298074214633707/1298074214633706907132624082305024) 1.00000000000001e-18 -19 1.0e-19 (8307674973655725/83076749736557242056487941267521536) 1.0e-19 === END === _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 07 4:18:34 pm From: tim <tim@apple.com> To: "David N. Smith" <dnsmith@watson.ibm.com>, <squeak@create.ucsb.edu> Subject: Re: Float bug in Squeak David N. Smith wrote: >It turns out that Squeak neither supports exponents in floats with a radix >specification greater than 14 (oddly that's the digit value of $e) nor does >it seem to issue an error message in these cases. Allowing both an exponent specification (signified with 'e') and radices that can use 'e' as a digit leads to ambiguous literal numbers (e.g. 15r1a.10e06 -> 15r [1a.10e06] -> 25.07082 -> 15r [1a.10] e06 -> 25.06 x 15^6 = 285449062.50 The problem is isolated in: !Number class methodsFor: 'instance creation'! readRemainderOf: integerPart from: aStream base: base "Read optional fractional part and exponent, and return the final result" | value fraction fracpos | value _ integerPart. (aStream peekFor: $.) ifTrue: ["<integer>.<fraction>" (aStream atEnd not and: [aStream peek digitValue between: 0 and: base - 1]) "*** ^^^^^^^^ this could be 'e'" ifTrue: [fracpos _ aStream position. fraction _ Integer readFrom: aStream base: base. fraction _ fraction asFloat / (base raisedTo: aStream position - fracpos). value _ value asFloat + (value < 0 ifTrue: [fraction negated] ifFalse: [fraction])] ifFalse: ["oops - just <integer>." aStream skip: -1. "un-gobble the period" ^ value "Number readFrom: '3r-22.2'"]]. (aStream peekFor: $e) "*** ^^ also comparing for 'e'" ifTrue: ["<integer>e<exponent>" ^ value * (base raisedTo: (Integer readFrom: aStream))]. ^ value! ! Ada is the only other language I know of that supports literal numbers in scientific notation with arbitrary radices; it does so by requiring that the significand be *enclosed* in special characters (in this case, the '#' character), rather than just prefixed by one (as in Squeak): 10 -- an integer literal 10.0 -- a real literal 1E3 -- an integer literal of value 1000 1.5E2 -- a real literal of value 150.0 2#1111_1111# -- an integer literal of value 255 2#1#E8 -- an integer literal of value 256 2#1.1111_1111_111#E11 -- a real literal of value 4095.0 This forces a separation of the significand from the exponent, to allow unambiguous parsing. Unfortunately we cannot reuse Squeak's 'r' (used to separate the radix from the significand) to separate the significand from the exponent, as 'r' is a legal digit for radices > 27. -- tim

Post a reply.

Go back to index.



Date: 97 May 08 10:13:25 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: tim <tim@apple.com> Cc: <squeak@create.ucsb.edu> In-Reply-To: <199705072345.QAA15134@scv1.apple.com> Subject: Re: Float bug in Squeak At 19:43 -0400 5/7/97, tim wrote: >David N. Smith wrote: > >>It turns out that Squeak neither supports exponents in floats with a radix >>specification greater than 14 (oddly that's the digit value of $e) nor does >>it seem to issue an error message in these cases. > >Allowing both an exponent specification (signified with 'e') and radices >that can use 'e' as a digit leads to ambiguous literal numbers (e.g. > > 15r1a.10e06 -> 15r [1a.10e06] -> 25.07082 > -> 15r [1a.10] e06 -> 25.06 x 15^6 = 285449062.50 > -- tim Tim: IBM Smalltalk almost gets it right: 16r1.0e2 -> 100.0 16r1.0E2 -> 1.05517578125 The rule is that all hex digits are uppercase and the 'r' and 'e' are always lower. However, all exponents are always decimal and one cannot write: 16r1.0e16r10 to get around that. Bummer. But at least it doesn't try to have it both ways! Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 08 3:50:43 pm From: Ian Piumarta <piumarta@prof.inria.fr> To: ranjan.bagchi@pobox.com, squeak@create.ucsb.edu Subject: Re: How do I regenerate the VM source code? A note for Unix Squeak users: in the 1.17 VM there was an "undocumented" option "-lazy" which put Squeak "to sleep" when the window was unmapped (iconified, on an undisplayed workspace, etc...). In 1.18 I somewhat rashly made it the default, so beware of unmapping the window while Squeak is busy doing something interesting. In the 1.19 VM I've put the option back and made the default be "run all the time". (And now I find I almost always kill Squeak moments after starting it, because I forgot to use the option. ;-) If you want to disable this in your 1.18 VM, find the case in the event loop for "StructureNotify" (which sits in a loop calling XNextEvent until a "MapNotify" arrives). Commenting out this case, and then recompiling, will disable the "feature". Just in case anyone has managed this long without discovering them, there are two other options too: -display <dpy> - does the obvious thing -memory <num>[mk] - allocate num mega/kilobytes of object memory Regards, Ian ------------------------------- projet SOR ------------------------------- Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87 ----------------------- Systemes a Objets Repartis -----------------------

Post a reply.

Go back to index.



Date: 97 May 09 9:26:48 am From: Ian Piumarta <piumarta@prof.inria.fr> To: gregory@eng.adaptec.com Cc: squeak@create.ucsb.edu Subject: Re: Accessing source code in 1.18 Greg, > I placed all of the files in the same directory. My directory > listing looks like: > > InterpTest.c Squeak1.18.changes.txt sq.h > InterpTestInline.c SqueakV1.sources sqFilePrims.c > Makefile SqueakV1.sources.txt sqSoundPrims.c > Makefile.dec SqueakVM-1.18-i586-linux1.2 sqUnixConfig.h > Makefile.linux SqueakVM-1.18-sparc-sunos4.1* sqUnixDirectory.c > Makefile.orig clone.image sqUnixJoystick.c > Makefile.sun cr2lf* sqUnixSound.c > Squeak1.18.changes lf2cr* sqXWindow.c The changes file is for an image called "Squeak1.18", but the only image in this directory is called "clone". You should be using an image and changes file for an image with the *same* name. By default the VM will look for an image called "clone.image" and a changes file called "clone.changes", so not finding clone.changes is probably the cause of your problem. I suggest you fetch the Squeak1.19d.image and .changes files and try with them. (They should work fine with the 1.18 VM.) You need to put (a link to) the SqueakV1.sources file in the same directory as the image/changes file, and run the VM (which doesn't have to be in the same directory -- it can be anywhere in your PATH, or use a relative/absolute path name, or a link, to get to it) from this directory. Regards, Ian ------------------------------- projet SOR ------------------------------- Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87 ----------------------- Systemes a Objets Repartis -----------------------

Post a reply.

Go back to index.



Date: 97 May 09 4:47:58 pm From: Dan Ingalls <DanI@wdi.disney.com> To: "David N. Smith" <dnsmith@watson.ibm.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <v0310280aaf966abf5bfc@[129.34.225.178]> Subject: Re: Float bug in Squeak --============_-1348895324==_============ Content-Type: text/plain; charset="us-ascii" I attach herewith a redefinition of Character digitValue which causes the Float read problems to go away. As pointed out by tim, these were the result of allowing lowercase letters as digits, thus introducing an ambiguity in, eg, 15r1a.10e06. >All float fans: > >On my PPC I get these strange results; the first two are OK, but then >things get very odd, with various bizare values of zero: > 13r0.0e0 0.0 > 14r0.0e0 0.0 > 15r0.0e0 0.0622222222222223 > 16r0.0e0 0.0546875 > 17r0.0e0 0.0484429065743945 With the fix, the results are now, as desired: 13r0.0e0 0.0 14r0.0e0 0.0 15r0.0e0 0.0 16r0.0e0 0.0 17r0.0e0 0.0 >These don't work too well either: > 16r1.0e0 1.0546875 > 16r1.0e1 1.054931640625 > 16r1.0e2 1.05517578125 > 16r1.0e3 1.055419921875 With the fix, the results are now, as desired: 16r1.0e0 1.0 16r1.0e1 16.0 16r1.0e2 256.0 16r1.0e3 4096.0 [and from a later message] >IBM Smalltalk almost gets it right: > > 16r1.0e2 100.0 > 16r1.0E2 1.05517578125 > >The rule is that all hex digits are uppercase and the 'r' and 'e' are >always lower. With the fix, these are both right, as 16r1.0e2 256.0 16r1.0E2 1.05517578125 Many thanks, David, for checkin' them details! - Dan --============_-1348895324==_============ Content-Type: text/plain; name="Character-digitValue.st"; charset="us-ascii" Content-Disposition: attachment; filename="Character-digitValue.st" 'From Squeak 1.19d of April 13, 1997 on 9 May 1997 at 5:03:45 pm'! !Character methodsFor: 'accessing'! digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0 otherwise. This is used to parse literal numbers of radix 2-36." value <= $9 asciiValue ifTrue: [^value - $0 asciiValue]. value >= $A asciiValue ifTrue: [value <= $Z asciiValue ifTrue: [^value - $A asciiValue + 10]]. ^ -1! ! --============_-1348895324==_============--

Post a reply.

Go back to index.



Date: 97 May 09 7:23:10 pm From: lnotarfr@dc.uba.ar (Luciano Esteban Notarfrancesco) To: squeak@create.ucsb.edu Subject: hashing Hello squeakers! I'd like to point out some things about hashing in Squeak: 1) Some classes that implement #= forgot to implement #hash. Some of them inherited a #hash that still makes sense with the reimplemented #=. I searched the system for that classes doing | aCollection | aCollection _ SortedCollection new. Smalltalk allBehaviorsDo: [:class | ((class includesSelector: #=) and: [(class includesSelector: #hash) not]) ifTrue: [aCollection add: class name, ' ', #=]]. Smalltalk browseMessageList: aCollection name: 'unimplemented hash' and I implemented #hash for that classes that needed it. 2) In a previous mail, I suggested some changes, and now I know some of them were just bad ideas: o. Extending Bag>>add:withOccurrences: for negative occurrences was just stupid (sorry); o. Implementing aClass>>asAClass (Bag>>asBag, for instance) to return self is not a good thing, since the ANSI Smalltalk will return always a copy of the receiver in such cases (and then the inherited #asSomething will suffice). Also I was wrong when checking the type of the receiver in Bad>>asBag (thanks for noticing me about this, Dave!); o. I reported a bug in comparisions between Symbols (#hola) and Strings ('hola'). I suggested to answer true when comparing #hola = 'hola'... and it was certainly wrong (thanks Douglas!). Both #hola = 'hola' and 'hola' = #hola should be false. 3) In a previous mail I post implementations of Set>>hash and SequenceableCollection>>hash. They were something like ^self inject: 0 into: [ :hashValue :each | hashValue + each hash]. But this could be very slow when hashing big collections. For speed, Set>>hash could be implemented like ^self size and SequenceableCollection>>hash like ^self size + (self at: 1 ifAbsent: [0]) hash. What is better? A faster hash function or a more disperse hash function? (an efficient hash function or an effective one?) 4) I think Squeak have some problem with IdentityDictionary>>includes: and IdentityDictionary>>occurrencesOf:. I don't have Squeak here, so I'll check it later. Best regards, --- Luciano. 'From Squeak 1.19d of April 13, 1997 on 9 May 1997 at 1:31:13 am'! !CharacterBlock methodsFor: 'comparing'! hash ^stringIndex hash! ! !Text methodsFor: 'comparing'! hash ^string hash + runs hash! ! !TextColor methodsFor: 'as yet unclassified'! hash ^color hash! ! !TextEmphasis methodsFor: 'as yet unclassified'! hash ^emphasisCode hash! ! !TextFontChange methodsFor: 'as yet unclassified'! hash ^fontNumber hash! !

Post a reply.

Go back to index.



Date: 97 May 11 8:25:44 am From: Ian Piumarta <piumarta@prof.inria.fr> To: Squeak@create.ucsb.edu Subject: process fun For many years I've had this recurring worry about non-local returns, where it's not enforced that the process that created the block is the same as the process that eventually invokes the non-local return. The return can end up crossing a process boundary without the VM being aware of it. Enjoy! ;-) Ian 'From Squeak 1.19d of April 13, 1997 on 11 May 1997 at 5:26:15 pm'! Object subclass: #Prank instanceVariableNames: 'pid1 pid2 block1 ' classVariableNames: '' poolDictionaries: '' category: 'Squeak Interpreter'! !Prank methodsFor: 'as yet unclassified'! doit "Prank new doit" pid1 _ Processor activeProcess. pid2 _ [ Processor activeProcess == pid2 ifFalse: [self error: 'process 2 is wrong']. Transcript cr; show: 'about to activate process 1 block'. block1 value. ] newProcess. pid2 priority: Processor userInterruptPriority. pid1 == pid2 ifTrue: [self error: 'process identity crisis']. self initBlock. "pid2 runs when resumed during this send" pid1 == Processor activeProcess ifFalse: [self error: 'process screwed']. Transcript cr; show: 'prank over'.! initBlock block1 _ [Transcript cr; show: 'about to return into process 1 stack'. ^42]. Transcript cr; show: 'about to resume process 2...'. pid2 resume! !

Post a reply.

Go back to index.



Date: 97 May 11 8:41:11 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: Float #hash method LONG and DULL All float fans: The Float hash method seems left over from olden days where small integers were 16K or so. It uses only one part of the float, possibly giving quite different answers depending on byte ordering. The suggested new one answers the same results on Big Endian and Small Endian machines (at least it does on my Pentium and PPC). Both words of the double float are used; 8 bits are removed from each end to clear most of the exponent regardless of the byte ordering. While it is a bit slower than the original version, it is slower only in the ratios 12:5 to 2:1 depending on values. The last (outermost) #bitAnd: can be removed; it is there to guarantee that the result is always 16 bits, bit it doesn't seem to matter. The hash is different, but doesn't seem worse. I tried a number of other hash algorithms and found lots of bad ones. This one seems to work better than the existing one in cases I've tried, and it works far better than at least one commercial implementation which answers the integer part of a float, ignoring the fraction entirely! However, there may be better ones; I make no guarantees. In particular, it would be nice if values had more than a 64K range but my attempts to do that always ended up with bad test results. Clearly more work is needed... The method is: -------------------------------------------------------------------- hashDNS "Hash is reimplemented because = is implemented. Both words of the double float are used; 8 bits are removed from each end to clear most of the exponent regardless of the byte ordering. (Three bitAnd:s are utilized to assure the intermediate results do not become a large integer.) Slower than the original version in the ratios 12:5 to 2:1 depending on values. Answers the same result on Big Endian and Small Endian IEEE machines.(DNS, 11May197) " ^ ( ( ((self basicAt: 1) bitAnd: 16r00FFFF00) + ((self basicAt: 2) bitAnd: 16r00FFFF00) ) bitAnd: 16r00FFFF00 ) >> 8 -------------------------------------------------------------------- Tests ----- Each test is the same except for the range in #to:by:do:. Each test tries a set of floats with each hash method, testing the distribution with a 100 element bucket test. The tests shown were run with 1.19d on an Apple PPC 9500/200. They were repeated on an IBM ThinkPad 760e (a recent Pentium) using 1.16 and the new hash algorithm answered the same values. (1) Test of wide range of floats, -100000 to 100000 by 10. Note the bad clustering in the first set of values from the existing hash method. The second set shows some variation but each bucket is hit with mo more than double the entries of any other. | bucket bucketd t | bucket := Array new: 100. bucket atAllPut: 0. bucketd := Array new: 100. bucketd atAllPut: 0. -100000.0 to: 100000.0 by: 10.0 do: [ :f | t := (f hash \\ bucket size) + 1. bucket at: t put: (bucket at: t) + 1. t := (f hashDNS \\ bucketd size) + 1. bucketd at: t put: (bucketd at: t) + 1 ]. Array with: bucket with: bucketd ((1021 0 0 0 774 0 0 0 672 0 0 0 812 0 0 0 800 0 0 0 814 0 0 0 840 0 0 0 756 0 0 0 748 0 0 0 852 0 0 0 800 0 0 0 800 0 0 0 768 0 0 0 748 0 0 0 840 0 0 0 840 0 0 0 814 0 0 0 720 0 0 0 812 0 0 0 748 0 0 0 774 0 0 0 748 0 0 0 756 0 0 0 904 0 0 0 840 0 0 0 ) (253 206 166 124 332 166 206 166 166 248 248 206 188 124 248 166 218 166 124 248 252 206 166 124 332 166 206 166 166 248 248 206 188 124 248 166 218 166 124 248 256 206 170 124 334 170 208 168 166 252 252 206 190 126 252 170 218 170 126 252 258 208 170 126 338 170 208 170 168 252 252 208 192 126 252 170 218 170 126 252 258 208 170 126 336 170 208 170 170 252 252 208 190 126 250 166 216 166 124 248 ) ) (2) Same as (1) but the by: value is 8.9 versus 10. Note that the bad clustering of the old hash disappears but that values still range from about 176 to 277 but with groups of two low value followed by groups of two high values. The new hash values range from 188 to 268, but doesn't show the (mild) clustering. | bucket bucketd t | bucket := Array new: 100. bucket atAllPut: 0. bucketd := Array new: 100. bucketd atAllPut: 0. -100000.0 to: 100000.0 by: 8.9 do: [ :f | t := (f hash \\ bucket size) + 1. bucket at: t put: (bucket at: t) + 1. t := (f hashDNS \\ bucketd size) + 1. bucketd at: t put: (bucketd at: t) + 1 ]. Array with: bucket with: bucketd ((277 178 181 260 276 177 179 282 266 183 174 276 266 180 184 267 269 180 179 267 274 179 182 265 266 191 182 267 271 179 188 267 270 183 183 270 269 171 189 269 273 176 173 276 266 183 171 272 268 184 179 266 275 189 175 276 269 187 179 272 261 176 180 275 270 181 178 267 276 177 182 268 273 176 180 268 273 182 177 276 261 182 184 275 264 174 180 263 267 176 179 266 276 173 175 269 265 178 180 264 ) (188 230 223 195 249 203 218 282 214 204 252 190 218 244 186 244 213 216 272 228 201 252 197 205 242 197 236 228 199 278 233 196 257 205 197 245 203 228 238 215 258 245 189 268 194 209 243 208 210 253 211 251 263 181 259 204 210 238 213 205 252 218 237 274 178 270 198 206 244 213 196 252 218 222 284 185 242 219 200 237 206 206 250 212 217 291 186 241 227 187 241 220 190 250 209 219 280 203 214 245 ) ) (3) A test of small numbers, from -1.0 to 1.0 with an uneven increment. The results are similar. | bucket bucketd t | bucket := Array new: 100. bucket atAllPut: 0. bucketd := Array new: 100. bucketd atAllPut: 0. -1.0 to: 1.0 by: 0.000084 do: [ :f | t := (f hash \\ bucket size) + 1. bucket at: t put: (bucket at: t) + 1. t := (f hashDNS \\ bucketd size) + 1. bucketd at: t put: (bucketd at: t) + 1 ]. Array with: bucket with: bucketd ((241 245 244 231 231 220 243 246 240 236 247 251 236 227 228 235 247 246 244 250 243 240 225 222 227 246 243 250 237 245 240 227 215 236 239 245 247 248 242 244 227 226 237 244 244 251 245 245 235 225 229 229 243 247 244 238 245 240 231 220 231 240 243 237 243 252 247 233 226 223 239 249 244 249 237 243 232 221 225 237 247 253 236 244 246 230 218 223 240 239 241 252 248 240 232 219 233 231 247 246 ) (233 248 244 219 241 239 230 250 228 260 240 242 226 245 234 238 243 231 250 226 246 221 249 216 250 237 239 235 248 240 227 241 230 260 234 236 249 241 226 239 245 227 248 235 235 243 237 227 233 238 229 246 253 225 239 235 252 224 248 235 248 238 239 232 246 241 228 245 229 246 220 256 228 244 230 249 220 241 237 239 238 231 253 233 247 237 242 234 243 238 235 246 240 232 235 237 224 244 247 233 ) ) (4) Same as (3) but with an even smaller range. Note the old values range from 119 to 356, indicating a less than perfect distribution. The new hash has a much better distribution. | bucket bucketd t | bucket := Array new: 100. bucket atAllPut: 0. bucketd := Array new: 100. bucketd atAllPut: 0. -0.001 to: 0.001 by: 0.000000084 do: [ :f | t := (f hash \\ bucket size) + 1. bucket at: t put: (bucket at: t) + 1. t := (f hashDNS \\ bucketd size) + 1. bucketd at: t put: (bucketd at: t) + 1 ]. Array with: bucket with: bucketd ((195 273 204 273 208 257 230 248 234 237 239 225 257 213 272 199 276 191 294 176 308 164 315 149 331 146 344 135 344 120 365 119 354 120 356 120 357 123 343 139 336 146 335 146 319 163 307 179 290 189 282 197 277 213 262 224 243 235 242 239 230 252 211 270 206 275 199 289 181 304 171 307 159 323 148 335 136 341 128 356 129 355 121 349 121 357 125 344 131 334 135 335 153 324 155 306 170 304 175 289 ) (228 234 239 242 240 245 249 230 245 244 254 218 221 229 241 231 252 233 251 236 246 242 253 237 222 220 233 236 252 235 245 243 246 237 244 251 234 217 224 240 238 244 238 252 229 250 233 258 234 231 216 229 233 244 235 258 239 238 246 239 248 231 235 217 228 233 248 230 256 240 245 237 252 241 226 227 228 227 236 255 243 244 238 248 234 252 227 230 222 232 234 240 245 249 233 251 239 245 240 221 ) ) (5) A test with very large numbers. Similar results. (Also similar results with an increment of 1.1e45.) | bucket bucketd t | bucket := Array new: 100. bucket atAllPut: 0. bucketd := Array new: 100. bucketd atAllPut: 0. -1.0e50 to: 1.0e50 by: 1.0e45 do: [ :f | t := (f hash \\ bucket size) + 1. bucket at: t put: (bucket at: t) + 1. t := (f hashDNS \\ bucketd size) + 1. bucketd at: t put: (bucketd at: t) + 1 ]. Array with: bucket with: bucketd ((1990 1984 1970 2029 2042 2002 1962 2018 2010 2004 2046 2020 1948 2010 2036 1992 2006 2008 1982 1980 2008 2002 2022 1998 1984 1994 2000 2008 2018 1980 1962 2006 2014 2006 2030 1982 1978 2042 1996 1996 2004 1992 2020 1998 2006 2018 2016 1962 2052 2028 1932 2026 2026 1982 2042 1968 1970 2004 2008 2040 1972 1964 2004 2026 1992 2008 1986 1970 1982 2030 2030 1986 2004 1984 1984 2026 2062 1980 1982 2002 1996 2046 2026 1996 1982 1952 2004 2032 1970 1992 1982 1972 1990 2022 1974 1972 1976 1988 2004 1992 ) (2070 2021 1935 1999 2073 2018 1946 1997 2068 2009 1972 1968 2078 2021 1929 1987 2063 2018 1948 1980 2077 2021 1943 1992 2067 2002 1964 1987 2090 2019 1948 1998 2062 2040 1942 1985 2077 2012 1951 1960 2084 2012 1940 1983 2074 2000 1922 1990 2060 1999 1951 1982 2072 2007 1933 1985 2070 2018 1907 1987 2079 2020 1914 1978 2079 1983 1946 1966 2078 1988 1921 1989 2051 2008 1911 1988 2058 1991 1922 1975 2058 2002 1924 1974 2081 1998 1938 1981 2074 2011 1917 1989 2046 1990 1960 1973 2092 2006 1944 1985 ) ) ---END--- _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 11 9:13:54 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: Ian Piumarta <piumarta@prof.inria.fr> Cc: Squeak@create.ucsb.edu In-Reply-To: <199705111552.RAA02028@prof.inria.fr> Subject: Re: process fun Ian: Just for fun I tried this on IBM Smalltalk V3 and it detected the an attempt to return twice from a method. It wasn't no fun at all! (Neither was the Error 11 and the hang of the MacOS when I tried in on Squeak 1.19d. Your sense of humor is significantly worse than mine. :-) IBM Smalltalk version: Object subclass: #Prank instanceVariableNames: 'pid1 pid2 block1 ' classVariableNames: '' poolDictionaries: ''! !Prank publicMethods! doit "Prank new doit" pid1 := Processor activeProcess. pid2 := [ Processor activeProcess == pid2 ifFalse: [self error: 'process 2 is wrong']. Transcript cr; show: 'about to activate process 1 block'. block1 value. ] newProcess. pid2 priority: Processor userInterruptPriority. pid1 == pid2 ifTrue: [self error: 'process identity crisis']. self initBlock. "pid2 runs when resumed during this send" pid1 == Processor activeProcess ifFalse: [self error: 'process screwed']. Transcript cr; show: 'prank over'.! initBlock block1 := [Transcript cr; show: 'about to return into process 1 stack'. ^42]. Transcript cr; show: 'about to resume process 2...'. pid2 resume! ! Prank new doit -------------------------------------------- The transcript shows: about to resume process 2... prank over about to activate process 1 block about to return into process 1 stack -------------------------------------------- The debugger opens with a message about trying to return twice from a method. This is a copy of the debuggers stack trace report. See the 7th line from the bottom. Debugger Stack Trace Report: 5/11/97 VM = 3.0, 6/6/95 Stack Trace for: Process:6253{suspended,4} [optimized] in ProcessorScheduler>>#yield BlockContextTemplate(Block)>>#critical ProcessorScheduler>>#yield ProcessorScheduler>>#enableProcessSwitches [optimized] in EtWindowSystemStartUp class>>#reportError:resumable:startBP: BlockContextTemplate(Block)>>#when:do:exitWith:retryReturn: arg1 = an ExceptionalEventCollection arg2 = [] in EtWindowSystemStartUp class>>#reportError:resumable:startBP: arg3 = [] in Block>>#when:do: arg4 = an Object temp1 = [] in Block>>#when:do:exitWith:retryReturn: temp2 = [] in Block>>#when:do:exitWith:retryReturn: temp3 = nil BlockContextTemplate(Block)>>#when:do: arg1 = an ExceptionalEventCollection arg2 = [] in EtWindowSystemStartUp class>>#reportError:resumable:startBP: temp1 = an Object temp2 = nil EtWindowSystemStartUp class>>#reportError:resumable:startBP: arg1 = 'attempt to return twice from method' arg2 = false arg3 = 89 temp1 = Process:6253{suspended,4} Process>>#reportError:resumable: arg1 = 'attempt to return twice from method' arg2 = false temp1 = 89 [optimized] in UndefinedObject(ExceptionalEvent class)>>#initializeSystemExceptions blockarg1 = Signal on Exception: (ExError) An error has occurred. Signal>>#evaluate: arg1 = [] in ExceptionalEvent class>>#initializeSystemExceptions ExceptionalEvent>>#applyDefaultHandler: arg1 = Signal on Exception: (ExError) An error has occurred. temp1 = Exception: (ExError) An error has occurred. ExceptionalEvent>>#signalWithArguments: arg1 = ('attempt to return twice from method') temp1 = Signal on Exception: (ExError) An error has occurred. temp2 = nil ExceptionalEvent>>#signalWith: arg1 = 'attempt to return twice from method' BlockContextTemplate(Object)>>#error: arg1 = 'attempt to return twice from method' BlockContextTemplate>>#cannotReturn [optimized] in Prank>>#initBlock [optimized] in Prank>>#doit Process>>#newProcessOn:stackSize: arg1 = [] in Prank>>#doit arg2 = 1024 _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 11 10:00:29 am From: Ian Piumarta <piumarta@prof.inria.fr> To: dnsmith@watson.ibm.com Cc: Squeak@create.ucsb.edu Subject: Re: process fun David, > about to resume process 2... > prank over > about to activate process 1 block > about to return into process 1 stack This doesn't look right. I suspect the #resume isn't pre-empting pid1, and that pid1 is returning from #initBlock and printing 'prank over' before pid2 starts to run (since the first thing that pid2 should do is to print 'about to activate process 1 block'). In which case the behaviour is correct: the activation of #initBlock in pid1 has already exited when block1, activated by pid2, tries to return from it a second time. pid2 is never reaching pid1's stack. Try inserting a "(Delay forSeconds: 1) wait" just after the #resume in #initBlock, to be *absolutely* sure that pid1 is still suspended in that context when pid2 tries to return into its stack. > Your sense of humor is significantly worse than mine. :-) That was a very carefully calculated "winky" after the word "Enjoy!". ;) Regards, Ian PS: Does Java have closures? (Maybe it's possible to turn Prank into an applet... ;) ------------------------------- projet SOR ------------------------------- Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87 ----------------------- Systemes a Objets Repartis -----------------------

Post a reply.

Go back to index.



Date: 97 May 11 10:21:25 am From: Ian Piumarta <piumarta@prof.inria.fr> To: dnsmith@watson.ibm.com Cc: Squeak@create.ucsb.edu Subject: Re: process fun It just occurred to me... > the Error 11 and the hang of the MacOS when I tried in on Squeak 1.19d. Look at this: clotho$ fgrep SEGV /usr/include/signal.h /usr/include/signal.h:#define SIGSEGV 11 Is this just a coincidence? (I can verify that it *is* a segmentation fault that you get under Squeak when you run the prank [I keep a debugger in my extensions folder at all times ;)].) Ian

Post a reply.

Go back to index.



Date: 97 May 12 1:04:01 am From: Hans-Martin Mosner <hmm@heeg.de> To: squeak@create.ucsb.edu Subject: Re: Newcomer, Persistent Store and Constraints John Maloney wrote: > > Thierry: > > Welcome to Squeak! > > Re: transactions > > I have no great ideas except that you modify Squeak ObjectMemory to > set a "dirty" bit on modified objects. There is a bit available in > the object header, although there's no guarantee that we won't > use that bit for something ourselves some day. > I'd suggest not a "dirty" bit but a "clean/readonly" bit that causes the VM to trap write accesses to the object (send it a message such as #trapWrite: newValue slot: slotNumber) This could be used to implement 2 desirable features: 1. Immutable objects I and every other Smalltalker that I know have always wanted immutable literals. This is the chance to have them in Squeak! 2. Persistent objects Although I see little probability for a GemStone-Squeak interface, some other persistent storage mechanisms might be ported to Squeak. How can it be done? My idea is that an object is either immutable (because it's a literal) or has a persistent storage manager. In the first case, writes are never allowed. In the second case, the storage manager decides whether a write is allowed, and can remember the object as dirty. A possible implementation looks like this: trapWrite: newValue slot: slotNumber | manager fixedSlots | manager := self persistentStorageManager. (manager == nil or: [manager isImmutable: self]) ifTrue: [self error: 'Write attempt to immutable object!']. manager markDirty: self. self primBeImmutable: false. fixedSlots := self class instSize. ^slotNumber <= fixedSlots ifTrue: [self instVarAt: slotNumber put: newValue] ifFalse: [self basicAt: slotNumber - fixedSlots put: newValue] ! persistentStorageManager ^PersistentStores detect: [:each | each managesObject: self] ifNone: [nil] ! beImmutable: aBoolean self isImmutable ifTrue: [self error: 'Immutable status can not be changed!']. self primBeImmutable: aBoolean ! The methods #isImmutable and #primBeImmutable: would be primitives accessing the clean/readonly bit. How the managers implement the messages #managesObject:, #isImmutable: and #markDirty: is their business, but should be straightforward. How could it be implemented efficiently in the VM? There is already a check to detect writes into old objects, so that the table of old objects referencing new ones can be maintained. The VM only looks at header bits if the object is in the address range of old objects. Since most writes are into young objects, it would be a significant performance hit to check the clean/readonly bit on every write. Therefore I propose that making an object immutable (which is a not-too-common operation) should move the old/young object boundary if the object is currently young. There are 2 possible alternatives: 1. Make all objects old. Simple but somewhat stupid since too many innocent new objects may be affected. However, it avoids updating the RootTable. 2. Make objects up to and including the newly immutable object old. More complicated since all intermediate objects need to be checked whether they need to be put into the RootTable. Overall, I think that the basic mechanism would not be too complicated to implement. There are a number of places in the VM where assumptions about the writability of objects are made, such as Context objects etc. These places need to be revisited. For performance reasons, such objects should probably be exempt from the clean/readonly mechanism (the primBeImmutable: primitive could just fail). Other objects, such as Floats, could be created by the VM with the clean/readonly bit already on, avoiding any messing around. Hans-Martin

Post a reply.

Go back to index.



Date: 97 May 12 2:39:28 am From: wimb@bart.nl (Wim Boot) To: squeak@create.ucsb.edu In-Reply-To: <v03102805af9b9e000ef8@[129.34.225.178]> Subject: Re: Float #hash method LONG and DULL David N. Smith wrote: >All float fans: > >The Float hash method seems left over from olden days where small = integers >were 16K or so. It uses only one part of the float, possibly giving = quite >different answers depending on byte ordering. Indeed. There are worse (very ancient) problems however. Try "1 hash =3D 1.0 hash" or "(3/2) hash =3D 1.5 hash". False in both cases, though "1 =3D 1.0" and "(3/2) =3D 1.5" both yield true. Your hashDNS method doesn't address this problem either. Wim Boot

Post a reply.

Go back to index.



Date: 97 May 12 5:13:09 am From: Thierry Goubier <Thierry.Goubier@enst-bretagne.fr> To: Hans-Martin Mosner <hmm@heeg.de> Cc: squeak@create.ucsb.edu In-Reply-To: <3376D4F6.2781E494@heeg.de> Subject: Re: Newcomer, Persistent Store and Constraints On Mon, 12 May 1997, Hans-Martin Mosner wrote: > John Maloney wrote: > > I have no great ideas except that you modify Squeak ObjectMemory to > > set a "dirty" bit on modified objects. There is a bit available in > > the object header, although there's no guarantee that we won't > > use that bit for something ourselves some day. The problem is that the hard job for the persistent store is to determine when an object is modified, not to record the fact it has been modified (I may be mistaken here, but the cost of scanning throught all object headers to determine which has been modified is high). > I'd suggest not a "dirty" bit but a "clean/readonly" bit that causes the > VM to trap write accesses to the object (send it a message such as > #trapWrite: newValue slot: slotNumber) I second this. That's a great idea for a persistent store. > This could be used to implement 2 desirable features: > 1. Immutable objects > I and every other Smalltalker that I know have always wanted immutable > literals. This is the chance to have them in Squeak! > 2. Persistent objects > Although I see little probability for a GemStone-Squeak interface, some > other persistent storage mechanisms might be ported to Squeak. I'll port my own little thing. But it won't be Gemstone-the return, don't hold your breath. It may be usefull, however, to save morphs and the like, or to try new things (schema management, cooperative software). I'll suggest another thing 3. Read-only duplication of distributed objects Thierry. ___________________Thierry.Goubier@enst-bretagne.fr__________________ But to look for heaven is to live here in hell [Sting] http://www-info.enst-bretagne.fr/~goubier/

Post a reply.

Go back to index.



Date: 97 May 12 5:26:49 am From: Anthony Lander <anthony@objectPeople.com> To: squeak@create.ucsb.edu Subject: Re: Newcomer, Persistent Store and Constraints At 10:29 AM 5/12/97 +0200, you wrote: >2. Persistent objects >Although I see little probability for a GemStone-Squeak interface, some >other persistent storage mechanisms might be ported to Squeak. In theory, at least, I could port TOPLink to run under Squeak. The only "tricky" part would be writing an ODBC interface. -Anthony Lander The Object People ----------------------------------------------------------------- "it's pretty scary when u look at the colon/semicolon key on your keyboard and you just see 4 faceless eyes staring at you" --Mark

Post a reply.

Go back to index.



Date: 97 May 12 6:40:12 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Cc: squeak@create.ucsb.edu In-Reply-To: <3377e88a.11392902@mail.gld.bart.nl> Subject: Re: Float #hash method LONG and DULL At 6:01 -0400 5/12/97, Wim Boot wrote: >David N. Smith wrote: > >>All float fans: >> >>The Float hash method seems left over from olden days where small integers >>were 16K or so. It uses only one part of the float, possibly giving quite >>different answers depending on byte ordering. > >Indeed. There are worse (very ancient) problems however. > >Try "1 hash = 1.0 hash" or "(3/2) hash = 1.5 hash". False in >both cases, though "1 = 1.0" and "(3/2) = 1.5" both yield true. > >Your hashDNS method doesn't address this problem either. > >Wim Boot Wim: Maybe I'm missing something, but I wouldn't expect two different objects to have the same hash just because they have the same 'value'. (3/2) is a completely different object than 1.5 How about: 'abc' = #abc true 'abc' hash = #abc hash false Should the hash of a string always be the hash of a symbol containing the same characters? Symbols are typically guaranteed to have different hashes for different values; strings are not because of the expense in many implementations. dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 12 6:55:05 am From: tim <tim@apple.com> To: "Dan Ingalls" <DanI@wdi.disney.com>, "David N. Smith" <dnsmith@watson.ibm.com> Cc: <Squeak@create.ucsb.edu> Subject: Re: Float bug in Squeak Dan Ingalls wrote: >I attach herewith a redefinition of Character digitValue which causes the >Float read problems to go away. As pointed out by tim, these were the >result of allowing lowercase letters as digits, thus introducing an >ambiguity in, eg, 15r1a.10e06. InputSensor>>joystickButtons InputSensor>>joystickXY: look to be the only existing sources that rely upon lower-case hex digits for literals; they should be changed to match the new digitValue method. -- tim

Post a reply.

Go back to index.



Date: 97 May 12 7:18:28 am From: johnson@cs.uiuc.edu (Ralph E. Johnson) To: "David N. Smith" <dnsmith@watson.ibm.com>, squeak@create.ucsb.edu Cc: squeak@create.ucsb.edu Subject: Re: Float #hash method LONG and DULL At 10:08 AM 5/12/97, David N. Smith wrote: >Maybe I'm missing something, but I wouldn't expect two different objects to >have the same hash just because they have the same 'value'. (3/2) is a >completely different object than 1.5 Sets and dictionaries assume that equal objects hash equally. Suppose x and y are two objects that are equal but have different hashes. If you put x in a set and ask whether the set includes y, the answer will be false unless x and y just happened to hash into the same location, in which the answer is true. So, if you redefine = then you should redefine hash. -Ralph

Post a reply.

Go back to index.



Date: 97 May 12 7:22:36 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: Ian Piumarta <piumarta@prof.inria.fr> Cc: Squeak@create.ucsb.edu In-Reply-To: <199705111727.TAA07507@prof.inria.fr> Subject: Re: process fun (in IBM Smalltalk too) At 13:27 -0400 5/11/97, Ian Piumarta wrote: >David, > >> about to resume process 2... >> prank over >> about to activate process 1 block >> about to return into process 1 stack > >This doesn't look right. I suspect the #resume isn't pre-empting pid1, >and that pid1 is returning from #initBlock and printing 'prank over' >before pid2 starts to run (since the first thing that pid2 should do is >to print 'about to activate process 1 block'). In which case the >behaviour is correct: the activation of #initBlock in pid1 has already >exited when block1, activated by pid2, tries to return from it a second >time. pid2 is never reaching pid1's stack. > >Try inserting a "(Delay forSeconds: 1) wait" just after the #resume in >#initBlock, to be *absolutely* sure that pid1 is still suspended in that >context when pid2 tries to return into its stack. > >> Your sense of humor is significantly worse than mine. :-) > >That was a very carefully calculated "winky" after the word "Enjoy!". ;) > >Regards, > >Ian > >PS: Does Java have closures? (Maybe it's possible to turn Prank into an > applet... ;) > >------------------------------- Ian: (Java friends claim that Java 1.1 has closures. I haven't seen them.) Adding a Delay made no difference, as didn't an explicit 'Processor yield' after the #resume. However, if I run pid1 by forking it (and thus it doesn't run as the user interface process) then I get: about to resume process 2... about to activate process 1 block about to return into process 1 stack prank over and the debugger gives me a 'illegal implicit process switch' message pointing at the '^42'. User interface processes are a bit odd and I should have tried this yesterday. The code is (note the change in the commented expression in #doit): --------------------------- Object subclass: #Prank instanceVariableNames: 'pid1 pid2 block1 ' classVariableNames: '' poolDictionaries: ''! !Prank publicMethods! doit "[Prank new doit] fork" pid1 := Processor activeProcess. pid2 := [ Processor activeProcess == pid2 ifFalse: [self error: 'process 2 is wrong']. Transcript cr; show: 'about to activate process 1 block'. block1 value. ] newProcess. pid2 priority: Processor userInterruptPriority. pid1 == pid2 ifTrue: [self error: 'process identity crisis']. self initBlock. "pid2 runs when resumed during this send" pid1 == Processor activeProcess ifFalse: [self error: 'process screwed']. Transcript cr; show: 'prank over'.! initBlock block1 := [Transcript cr; show: 'about to return into process 1 stack'. ^42]. Transcript cr; show: 'about to resume process 2...'. pid2 resume. (Delay forSeconds: 2) wait! ! --------------------------- Debugger Stack Trace Report: 5/12/97 VM = 3.0, 6/6/95 ...snip... BlockContextTemplate(Object)>>#error: arg1 = 'illegal implicit process switch' BlockContextTemplate>>#cannotReturn [optimized] in Prank>>#initBlock [optimized] in Prank>>#doit Process>>#newProcessOn:stackSize: arg1 = [] in Prank>>#doit arg2 = 1024 --------------------------- HOWEVER, if I remove the Delay then I get: ----------------- about to resume process 2... about to activate process 1 block prank overabout to return into process 1 stack ----------------- and the debugger says 'attempt to return twice from method'. A Processor yield makes no difference, but invoking the code this way does: "[Prank new doit] forkAt: 2" (where process priorities are as in the Blue Book). This makes it run with the same results as with the code above. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 12 7:34:55 am From: Hans-Martin Mosner <hmm@heeg.de> To: "David N. Smith" <dnsmith@watson.ibm.com> Cc: squeak@create.ucsb.edu Subject: Re: Float #hash method LONG and DULL David N. Smith wrote: > > Wim: > > Maybe I'm missing something, but I wouldn't expect two different objects to > have the same hash just because they have the same 'value'. (3/2) is a > completely different object than 1.5 Hasn't this topic been hashed to death already? (pardon the pun) If two objects compare equal, their hash values should be equal as well. I know that this has strange implications for numeric classes, but this is a matter of definition... If I put 3/2 and 1.5 in a Set, do I expect the Set to have size 1 or 2? By definition, for each a,b element of a Set, a ~= b. Since (3/2) = 1.5, the Set must have one element only (whichever came first). To make this really happen, 3/2 must have the same hash as 1.5. Perhaps a good time now to think about the implications and reimplement #hash in all the number classes. > How about: > > 'abc' = #abc > true Should not be. Someone on this list acknowleged that it's a bug, because #abc ~= 'abc'. Equality should work both ways. > > 'abc' hash = #abc hash > false > > Should the hash of a string always be the hash of a symbol containing the > same characters? No, because that would be impossible. Symbols just have arbitrary hash values that are not related to their constituent characters. (Which is probably bad for object migration. Setting the hash value of a Symbol from the CRC of its characters might be better) > Symbols are typically guaranteed to have different hashes > for different values; No, Symbols are just guaranteed to be unique, that is, two Symbols are the same object if and only if they have the same characters. Symbols (like other Objects) are guaranteed to have same hashes for same values, though. > strings are not because of the expense in many > implementations. For Symbols, hash is synonymous to identity hash (which is logical, since equality for Symbols is synonymous to identity) For Strings, hash is a fast (and some say, bad) function of the characters in the string. Hans-Martin

Post a reply.

Go back to index.



Date: 97 May 12 8:11:54 am From: Dan Ingalls <DanI@wdi.disney.com> To: Squeak@create.ucsb.edu Subject: Three fileIns --============_-1348667088==_============ Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: quoted-printable NumberFixes-di.cs Three fixes to Float, suggested or requested by David Smith. Eliminates= amgiguity of non-decimal constants by requiring letter-digits to be= uppercase, and fixes two methods that used lowercase hex digits (thanks= tim). Renames the old asFraction code to be asApproximateFraction, and= installs David's asTrueFraction as well. Finally includes David's= improvement to Float>>hash. Takes a while at the end to rehash all= existing sets, and also fixes a bug in the progress bar which is used in= the process. VMfixes-di.cs Sundry fixes and improvements to the VM. Speeds up BitBlt 'paint' mode when= the source is zero. =46ixes a problem reported by Paul McCullough and Don Charnley, so that the= VM now checks for recursive evaluation of blocks (currently crashes). = Fixes two problems reported by Carl Watts: perform now checks that its= selector is not an immediate object (currently crashes), and perform also= adjusts its argument count at the correct time so that the= doesNotUnderstand facility works properly. Also includes minor= improvements to related error messages. ChangeSetCommentFix.st ChangeSets have not been filing out class comments since a change that= merged class and metaclass access to comments months ago. This restores= the fileOut of changed class comments from changeSorters. --============_-1348667088==_============ Content-Type: text/plain; name="NumberFixes-di.cs"; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="NumberFixes-di.cs" 'From Squeak 1.19d of April 13, 1997 on 12 May 1997 at 8:29:02 am'! "Change Set: NumberFixes Date: 11 May 1997 Author: Your Name Three fixes to Float, suggested or requested by David Smith. Eliminates= amgiguity of non-decimal constants by requiring letter-digits to be= uppercase. Renames the old asFraction code to be asApproximateFraction,= and installs David's asTrueFraction as well. Finally includes David's= improvement to Float>>hash. Takes a while at the end to rehash all existing sets, and also fixes a bug= in the progress bar code which is used in the process. "! !Character methodsFor: 'accessing'! digitValue "Answer 0-9 if the receiver is $0-$9, 10-35 if it is $A-$Z, and < 0=20 otherwise. This is used to parse literal numbers of radix 2-36." value <=3D $9 asciiValue=20 ifTrue: [^value - $0 asciiValue]. value >=3D $A asciiValue=20 ifTrue: [value <=3D $Z asciiValue ifTrue: [^value - $A asciiValue + 10]]. ^ -1! ! !Float methodsFor: 'comparing'! hash "Hash is reimplemented because =3D is implemented. Both words of the double float are used; 8 bits are removed from each end to clear most of the exponent regardless of the byte ordering. (Three bitAnd:s are utilized to assure the intermediate results do not become a large integer.) Slower than the original version in the ratios 12:5 to 2:1 depending on values. Answers the same result on Big Endian and Small Endian IEEE machines.(DNS, 11 May, 1997) " ^ ( ( ((self basicAt: 1) bitAnd: 16r00FFFF00) + ((self basicAt: 2) bitAnd: 16r00FFFF00) ) bitAnd: 16r00FFFF00 ) >> 8 ! ! !Float methodsFor: 'converting'! asApproximateFraction "Answer a Fraction approximating the receiver. This conversion uses the=20 continued fraction method to approximate a floating point number." | num1 denom1 num2 denom2 int frac newD temp | num1 _ self asInteger. "The first of two alternating numerators" denom1 _ 1. "The first of two alternating denominators" num2 _ 1. "The second numerator" denom2 _ 0. "The second denominator--will update" int _ num1. "The integer part of self" frac _ self fractionPart. "The fractional part of self" [frac =3D 0] whileFalse:=20 ["repeat while the fractional part is not zero" newD _ 1.0 / frac. "Take reciprocal of the fractional part" int _ newD asInteger. "get the integer part of this" frac _ newD fractionPart. "and save the fractional part for next time" temp _ num2. "Get old numerator and save it" num2 _ num1. "Set second numerator to first" num1 _ num1 * int + temp. "Update first numerator" temp _ denom2. "Get old denominator and save it" denom2 _ denom1. "Set second denominator to first" denom1 _ int * denom1 + temp. "Update first denominator" 10000000000.0 < denom1 ifTrue:=20 ["Is ratio past float precision? If so, pick which=20 of the two ratios to use" num2 =3D 0.0=20 ifTrue: ["Is second denominator 0?" ^ Fraction numerator: num1 denominator: denom1]. ^ Fraction numerator: num2 denominator: denom2]]. "If fractional part is zero, return the first ratio" denom1 =3D 1 ifTrue: ["Am I really an Integer?" ^ num1 "Yes, return Integer result"] ifFalse: ["Otherwise return Fraction result" ^ Fraction numerator: num1 denominator: denom1]! asFraction ^ self asApproximateFraction ! asTrueFraction " Answer a fraction that EXACTLY represents self, a double precision IEEE floating point number. (It tears an IEEE float into its components; it assumes 'correct' byte ordering; runs on PPC.)=20 Thanks to David N. Smith" | shifty sign exp fraction | shifty :=3D ((self at: 1) bitShift: 32) bitOr: (self at: 2). sign :=3D (shifty bitShift: -63) =3D 0 ifTrue: [1] ifFalse: [-1]. exp :=3D (shifty >> 52) bitAnd: 16r7FF. fraction :=3D shifty bitAnd: 16r000FFFFFFFFFFFFF. (exp =3D 0) & (fraction =3D 0) ifTrue: [ ^ 0 ]. fraction :=3D fraction bitOr: 16r0010000000000000. exp :=3D exp - 16r3FF. " Validate that the dismemberment was correct " (sign * fraction / (2 raisedToInteger: 52 - exp)) asFloat =3D self ifFalse: [self error: 'asFraction validation failed' ]. ^ sign * fraction / (2 raisedToInteger: 52 - exp)! ! !InputSensor methodsFor: 'joystick'! joystickButtons: index ^ ((self primReadJoystick: index) bitShift: -22) bitAnd: 16r71F ! joystickXY: index | inputWord x y | inputWord _ self primReadJoystick: index. x _ (inputWord bitAnd: 16r7FF) - 16r400. y _ ((inputWord bitShift: -11) bitAnd: 16r7FF) - 16r400. ^ x@y ! ! !Set class methodsFor: 'initialization'! rehashAllSets "Set rehashAllSets" | insts | self withAllSubclassesDo: [:c | insts _ c allInstances. insts isEmpty ifFalse: ['Rehashing instances of ' , c name displayProgressAt: Sensor cursorPoint from: 1 to: insts size during: [:bar | 1 to: insts size do: [:x | bar value: x. (insts at: x) rehash]]]]! ! !String methodsFor: 'displaying'! displayProgressAt: aPoint from: minVal to: maxVal during: workBlock=20 "Display this string as a caption over a progress bar while workBlock is ev= aluated. EXAMPLE (Select next 6 lines and Do It) 'Now here''s some Real Progress' displayProgressAt: Sensor cursorPoint from: 0 to: 10 during: [:bar | 1 to: 10 do: [:x | bar value: x. (Delay forMilliseconds: 500) wait]]. HOW IT WORKS (Try this in any other language :-) Since your code (the last 2 lines in the above example) is in a block, this method gets control to display its heading before, and clean up=20 the screen after, its execution. The key, though, is that the block is supplied with an argument, named 'bar' in the example, which will update the bar image every=20 it is sent the message value: x, where x is in the from:to: range. " | delta savedArea captionText textFrame barFrame outerFrame result range | barFrame _ aPoint - (75@10) corner: aPoint + (75@10). captionText _ DisplayText text: self asText allBold. textFrame _ captionText boundingBox insetBy: -4. textFrame _ textFrame align: textFrame bottomCenter with: barFrame topCenter + (0@2). outerFrame _ barFrame merge: textFrame. delta _ outerFrame amountToTranslateWithin: Display boundingBox. barFrame _ barFrame translateBy: delta. textFrame _ textFrame translateBy: delta. outerFrame _ outerFrame translateBy: delta. savedArea _ Form fromDisplay: outerFrame. Display fillBlack: barFrame; fillWhite: (barFrame insetBy: 2). Display fillBlack: textFrame; fillWhite: (textFrame insetBy: 2). captionText displayOn: Display at: textFrame topLeft + (4@4). range _ maxVal =3D minVal ifTrue: [1] ifFalse: [maxVal - minVal]. "Avoid= div by 0" result _ workBlock value: "Supply the bar-update block for evaluation in= the work block" [:barVal | Display fillGray: (barFrame topLeft + (2@2) extent: (((barFrame width-4) * (barVal-minVal) / range)@16))]. savedArea displayOn: Display at: outerFrame topLeft. ^ result! ! Set rehashAllSets! --============_-1348667088==_============ Content-Type: text/plain; name="VMfixes-di.cs"; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="VMfixes-di.cs" 'From Squeak 1.19d of April 13, 1997 on 11 May 1997 at 3:19:25 pm'! "Change Set: VMchanges Date: 11 May 1997 Author: Dan Ingalls Sundry fixes and improvements to the VM. Speeds up BitBlt 'paint' mode when= the source is zero. =46ixes a problem reported by Paul McCullough and Don Charnley, so that the= VM now checks for recursive evaluation of blocks. Fixes two problems= reported by Carl Watts: perform now checks that its selector is not an= immediate object (had caused crashes), and perform also adjusts its= argument count at the correct time so that the doesNotUnderstand facility= works properly. Also includes minor improvements to related error messages. "! !Object methodsFor: 'message handling'! perform: selector withArguments: anArray=20 "Primitive. Send the receiver the keyword message indicated by the=20 arguments. The argument, selector, is the selector of the message. The=20 arguments of the message are the elements of anArray. Invoke=20 messageNotUnderstood: if the number of arguments expected by the=20 selector is not the same as the length of anArray. Essential. See Object=20 documentation whatIsAPrimitive." <primitive: 84> (selector isMemberOf: Symbol) ifFalse: [^ self error: 'selector argument must be a Symbol']. self primitiveFailed! ! !BitBltSimulation methodsFor: 'combination rules'! merge: sourceWord with: destinationWord " ^ self dispatchOn: combinationRule with: sourceWord with: destinationWord in: RuleTable. " self inline: true. "These are the combination rules..." combinationRule < 16 ifTrue: [combinationRule < 8 ifTrue: [combinationRule < 4 ifTrue: [combinationRule < 2 ifTrue: [combinationRule < 1 ifTrue: ["0" ^ 0] ifFalse: ["1" ^ sourceWord bitAnd: destinationWord]] ifFalse: [combinationRule < 3 ifTrue: ["2" ^ sourceWord bitAnd: destinationWord bitInvert32] ifFalse: ["3" ^ sourceWord]]] ifFalse: [combinationRule < 6 ifTrue: [combinationRule < 5 ifTrue: ["4" ^ sourceWord bitInvert32 bitAnd: destinationWord] ifFalse: ["5" ^ destinationWord]] ifFalse: [combinationRule < 7 ifTrue: ["6" ^ sourceWord bitXor: destinationWord] ifFalse: ["7" ^ sourceWord bitOr: destinationWord]]]] ifFalse: [combinationRule < 12 ifTrue: [combinationRule < 10 ifTrue: [combinationRule < 9 ifTrue: ["8" ^ sourceWord bitInvert32 bitAnd: destinationWord bitInvert32] ifFalse: ["9" ^ sourceWord bitInvert32 bitXor: destinationWord]] ifFalse: [combinationRule < 11 ifTrue: ["10" ^ destinationWord bitInvert32] ifFalse: ["11" ^ sourceWord bitOr: destinationWord bitInvert32]]] ifFalse: [combinationRule < 14 ifTrue: [combinationRule < 13 ifTrue: ["12" ^ sourceWord bitInvert32] ifFalse: ["13" ^ sourceWord bitInvert32 bitOr: destinationWord]] ifFalse: [combinationRule < 15 ifTrue: ["14" ^ sourceWord bitInvert32 bitOr: destinationWord bitInvert32] ifFalse: ["15" ^ destinationWord]]]]] ifFalse: [combinationRule < 24 ifTrue: [combinationRule < 20 ifTrue: [combinationRule < 18 ifTrue: [combinationRule < 17 ifTrue: ["16" ^ destinationWord "no op"] ifFalse: ["17" ^ destinationWord "no op"]] ifFalse: [combinationRule < 19 ifTrue: ["18" ^ sourceWord + destinationWord] ifFalse: ["19" ^ sourceWord - destinationWord]]] ifFalse: [combinationRule < 22 ifTrue: [combinationRule < 21 ifTrue: ["20" ^ self rgbAdd: sourceWord with: destinationWord] ifFalse: ["21" ^ self rgbSub: sourceWord with: destinationWord]] ifFalse: [combinationRule < 23 ifTrue: ["22" ^ self rgbDiff: sourceWord with: destinationWord] ifFalse: ["23" ^ self tallyIntoMap: destinationWord]]]] ifFalse: [combinationRule < 28 ifTrue: [combinationRule < 26 ifTrue: [combinationRule < 25 ifTrue: ["24" ^ self alphaBlend: sourceWord with: destinationWord] ifFalse: ["25" sourceWord =3D 0 ifTrue: [^ destinationWord]. ^ self pixPaint: sourceWord with: destinationWord]] ifFalse: [combinationRule < 27 ifTrue: ["26" ^ self pixMask: sourceWord with: destinationWord] ifFalse: ["27" ^ self rgbMax: sourceWord with: destinationWord]]] ifFalse: [combinationRule < 30 ifTrue: [combinationRule < 29 ifTrue: ["28" ^ self rgbMin: sourceWord with: destinationWord] ifFalse: ["29" ^ self rgbMin: sourceWord bitInvert32 with: destinationWord]] ifFalse: [combinationRule < 31 ifTrue: ["30" ^ destinationWord "no op"] ifFalse: ["31" ^ destinationWord "no op"]]]]]! ! !BlockContext methodsFor: 'evaluating'! valueWithArguments: anArray=20 "Primitive. Evaluate the block represented by the receiver. The argument=20 is an Array whose elements are the arguments for the block. Fail if the=20 length of the Array is not the same as the the number of arguments that=20 the block was expecting. Fail if the block is already being executed.=20 Essential. See Object documentation whatIsAPrimitive." <primitive: 82> self numArgs =3D anArray size ifTrue: [self error: 'Attempt to evaluate a block that is already being ev= aluated.'] ifFalse: [self error: 'This block requires ' , self numArgs printString ,= ' arguments.']! ! !BlockContext methodsFor: 'private'! cannotReturn: arg self error: 'This block cannot return (it has already done so).'. "Kill off this process" Processor terminateActive! ! !Interpreter methodsFor: 'contexts'! caller ^self fetchPointer: CallerIndex ofObject: activeContext! ! !Interpreter methodsFor: 'control primitives'! primitivePerform | performSelector newReceiver selectorIndex | performSelector _ messageSelector. messageSelector _ self stackValue: argumentCount - 1. (self isIntegerObject: self stackTop) ifTrue: [self primitiveFail. ^ 0]. newReceiver _ self stackValue: argumentCount. "NOTE: the following lookup may fail and be converted to #doesNotUnderstand= :, so we must adjust argument count now, so that would work." argumentCount _ argumentCount - 1. self lookupMethodInClass: (self fetchClassOf: newReceiver). self success: (self argumentCountOf: newMethod) =3D argumentCount. successFlag ifTrue: [selectorIndex _ self stackPointerIndex - argumentCount. self transfer: argumentCount fromIndex: selectorIndex + 1 ofObject: activeContext toIndex: selectorIndex ofObject: activeContext. self pop: 1. self executeNewMethod. "Recursive xeq affects successFlag" successFlag _ true] ifFalse: [argumentCount _ argumentCount + 1. messageSelector _ performSelector]! primitivePerformWithArgs | thisReceiver performSelector argumentArray arraySize index cntxSize | argumentArray _ self popStack. arraySize _ self fetchWordLengthOf: argumentArray. cntxSize _ self fetchWordLengthOf: activeContext. self success: (self stackPointerIndex + arraySize) < cntxSize. self success: (self isIntegerObject: self stackTop) not. self assertClassOf: argumentArray is: (self splObj: ClassArray). successFlag ifTrue: [performSelector _ messageSelector. messageSelector _ self popStack. thisReceiver _ self stackTop. argumentCount _ arraySize. index _ 1. [index <=3D argumentCount] whileTrue: [self push: (self fetchPointer: index - 1 ofObject: argumentArray). index _ index + 1]. self lookupMethodInClass: (self fetchClassOf: thisReceiver). self success: (self argumentCountOf: newMethod) =3D argumentCount. successFlag ifTrue: [self executeNewMethod. "Recursive xeq affects successFlag" successFlag _ true] ifFalse: [self unPop: argumentCount. self push: messageSelector. self push: argumentArray. argumentCount _ 2. messageSelector _ performSelector]] ifFalse: [self unPop: 1]! primitiveValue | blockContext blockArgumentCount initialIP | blockContext _ self stackValue: argumentCount. blockArgumentCount _ self argumentCountOfBlock: blockContext. self success: (argumentCount =3D blockArgumentCount and: [(self fetchPointer: CallerIndex ofObject: blockContext) =3D nilObj]= ). successFlag ifTrue: [self transfer: argumentCount fromIndex: self stackPointerIndex - argumentCount + 1 ofObject: activeContext toIndex: TempFrameStart ofObject: blockContext. "Assume: The call to transfer:... makes blockContext a root if necessary, allowing use to use unchecked stored in the following code." self pop: argumentCount + 1. initialIP _ self fetchPointer: InitialIPIndex ofObject: blockContext. self storePointerUnchecked: InstructionPointerIndex ofObject: blockContex= t withValue: initialIP. self storeStackPointerValue: argumentCount inContext: blockContext. self storePointerUnchecked: CallerIndex ofObject: blockContext withValue: activeContext. self newActiveContext: blockContext]! primitiveValueWithArgs | argumentArray blockContext blockArgumentCount arrayArgumentCount= initialIP | argumentArray _ self popStack. blockContext _ self popStack. blockArgumentCount _ self argumentCountOfBlock: blockContext. self assertClassOf: argumentArray is: (self splObj: ClassArray). successFlag ifTrue: [ arrayArgumentCount _ self fetchWordLengthOf: argumentArray. self success: (arrayArgumentCount =3D blockArgumentCount and: [(self fetchPointer: CallerIndex ofObject: blockContext) =3D nilObj]= )]. successFlag ifTrue: [ self transfer: arrayArgumentCount fromIndex: 0 ofObject: argumentArray toIndex: TempFrameStart ofObject: blockContext. "Assume: The call to transfer:... makes blockContext a root if necessary, allowing use to use unchecked stored in the following code." initialIP _ self fetchPointer: InitialIPIndex ofObject: blockContext. self storePointerUnchecked: InstructionPointerIndex ofObject: blockContext withValue: initialIP. self storeStackPointerValue: arrayArgumentCount inContext: blockContext. self storePointerUnchecked: CallerIndex ofObject: blockContext withValue: activeContext. self newActiveContext: blockContext. ] ifFalse: [self unPop: 2].! ! --============_-1348667088==_============ Content-Type: text/plain; name="ChangeSetCommentFix.st"; charset="us-ascii" Content-Disposition: attachment; filename="ChangeSetCommentFix.st" 'From Squeak 1.19d of April 13, 1997 on 11 May 1997 at 4:46:17 pm'! !ChangeSet methodsFor: 'private'! fileOutClassModifications: class on: stream "Write out class mod-- rename, comment, reorg, remove, on the given stream. Differs from the superseded fileOutClassChanges:on: in that it does not deal with class definitions, and does not file out entire added classes. 5/15/96 sw 10/28/96 sw: put out a rename indicator that won't halt if class of old name not there." (self atClass: class includes: #rename) ifTrue: [stream nextChunkPut: 'Smalltalk renameClassNamed: #', (self oldNameFor: class), ' as: #', class name; cr]. (self atClass: class includes: #comment) ifTrue: [class theNonMetaClass organization putCommentOnFile: stream numbered: nil moveSource: false. stream cr]. (self atClass: class includes: #reorganize) ifTrue: [class fileOutOrganizationOn: stream. stream cr]! ! --============_-1348667088==_============--

Post a reply.

Go back to index.



Date: 97 May 12 8:35:47 am From: Dan Ingalls <DanI@wdi.disney.com> To: Squeak@create.ucsb.edu Subject: Pure Rectangles and Points I have another, larger, fileIn with which I shall not burden everyone, but I thought I'd announce its availability in case anyone wants it. This fileIn removes some 40 methods that cause side-effects to points and rectangles, and redefines about 50 methods so that they replace with copies instead of using side-effects. This was very satisfying to do. My feeling (and my experience) is that this more functional coding style is less prone to errors, and I intend to include these changes in the next release of Squeak. Let me know if you would like an advanced copy now. - Dan P.S. I'm also interested in a Squeak variant that *always* uses side-effects for change (for high performance), but I don't think it makes such a good general purpose programming language.

Post a reply.

Go back to index.



Date: 97 May 12 8:46:31 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu In-Reply-To: <v03102800af9cd0d6b708@[129.34.225.178]> Subject: Re: Float #hash method LONG and DULL At 10:08 -0400 5/12/97, David N. Smith wrote: >At 6:01 -0400 5/12/97, Wim Boot wrote: >>David N. Smith wrote: >> >>>All float fans: >>> >>>The Float hash method seems left over from olden days where small integers >>>were 16K or so. It uses only one part of the float, possibly giving quite >>>different answers depending on byte ordering. >> >>Indeed. There are worse (very ancient) problems however. >> >>Try "1 hash = 1.0 hash" or "(3/2) hash = 1.5 hash". False in >>both cases, though "1 = 1.0" and "(3/2) = 1.5" both yield true. >> >>Your hashDNS method doesn't address this problem either. >> >>Wim Boot > >Wim: > >Maybe I'm missing something, but I wouldn't expect two different objects to >have the same hash just because they have the same 'value'. (3/2) is a >completely different object than 1.5 > >How about: > > 'abc' = #abc > true > > 'abc' hash = #abc hash > false > >Should the hash of a string always be the hash of a symbol containing the >same characters? Symbols are typically guaranteed to have different hashes >for different values; strings are not because of the expense in many >implementations. > >dave Sorry, it was before coffee. I know better. However, I only tested it in Squeak and that's what it answers! Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 12 9:27:32 am From: Maloney <johnm@wdi.disney.com> To: "David N. Smith" <dnsmith@watson.ibm.com> Cc: squeak@create.ucsb.edu In-Reply-To: <v03102805af9b9e000ef8@[129.34.225.178]> Subject: Float Byte Ordering Re: >The Float hash method seems left over from olden days where small integers >were 16K or so. It uses only one part of the float, possibly giving quite >different answers depending on byte ordering. Just so everyone knows, in the 1.18 Squeak release we made Squeak Floats keep the same byte ordering (IEEE standard) on all platforms. On machines whose hardware floats have a different byte ordering, the bytes are swapped just before doing a float operation. (This turned out to not take significant additional time because we had to deal with the possibility of misaligned floats so had to move the float into a temporary variable before operating on it anyway.) So, the the byte ordering of Squeak Floats is the same on all platforms; it is safe to depend on it. -- John P.S. Thanks for your ongoing contributions to improving Squeak's number classes, Dave!

Post a reply.

Go back to index.



Date: 97 May 12 9:32:43 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: johnson@cs.uiuc.edu (Ralph E. Johnson) Cc: squeak@create.ucsb.edu In-Reply-To: <v01540b0daf9c885e9858@[130.126.27.213]> Subject: Re: Float #hash method LONGer and DULLer At 10:44 -0400 5/12/97, Ralph E. Johnson wrote: >At 10:08 AM 5/12/97, David N. Smith wrote: >>Maybe I'm missing something, but I wouldn't expect two different objects to >>have the same hash just because they have the same 'value'. (3/2) is a >>completely different object than 1.5 > >Sets and dictionaries assume that equal objects hash equally. Suppose >x and y are two objects that are equal but have different hashes. If >you put x in a set and ask whether the set includes y, the answer will >be false unless x and y just happened to hash into the same location, in >which the answer is true. So, if you redefine = then you should redefine >hash. > >-Ralph Ralph: OK, I forgot. It is true that any two objects that answer true to #= should answer the same #hash value so that certain collections work. Duh! I knew that; I even have the T-Shirt! But, now that I've been caught, I'd like to argue that this is a poor rule. First, some rubber on the road... I just ran these two tests. Booleans in comments are the results to that point. ------------------------------------ First, Squeak 1.19 (using the original hash): | s | s := Set new. s add: 1.5. s includes: (3/2). "false" s add: (3/2). s includes: (3/2). "true" s inject: OrderedCollection new into: [ :inj :elem | inj add: elem. inj ] OrderedCollection (1.5 (3/2) ) | b | b := Bag new. b add: 1.5. b includes: (3/2). "false" b add: (3/2). b includes: (3/2). "true " b inject: OrderedCollection new into: [ :inj :elem | inj add: elem. inj ] OrderedCollection (1.5 (3/2) ) These act like I think they should act, even if it is due to broken #hash methods. Both the Set and the Bag have two elements of two different classes. ------------------------------------ Then VW 2.5 and IBM Smalltalk V3:: | s | s := Set new. s add: 1.5. s includes: (3/2). "true" s add: (3/2). s includes: (3/2). "true" s inject: OrderedCollection new into: [ :inj :elem | inj add: elem. inj ] OrderedCollection (1.5) | b | b := Bag new. b add: 1.5. b includes: (3/2). "true" b add: (3/2). b includes: (3/2). "true " b inject: OrderedCollection new into: [ :inj :elem | inj add: elem. inj ] OrderedCollection (1.5 1.5) I find this bizare in the extreme: I add a Fraction and it goes away! But notice what happens if I add the elements in the other order (VW 2.5): | s | s := Set new. s add: (3/2). s includes: 1.5. "true" s add: 1.5. s includes: 1.5. "true" s inject: OrderedCollection new into: [ :inj :elem | inj add: elem. inj ] OrderedCollection ((3/2)) Now the float goes away! (I assume IBM/ST does the same thing.) ------------------------------------ However, change the data a little and one gets (on VW 2.5): | s | s := Set new. s add: 0.12499999886094d. s includes: (13717421/109739369). " false" s add: (13717421/109739369). s includes: (13717421/109739369). "true" s inject: OrderedCollection new into: [ :inj :elem | inj add: elem. inj ] OrderedCollection (0.12499999886094d (13717421/109739369)) Yet, converting the fraction to a Double (with asDouble) answers the floating point number. (It's probably off just in the last bit, but try to explain to a newby why one sometimes gets two elements and sometimes one.) ------------------------------------- There is no way to get it right with floating point numbers. One can always find some situation where computing a float provides a different result than an 'equivalent' literal. While it might be traditional to define hash and equality as they are, it leads to counterintuitive results (adding two different objects to a Set should always result in a set with either one or two objects and not a capricious sometimes it has two but maybe not), and it leads to horrible hash values. IBM Smalltalk achieves its equality of hashes by ignoring fractional parts. Float hash answers self truncated. Blah. I once ran a test of a Dictionary and the 'new' LookupTable class in IBM Smalltalk V3 to see if LookupTable was truly faster, as claimed. I generated a large number of random numbers in the default range [0.0-1.0) and threw them at instances of each class. The results were horrible. Both went out to lunch, or I did anyhow, as I waited for the tests to finish. Since hash for floats was defined as 'self truncated', EVERY key was 0.0. Both instances were doing lots of sequential lookups. Is some rule that two different objects have the same hash when some idea of value equality is met worth ruining the quality of hashes for their intended purpose as keys in collections? There is no way to get it right. Large integers, and fractions made up of large integers are really different objects than their floating point 'equivalents'. So are scaled decimal values and float values that 'look the same'. ------------------- So, what to do? Keep with tradition and live with the bizare results (and bad collection performance?) Or fix this mess? Can it be fixed? Is it reaonable to add an 'equal' fraction and float to a Set and usually get one element but not always? Can hash and #= be decoupled without wrecking some basic assumptions (other than in hashed collections?) IE, what else am I missing? Could we add a trueEquality: method in Object and require all users of hash to use it to compare two objects for equality? trueEquality: anObject ^ self class == anObject class and: [ self = anObject ] or, better, something like: trueEquality: anObject ^ (self classesAreEquivalent: anObject) and: [ self = anObject ] classesAreEquivalent: anObject ^ self class == anObject class which lets subclasses redefine class equivalence if and as needed. Hashing is too important to let the equality rule force bad hashes; esoteric rules should not compromise day-to-day performance. The current situation is ugly, if traditional, and maybe should be properly fixed in Squeak rather than just keeping the traditional solution. Hashing is clearly broken in Squeak in its current state. Or am I still missing something? Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 12 9:39:32 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: Hans-Martin Mosner <hmm@heeg.de> Cc: squeak@create.ucsb.edu In-Reply-To: <3377309D.31DFF4F5@heeg.de> Subject: Re: Float #hash method LONG and DULL At 11:00 -0400 5/12/97, Hans-Martin Mosner wrote: >David N. Smith wrote: >> > ...snip... > >> How about: >> >> 'abc' = #abc >> true >Should not be. Someone on this list acknowleged that it's a bug, because >#abc ~= 'abc'. Equality should work both ways. >> >> 'abc' hash = #abc hash >> false >> >> Should the hash of a string always be the hash of a symbol containing the >> same characters? >No, because that would be impossible. Symbols just have arbitrary hash >values >that are not related to their constituent characters. That's what I was trying to say... >(Which is probably bad for object migration. Setting the hash value of >a Symbol from the CRC of its characters might be better) > >> Symbols are typically guaranteed to have different hashes >> for different values; >No, Symbols are just guaranteed to be unique, that is, two >Symbols are the same object if and only if they have the same >characters. >Symbols (like other Objects) are guaranteed to have same hashes >for same values, though. Again, that's what I was trying to say... > >> strings are not because of the expense in many >> implementations. >For Symbols, hash is synonymous to identity hash (which is logical, >since >equality for Symbols is synonymous to identity) >For Strings, hash is a fast (and some say, bad) function of >the characters in the string. > >Hans-Martin Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 12 9:44:57 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: Dan Ingalls <DanI@wdi.disney.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <v03007800af9cf60e73e8@[206.16.10.79]> Subject: Re: Three fileIns At 12:43 -0400 5/12/97, Dan Ingalls wrote: >NumberFixes-di.cs >Three fixes to Float, suggested or requested by David Smith. Eliminates >amgiguity of non-decimal constants by requiring letter-digits to be >uppercase, and fixes two methods that used lowercase hex digits (thanks >tim). Renames the old asFraction code to be asApproximateFraction, and >installs David's asTrueFraction as well. Finally includes David's >improvement to Float>>hash. If there is a list somewhere of platform dependencies in Smalltalk code, it should note that #asTrueFraction is Endian sensitive... Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 12 9:50:21 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: Maloney <johnm@wdi.disney.com> Cc: squeak@create.ucsb.edu In-Reply-To: <v03007801af9cff1a63f1@[206.16.10.208]> Subject: Re: Float Byte Ordering At 13:17 -0400 5/12/97, Maloney wrote: >Re: >>The Float hash method seems left over from olden days where small integers >>were 16K or so. It uses only one part of the float, possibly giving quite >>different answers depending on byte ordering. > >Just so everyone knows, in the 1.18 Squeak release we made Squeak Floats >keep the same byte ordering (IEEE standard) on all platforms. On machines >whose hardware floats have a different byte ordering, the bytes are swapped >just before doing a float operation. (This turned out to not take significant >additional time because we had to deal with the possibility of misaligned >floats so had to move the float into a temporary variable before operating >on it anyway.) > >So, the the byte ordering of Squeak Floats is the same on all platforms; it >is safe to depend on it. > > -- John > >P.S. Thanks for your ongoing contributions to improving Squeak's number >classes, Dave! John: Neat! Dan can then safely ignore my post of 2 minutes ago, but the comment in #trueFraction should be changed. asTrueFraction " Answer a fraction that EXACTLY represents self, a double precision IEEE floating point number. (It tears an IEEE float into its components; since Squeak always stores Floats in the same order, this should work on all IEEE platforms.) Thanks to David N. Smith" | shifty sign exp fraction | shifty := ((self at: 1) bitShift: 32) bitOr: (self at: 2). sign := (shifty bitShift: -63) = 0 ifTrue: [1] ifFalse: [-1]. exp := (shifty >> 52) bitAnd: 16r7FF. fraction := shifty bitAnd: 16r000FFFFFFFFFFFFF. (exp = 0) & (fraction = 0) ifTrue: [ ^ 0 ]. fraction := fraction bitOr: 16r0010000000000000. exp := exp - 16r3FF. " Validate that the dismemberment was correct " (sign * fraction / (2 raisedToInteger: 52 - exp)) asFloat = self ifFalse: [self error: 'asFraction validation failed' ]. ^ sign * fraction / (2 raisedToInteger: 52 - exp)! ! Dave Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 12 10:32:49 am From: johnson@cs.uiuc.edu (Ralph E. Johnson) To: "David N. Smith" <dnsmith@watson.ibm.com> Cc: squeak@create.ucsb.edu Subject: Re: Float #hash method LONGer and DULLer At 1:00 PM 5/12/97, David N. Smith wrote: >There is no way to get it right. Large integers, and fractions made up of >large integers are really different objects than their floating point >'equivalents'. So are scaled decimal values and float values that 'look the >same'. >So, what to do? Keep with tradition and live with the bizare results (and >bad collection performance?) Or fix this mess? Can it be fixed? What to do? You should write an OOPSLA paper! >Is it reaonable to add an 'equal' fraction and float to a Set and usually >get one element but not always? No. Either always one, or never one, but "usually but not always" is horrendous! >Can hash and #= be decoupled without wrecking some basic assumptions (other >than in hashed collections?) IE, what else am I missing? I think hashed collections are the only place that makes that assumption. That is a pretty big "only", however. -Ralph

Post a reply.

Go back to index.



Date: 97 May 13 9:45:59 am From: Dan Ingalls <DanI@wdi.disney.com> To: Squeak@create.ucsb.edu Subject: Two other tidbits --============_-1348575084==_============ Content-Type: text/plain; charset="us-ascii" NewLabels gives our windows a new look -- not Mac-like, not Windows-like. A very simple change. BBFix32 is Andreas Raab's fix for 32-bit color on machines that wrap shifts greater than 31. It should have been included in my last VMchanges file. --============_-1348575084==_============ Content-Type: text/plain; name="NewLabels-di.cs"; charset="us-ascii" Content-Disposition: attachment; filename="NewLabels-di.cs" 'From Squeak 1.19d of April 13, 1997 on 2 May 1997 at 4:07:16 pm'! !StandardSystemView methodsFor: 'label access'! setLabelRegion "Always follows view width" labelFrame region: (0 @ 0 extent: self displayBox width @ self labelHeight). ! ! !StandardSystemView methodsFor: 'displaying'! deEmphasizeLabel "Un-Highlight the label." self displayLabelBackground: false. self displayLabelText.! displayLabelBackground: emphasized "Clear or emphasize the inner region of the label" | r1 r2 r3 c3 c2 c1 | emphasized ifFalse: ["Just clear the label if not emphasized" ^ Display fill: (self labelDisplayBox insetBy: 2) fillColor: self labelColor]. r1 _ self labelDisplayBox insetBy: 2. r2 _ r1 insetBy: 0@2. r3 _ r2 insetBy: 0@3. c3 _ self labelColor. c2 _ c3 darker. c1 _ c2 darker darker. Display fill: r1 fillColor: c1. Display fill: r2 fillColor: c2. Display fill: r3 fillColor: c3. " Here is the Mac racing stripe code stripes _ Bitmap with: (self labelColor pixelWordForDepth: Display depth) with: (Form black pixelWordForDepth: Display depth). self windowOrigin y even ifTrue: [stripes swap: 1 with: 2]. Display fill: (self labelDisplayBox insetBy: 3) fillColor: stripes. "! displayLabelText "The label goes in the center of the window" | labelRect | labelText foregroundColor: self foregroundColor backgroundColor: self labelColor. labelRect _ self labelTextRegion. Display fill: (labelRect expandBy: 3@0) fillColor: self labelColor. labelText displayOn: Display at: labelRect topLeft clippingBox: labelRect rule: labelText rule fillColor: labelText fillColor! emphasizeLabel "Highlight the label." self displayLabelBackground: true. self displayLabelBoxes. self displayLabelText.! ! StandardSystemView removeSelector: #displayRacingStripes! --============_-1348575084==_============ Content-Type: text/plain; name="BBFix32.cs"; charset="us-ascii" Content-Disposition: attachment; filename="BBFix32.cs" 'From Squeak 1.19d of April 13, 1997 on 13 May 1997 at 8:22:05 am'! !BitBltSimulation methodsFor: 'inner loop'! copyLoopPixMap "This version of the inner loop maps source pixels to a destination form with different depth. Because it is already unweildy, the loop is not unrolled as in the other versions. Preload, skew and skewMask are all overlooked, since pickSourcePixels delivers its destination word already properly aligned. Note that pickSourcePixels could be copied in-line at the top of the horizontal loop, and some of its inits moved out of the loop." | skewWord halftoneWord mergeWord destMask srcPixPerWord scrStartBits nSourceIncs startBits endBits sourcePixMask destPixMask nullMap | self inline: false. "Additional inits peculiar to unequal source and dest pix size..." srcPixPerWord _ 32//sourcePixSize. "Check for degenerate shift values 4/28/97 ar" sourcePixSize = 32 ifTrue: [ sourcePixMask _ -1] ifFalse: [ sourcePixMask _ (1 << sourcePixSize) - 1]. destPixSize = 32 ifTrue: [ destPixMask _ -1] ifFalse: [ destPixMask _ (1 << destPixSize) - 1]. nullMap _ colorMap = interpreterProxy nilObject. sourceIndex _ (sourceBits + 4) + (sy * sourceRaster + (sx // srcPixPerWord) *4). scrStartBits _ srcPixPerWord - (sx bitAnd: srcPixPerWord-1). bbW < scrStartBits ifTrue: [nSourceIncs _ 0] ifFalse: [nSourceIncs _ (bbW - scrStartBits)//srcPixPerWord + 1]. sourceDelta _ (sourceRaster - nSourceIncs) * 4. "Note following two items were already calculated in destmask setup!!" startBits _ pixPerWord - (dx bitAnd: pixPerWord-1). endBits _ ((dx + bbW - 1) bitAnd: pixPerWord-1) + 1. 1 to: bbH do: "here is the vertical loop" [ :i | noHalftone ifTrue: [halftoneWord _ AllOnes] ifFalse: [halftoneWord _ interpreterProxy longAt: (halftoneBase + (dy+i-1 \\ halftoneHeight * 4))]. srcBitIndex _ (sx bitAnd: srcPixPerWord - 1)*sourcePixSize. destMask _ mask1. "pick up first word" bbW < startBits ifTrue: [skewWord _ self pickSourcePixels: bbW nullMap: nullMap srcMask: sourcePixMask destMask: destPixMask. skewWord _ skewWord bitShift: (startBits - bbW)*destPixSize] ifFalse: [skewWord _ self pickSourcePixels: startBits nullMap: nullMap srcMask: sourcePixMask destMask: destPixMask]. "Here is the horizontal loop..." 1 to: nWords do: "here is the inner horizontal loop" [ :word | mergeWord _ self merge: (skewWord bitAnd: halftoneWord) with: ((interpreterProxy longAt: destIndex) bitAnd: destMask). interpreterProxy longAt: destIndex put: ((destMask bitAnd: mergeWord) bitOr: (destMask bitInvert32 bitAnd: (interpreterProxy longAt: destIndex))). destIndex _ destIndex + 4. word >= (nWords - 1) ifTrue: [word = nWords ifFalse: ["set mask for last word in this row" destMask _ mask2. skewWord _ self pickSourcePixels: endBits nullMap: nullMap srcMask: sourcePixMask destMask: destPixMask. skewWord _ skewWord bitShift: (pixPerWord-endBits)*destPixSize]] ifFalse: ["use fullword mask for inner loop" destMask _ AllOnes. skewWord _ self pickSourcePixels: pixPerWord nullMap: nullMap srcMask: sourcePixMask destMask: destPixMask]]. sourceIndex _ sourceIndex + sourceDelta. destIndex _ destIndex + destDelta]! ! !BitBltSimulation methodsFor: 'pixel mapping'! warpSourcePixels: nPix xDeltah: xDeltah yDeltah: yDeltah xDeltav: xDeltav yDeltav: yDeltav smoothing: n sourceMap: sourceMapOop "Pick nPix pixels using these x- and y-incs, and map color if necess." | destWord sourcePix sourcePixMask destPixMask srcPixPerWord destPix | "Fix degenerate shift values 4/28/97 ar" sourcePixSize = 32 ifTrue: [ sourcePixMask _ -1] ifFalse: [ sourcePixMask _ (1 << sourcePixSize) - 1]. destPixSize = 32 ifTrue: [ destPixMask _ -1] ifFalse: [ destPixMask _ (1 << destPixSize) - 1]. srcPixPerWord _ 32 // sourcePixSize. destWord _ 0. 1 to: nPix do: [:i | n > 1 ifTrue: ["Average n pixels and compute dest pixel from color map" destPix _ (self smoothPix: n atXf: sx yf: sy dxh: xDeltah//n dyh: yDeltah//n dxv: xDeltav//n dyv: yDeltav//n pixPerWord: srcPixPerWord pixelMask: sourcePixMask sourceMap: sourceMapOop) bitAnd: destPixMask] ifFalse: ["No smoothing -- just pick pixel and map if difft depths or color map supplied" sourcePix _ (self sourcePixAtX: sx >> BinaryPoint y: sy >> BinaryPoint pixPerWord: srcPixPerWord) bitAnd: sourcePixMask. colorMap = interpreterProxy nilObject ifTrue: [destPixSize = sourcePixSize ifTrue: [destPix _ sourcePix] ifFalse: [sourcePixSize >= 16 ifTrue: ["Map between RGB pixels" sourcePixSize = 16 ifTrue: [destPix _ self rgbMap: sourcePix from: 5 to: 8] ifFalse: [destPix _ self rgbMap: sourcePix from: 8 to: 5]] ifFalse: [destPix _ sourcePix bitAnd: destPixMask]]] ifFalse: [sourcePixSize >= 16 ifTrue: ["RGB pixels first get reduced to cmBitsPerColor" sourcePixSize = 16 ifTrue: [sourcePix _ self rgbMap: sourcePix from: 5 to: cmBitsPerColor] ifFalse: [sourcePix _ self rgbMap: sourcePix from: 8 to: cmBitsPerColor]]. "Then look up sourcePix in colorMap" destPix _ (interpreterProxy fetchWord: sourcePix ofObject: colorMap) bitAnd: destPixMask]]. destWord _ (destWord << destPixSize) bitOr: destPix. sx _ sx + xDeltah. sy _ sy + yDeltah. ]. ^ destWord! ! --============_-1348575084==_============--

Post a reply.

Go back to index.



Date: 97 May 13 11:36:18 pm From: "Ted K." <tedk@wdi.disney.com> To: squeak@create.ucsb.edu Subject: Squeak collaboration (AgentBase is Michael Korns' very large lisp-based database integrator. A neat system. -tk) >From: "Michael Korns" <mkorns@ix.netcom.com> >To: "Ted Kaehler" <kaehler2@webpage.com> >Subject: Squeak collaboration >Date: Tue, 13 May 1997 10:13:34 -0700 > >Ted, > >There is an internet interest group forming to discuss the construction of >a Universal Virtual Machine which would run Java, Lisp, Smalltalk, Prolog, >etc. agents across the net. > >AgentBase is participating in these initial discussions, and would like to >be able to provide persistence and server execution for agents developed in >the above languages (as well as SmartLisp). > >I'm wondering if you could send me the URL where I can down load the latest >copy of Squeak? Would you be willing to lend guidance and technical >consulting if we tried to enhance AgentBase to support Squeak >agents/applets? > >I'll call later to talk. > > >************************************** >Michael F. Korns >214 Shorebreaker >Laguna Niguel, California 92677 >(714) 443-4847 >mkorns@ix.netcom.com >************************************* > Ted Kaehler Walt Disney Imagineering, R&D (home) 3415 Cork Oak Way, Palo Alto, CA 94303 voice (415) 424-1070 http://www.webPage.com/~kaehler2/

Post a reply.

Go back to index.



Date: 97 May 14 12:27:21 am From: mack@sfo.com (Michael Ackerman) To: squeak@create.ucsb.edu Subject: Which Smalltalk is Squeak? I am new to Smalltalk and Squeak. I understand that Squeak is "basically" Smalltalk-80, but I have read that Smalltalk-80 comes in two versions, and that the 2nd version supports multiple inheritance, while the first does not. Which version is Squeak most like? Thanks. Michael Ackerman

Post a reply.

Go back to index.



Date: 97 May 14 7:31:15 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: Casing the joint To whom, etc: Two methods in Object, #case: and #case:otherwise: seem not to be used anywhere in the image (1.19d). Are they still needed? They seem to take a parameter that is an instance of BlockAssociationCollection but there is no class with that name. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 14 7:33:35 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: mack@sfo.com (Michael Ackerman) Cc: squeak@create.ucsb.edu In-Reply-To: <v01510101af9f2d932341@[207.33.216.22]> Subject: Re: Which Smalltalk is Squeak? At 4:55 -0400 5/14/97, Michael Ackerman wrote: >I am new to Smalltalk and Squeak. I understand that Squeak is "basically" >Smalltalk-80, but I have read that Smalltalk-80 comes in two versions, and >that the 2nd version supports multiple inheritance, while the first does >not. Which version is Squeak most like? > Thanks. > >Michael Ackerman Michael: I'm probably not the right person to answer this, but to my knowledge the MI code in Smalltalk-80 worked but no one used it. Squeak does not support it to the best of my knowledge. Why? Because, unlike C++ where MI seems to be important for reasons I don't quite get, it is not important in Smalltalk. The arguments have raged for years, and there have been implementations, but when the rubber hits the road no one really uses MI in Smalltalk. SELF, a "Smalltalk variant" :), has MI; maybe one of the SELFers here can speak about it. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 14 9:11:08 am From: Hans-Martin Mosner <hmm@heeg.de> To: Squeak Mailing List <squeak@create.ucsb.edu> Subject: Morphic Menus, and 8-bit color dithering This is a multi-part message in MIME format. --------------64880EEB773C24486F5992E1 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hello, here is a first implementation of morphic menus. You'll probably like them, although they're a little slow on low-end machines. Another goodie: dithering for 8-bit color. Makes the #lighter and #darker colors look much better... --------------64880EEB773C24486F5992E1 Content-Type: text/plain; charset=us-ascii; name="Color-dithering.st" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Color-dithering.st" !Color methodsFor: 'conversions'! bitPatternForDepth: depth "The raw call on BitBlt needs a Bitmap to represent this color. Return the color at the destination Form depth as a Bitmap. Patterns return longer Bitmaps. 6/14/96 tk For the bits that are in a single pixel, use pixelValueAtDepth:. For a 32-bit integer of (32/depth) pixels, use pixelWordAtDepth:" | brightness | depth == cachedDepth ifTrue: [^ cachedBitPattern]. cachedDepth := depth. depth > 1 ifTrue: [^ cachedBitPattern := self computeBitPatternForDepth: depth]. "Spatial halftones for depth 1" brightness := self luminance. brightness < 0.2 ifTrue: [ ^ cachedBitPattern := Bitmap with: 16rFFFFFFFF]. "black" brightness < 0.4 ifTrue: [ ^ cachedBitPattern := Bitmap with: 16rBBBBBBBB with: 16rEEEEEEEE]. "dark gray" brightness < 0.6 ifTrue: [ ^ cachedBitPattern := Bitmap with: 16r55555555 with: 16rAAAAAAAA]. "medium gray" brightness < 0.8 ifTrue: [ ^ cachedBitPattern := Bitmap with: 16r44444444 with: 16r11111111]. "light gray" ^ cachedBitPattern := Bitmap with: 16r0. "white"! computeBitPatternForDepth: depth | pixels | depth = 8 ifFalse: [^Bitmap with: (self pixelWordForDepth: depth)]. pixels := self fourPixelValuesForDither: depth. ^Bitmap with: (16r10001 * (pixels at: 1)) + (16r1000100 * (pixels at: 3)) with: (16r10001 * (pixels at: 4)) + (16r1000100 * (pixels at: 2))! fourPixelValuesForDither: depth | r g b rPlus gPlus bPlus | depth = 8 ifFalse: [^Array new: 4 withAll: (self pixelValueForDepth: depth)]. rgb = 0 ifTrue: [^ Array new: 4 withAll: 1]. "Special case for black, very common" rgb = 16r3FFFFFFF ifTrue: [^ Array new: 4 withAll: 0 "255"]. "Special case for white, very common" self privateRed = self privateGreen ifTrue: [ self privateRed = self privateBlue ifTrue: [^Array new: 4 withAll: self closestPixelValue8]]. r := (self privateRed * 5) // ComponentMask. g := (self privateGreen * 5) // ComponentMask. b := (self privateBlue * 5) // ComponentMask. rPlus := (self privateRed * 5) \\ ComponentMask * 4 + HalfComponentMask // ComponentMask. gPlus := (self privateGreen * 5) \\ ComponentMask * 4 + HalfComponentMask // ComponentMask. bPlus := (self privateBlue * 5) \\ ComponentMask * 4 + HalfComponentMask // ComponentMask. ^(1 to: 4) collect: [:i | (r + (i > rPlus ifTrue: [0] ifFalse: [1]) * 36) + (b + (i > bPlus ifTrue: [0] ifFalse: [1]) * 6) + (g + (i > gPlus ifTrue: [0] ifFalse: [1])) + 40] ! ! --------------64880EEB773C24486F5992E1 Content-Type: text/plain; charset=us-ascii; name="MorphicMenus.cs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="MorphicMenus.cs" 'From Squeak 1.19d of April 13, 1997 on 14 May 1997 at 4:35:18 pm'! StringMorph subclass: #MenuItemMorph instanceVariableNames: 'action flags subMenu ' classVariableNames: 'SubMenuMarker ' poolDictionaries: '' category: 'Morphic-Menus'! Morph subclass: #MenuLineMorph instanceVariableNames: '' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Menus'! LayoutMorph subclass: #MenuMorph instanceVariableNames: 'lastSelection receiver popUpOwner ' classVariableNames: '' poolDictionaries: '' category: 'Morphic-Menus'! !Object methodsFor: 'menus'! dispatchAsMenuActionTo: anObject "Don't know what to do..."! performMenuAction: anObject ^anObject dispatchAsMenuActionTo: self! performMenuAction: anObject with: argument ^anObject dispatchAsMenuActionTo: self with: argument! ! !BlockContext methodsFor: 'menus'! dispatchAsMenuActionTo: anObject ^self numArgs = 0 ifTrue: [self value] ifFalse: [self value: anObject]! dispatchAsMenuActionTo: anObject with: argument ^self numArgs = 0 ifTrue: [self value] ifFalse: [self numArgs = 1 ifTrue: [self value: anObject] ifFalse: [self value: anObject value: argument]]! performMenuAction: anObject self value: anObject! ! !HandMorph methodsFor: 'event dispatching'! handleMouseUp: evt | oldFocus | mouseFocus = nil ifTrue: [^ self dropMorphsEvent: evt]. "drop morphs being carried, if any" "ensure that at least one mouseMove: is reported for each mouse focus transaction:" mouseFocus mouseMove: (self transformEvent: (evt copy setType: #mouseMove)). oldFocus := mouseFocus. "make sure that focus becomes nil." mouseFocus _ nil. "mouse focus transaction ends when mouse goes up" oldFocus mouseUp: (self transformEvent: evt). ! ! !HandMorph methodsFor: 'meta menu'! buildMetaMenu "Build the meta menu. This menu has two sections. The first section contains commands that are interpreted by the hand itself; the second contains commands provided by the morph itself. Each entry contains a string to be presented in the menu and a symbol to be sent to either the hand itself (for commands in the first section) or to the morph provided the menu (for commands in the second section). If a selector takes an argument, the mouse-down event that invoked the menu is provided. This lets the command know which hand invoked it in order to do things like attaching the result of the command to that hand." | menu arg | menu _ MenuMorph new. arg _ self argumentOrNil. arg == nil ifTrue: [ menu add: 'new morph' action: #newMorph. menu add: 'new parts bin' action: #newPartsBin. menu add: 'new drawing' action: #makeNewDrawing. menu add: 'change background color' action: #changeBackgroundColor. menu addLine. menu add: 'parts bin' action: #partsBin. menu add: 'run all' action: #startRunningAll. menu add: 'stop all' action: #stopRunningAll. menu addLine. menu add: 'add control variable ' action: #newVariable. menu add: 'save as model ' action: #saveAsModel. menu add: 'save as world' action: #saveAsWorld. menu addLine. menu add: 'inspect this world' action: #inspectWorld. lastMetaMenuItem _ menu selections size. ^ menu]. menu add: 'grab' action: #grabMorph. menu add: 'dismiss' action: #dismissMorph. menu add: 'go behind' action: #goBehind. menu add: 'duplicate' action: #duplicateMorph. ((self world rootMorphsAt: targetOffset) size > 1) ifTrue: [menu add: 'embed' action: #embedMorph]. menu add: 'grab or extract' action: #extractMorph. menu add: 'inspect' action: #inspectMorph. menu add: 'browse' action: #browseMorphClass. menu add: 'make own subclass' action: #subclassMorph. menu addLine. arg isMouseSensor ifTrue: [menu add: 'desensitize' action: #desensitizeMorph] ifFalse: [menu add: 'sensitize' action: #sensitizeMorph]. arg nameInModel ifNil: [ menu add: 'name me' action: #nameMorph]. menu addLine. (arg isKindOf: SketchMorph) ifFalse: [ (arg isKindOf: StringMorph) ifFalse: [ menu add: 'resize' action: #resizeMorph. ]. menu add: 'fill color' action: #changeColor. ]. menu addLine. lastMetaMenuItem _ menu selections size. arg addCustomMenuItems: menu hand: self. ^ menu ! invokeMetaMenu: evt | menu caption receiver saveTargetOffset | targetOffset _ saveTargetOffset _ self position. menu _ self buildMetaMenu. self argumentOrNil == nil ifTrue: [caption _ 'World'] ifFalse: [caption _ self argumentOrNil class name]. menu addTitle: caption. menu lastSelectionAction: lastMenuSelection. menu popUpOwner: self. menu receiver: [:item | targetOffset _ saveTargetOffset. menu delete. owner displayWorld. item ifNotNil: [ lastMenuSelection _ item. receiver := (menu selections indexOf: item) <= lastMetaMenuItem ifTrue: [self] ifFalse: [self argumentOrNil]. Cursor normal showWhile: [receiver performMenuAction: item with: evt]]]. menu popUpAt: evt cursorPoint in: owner. self newMouseFocus: menu items first! newMorph | morphClassList menu categories subMenu | menu _ MenuMorph new. menu addTitle: 'Select Morph Class'. morphClassList _ Morph withAllSubclasses asSortedCollection: [:m1 :m2 | m1 class name < m2 class name]. morphClassList remove: WorldMorph; remove: HandMorph; remove: MorphicModel; remove: RemoteHandMorph. morphClassList := morphClassList select: [:c | (c inheritsFrom: MorphicModel) not or: ["Only include Models that have been saved" c includesSelector: #initMorph]]. categories := (morphClassList collect: [:each | each category]) asSet asSortedCollection. categories do: [:cat | subMenu := MenuMorph new. subMenu receiver: [:cls | self newMorphOfClass: cls]. morphClassList do: [:each | each category = cat ifTrue: [subMenu add: each name action: each]]. menu add: cat subMenu: subMenu]. menu popUpOwner: self. menu popUpAt: self position in: owner! newMorphOfClass: morphClass "taken out of the old method #newMorph" | m | m _ morphClass new. m installModelIn: owner. "A chance to install model pointers" self attachMorph: m. owner startSteppingSubmorphsOf: m! ! !LayoutMorph methodsFor: 'private'! resizeIfNeeded "Resize this morph if it is space-filling or shrink-wrap and its owner is not a layout morph." | newExtent | newExtent _ bounds extent. (owner == nil or: [owner isLayoutMorph not]) ifTrue: [ "if spaceFill and not in a LayoutMorph, grow to enclose submorphs" hResizing = #spaceFill ifTrue: [newExtent x: (self minWidth max: self bounds width)]. vResizing = #spaceFill ifTrue: [newExtent y: (self minHeight max: self bounds height)]]. "if shrinkWrap, adjust size to just fit around submorphs" hResizing = #shrinkWrap ifTrue: [newExtent x: self minWidth]. vResizing = #shrinkWrap ifTrue: [newExtent y: self minHeight]. newExtent = bounds extent ifFalse: [ "bounds really changed" bounds _ bounds topLeft extent: newExtent. self fixLayout. self layoutChanged "flush fullBounds cache"]. ! ! !MenuItemMorph methodsFor: 'flag accessing'! isEnabled ^(flags bitAnd: 1) = 0! isEnabled: aBoolean self isEnabled = aBoolean ifTrue: [^self]. flags := flags bitXor: 1. self color: (aBoolean ifTrue: [Color black] ifFalse: [Color gray])! isInTransition ^(flags bitAnd: 2) > 0! isInTransition: aBoolean self isInTransition = aBoolean ifTrue: [^self]. flags := flags bitXor: 2. self changed. self showSubMenu! ! !MenuItemMorph methodsFor: 'accessing'! action ^action! action: aSymbol action := aSymbol! subMenu ^subMenu! subMenu: aMenuMorph subMenu := aMenuMorph. self changed! ! !MenuItemMorph methodsFor: 'drawing'! drawOn: aCanvas (self isInTransition and: [self isEnabled]) ifTrue: [aCanvas fillRectangle: self bounds color: owner color darker]. super drawOn: aCanvas. subMenu == nil ifFalse: [aCanvas image: SubMenuMarker at: (self bounds right - 8 @ (self bounds top + self bounds bottom - SubMenuMarker height + 1 // 2))]! ! !MenuItemMorph methodsFor: 'initialize-release'! initialize color _ Color black. owner _ nil. submorphs _ EmptyArray. font _ nil. hasFocus _ false. contents := ''. bounds := 0@0 extent: 10@10. flags := 0! ! !MenuItemMorph methodsFor: 'events'! mouseDown: evt "Handle a mouse down event. Menu items get activated when the mouse is over them." self isInMenu ifFalse: [^super mouseDown: evt]. evt shiftPressed ifTrue: ["enable label editing" ^super mouseDown: evt]. evt hand newMouseFocus: self. self isInTransition: true! mouseMove: evt | m | m _ self world mouseRecipientAt: evt cursorPoint. self isInTransition: m == self. m == self ifTrue: [^self]. (((m isKindOf: MenuItemMorph) and: [m isInMenu]) and: [ m owner == self owner or: [ m owner == subMenu or: [ m owner hasSubMenu: owner]]]) ifTrue: [m owner == subMenu ifFalse: [self hideSubMenu]. (m owner == self owner or: [m subMenu == owner or: [m owner == subMenu]]) ifFalse: [owner delete]. evt hand newMouseFocus: m]! mouseUp: evt "Handle a mouse up event. Menu items get activated when the mouse is over them." self isInTransition: false. self isInMenu ifTrue: [ owner deleteIfPopUp. subMenu == nil ifFalse: [self hideSubMenu] ifTrue: [(self bounds containsPoint: evt cursorPoint) ifTrue: [owner itemWasSelected: self]]]! ! !MenuItemMorph methodsFor: 'layout'! hResizing ^#spaceFill! isLayoutMorph ^true! layoutInExtent: aPoint | scanner | scanner _ QuickPrint newOn: Display box: Display boundingBox font: font. self extent: ((scanner stringWidth: contents) @ (scanner lineHeight) max: aPoint)! minHeight ^self extent y! minWidth | scanner | scanner _ QuickPrint newOn: Display box: Display boundingBox font: font. ^(scanner stringWidth: contents) + (subMenu == nil ifTrue: [0] ifFalse: [10])! vResizing ^#shrinkWrap! ! !MenuItemMorph methodsFor: 'private'! hideSubMenu subMenu == nil ifFalse: [subMenu delete]. self isInTransition: false! isInMenu ^owner isKindOf: MenuMorph! showSubMenu subMenu == nil ifFalse: [ subMenu delete; popUpOwner: self. subMenu popUpAt: self bounds topRight in: self world]! ! !MenuItemMorph class methodsFor: 'class initialization'! initialize "MenuItemMorph initialize" SubMenuMarker := Form extent: 5@9 fromArray: #( 2147483648 3221225472 3758096384 4026531840 4160749568 4026531840 3758096384 3221225472 2147483648) offset: 0@0! ! !MenuLineMorph methodsFor: 'drawing'! drawOn: aCanvas aCanvas fillRectangle: (bounds topLeft corner: bounds rightCenter) color: owner color darker. aCanvas fillRectangle: (bounds leftCenter corner: bounds bottomRight) color: owner color lighter! ! !MenuLineMorph methodsFor: 'layout'! hResizing ^#spaceFill! isLayoutMorph ^true! layoutInExtent: aPoint self extent: aPoint! minHeight ^2! minWidth ^10! vResizing ^#shrinkWrap! ! !MenuMorph methodsFor: 'initialize-release'! initialize super initialize. self setColor: (Color red: 0.8 green: 0.8 blue: 0.8) borderWidth: 2 borderColor: #raised. inset := 3. orientation _ #vertical. hResizing _ #shrinkWrap. vResizing _ #shrinkWrap. ! ! !MenuMorph methodsFor: 'geometry'! minHeightWhenEmpty ^ 10 ! minWidthWhenEmpty ^ 20 ! popUpAt: aPoint in: world | selectedItem delta | selectedItem := self items detect: [:each | each == lastSelection] ifNone: []. selectedItem == nil ifTrue: [self position: aPoint] ifFalse: [self position: aPoint - selectedItem position + self position]. delta := self bounds amountToTranslateWithin: world bounds. delta = (0@0) ifFalse: [self position: self position + delta]. world addMorphFront: self. self changed! positionSelectionAt: aPoint | selectedItem | selectedItem := self items detect: [:each | each == lastSelection] ifNone: []. selectedItem == nil ifTrue: [self position: aPoint] ifFalse: [self position: aPoint - selectedItem position + self position]! ! !MenuMorph methodsFor: 'adding'! add: aString action: anAction | item | item := MenuItemMorph new. item contents: aString; action: anAction. self addMorphBack: item! add: aString subMenu: aMenuMorph | item | item := MenuItemMorph new. item contents: aString; subMenu: aMenuMorph. self addMorphBack: item! addLine self addMorphBack: MenuLineMorph new! addTitle: aString | title | title := LayoutMorph new setColor: (Color red: 0.5 green: 1 blue: 0.75) borderWidth: 1 borderColor: #inset. title vResizing: #shrinkWrap. title orientation: #vertical. title centering: #center. title addMorph: (StringMorph new contents: aString). self addMorphFront: title! ! !MenuMorph methodsFor: 'accessing'! hasSubMenu: aMenuMorph | sub | self items do: [:each | sub := each subMenu. sub == nil ifFalse: [ sub == aMenuMorph ifTrue: [^true]. (sub hasSubMenu: aMenuMorph) ifTrue: [^true]]]. ^false! isPopUp ^popUpOwner notNil! items ^submorphs select: [:each | each isKindOf: MenuItemMorph]! lastSelectionAction ^lastSelection == nil ifTrue: [lastSelection action]! lastSelectionAction: aSymbol lastSelection := self items detect: [:each | each action == aSymbol] ifNone: []! popUpOwner ^popUpOwner! popUpOwner: aMenuItemMorph popUpOwner := aMenuItemMorph! receiver ^receiver! receiver: anObject receiver := anObject! selections ^self items collect: [:each | each action]! ! !MenuMorph methodsFor: 'menu'! addCustomMenuItems: aCustomMenu hand: aHandMorph super addCustomMenuItems: aCustomMenu hand: aHandMorph. aCustomMenu addLine. aCustomMenu add: 'add item...' action: #addItem. aCustomMenu add: 'add title...' action: #addTitle. aCustomMenu add: 'add line' action: #addLine. (self canDetachSubMenu: aHandMorph) ifTrue: [aCustomMenu add: 'detach submenu' action: #detachSubMenu:]! addItem | string action | string := FillInTheBlank request: 'Label for new item?'. string = '' ifTrue: [^self]. action := FillInTheBlank request: 'Action?'. action := action = '' ifFalse: [action first = $[ ifTrue: [Object readFromString: action] ifFalse: [action asSymbol]]. self add: string action: action! addTitle | string | string := FillInTheBlank request: 'Title for menu?'. string = '' ifTrue: [^self]. self addTitle: string! beSubMenu: evt | rootMorphs targetRoot targetMorph | rootMorphs _ evt hand world rootMorphsAt: evt hand targetOffset. rootMorphs size < 2 ifTrue: [^ self]. targetRoot _ rootMorphs at: 2. targetMorph _ evt hand chooseTargetSubmorphOf: targetRoot. targetMorph ifNotNil: [ targetMorph subMenu: self. self delete. targetMorph changed]. ! canDetachSubMenu: hand | possibleTargets item | possibleTargets := hand argumentOrNil morphsAt: hand targetOffset. item := possibleTargets detect: [:each | each isKindOf: MenuItemMorph] ifNone: []. item == nil ifTrue: [^false]. ^item subMenu notNil! deleteIfPopUp self isPopUp ifTrue: [ self delete. (popUpOwner isKindOf: MenuItemMorph) ifTrue: [ popUpOwner owner deleteIfPopUp]]. ! detachSubMenu: evt | possibleTargets item | possibleTargets := evt hand argumentOrNil morphsAt: evt hand targetOffset. item := possibleTargets detect: [:each | each isKindOf: MenuItemMorph] ifNone: []. item == nil ifTrue: [^self]. item subMenu == nil ifFalse: [ evt hand attachMorph: item subMenu. item subMenu popUpOwner: nil. item subMenu: nil]! itemWasSelected: aMenuItem lastSelection := aMenuItem. receiver performMenuAction: aMenuItem action! ! !MenuMorph methodsFor: 'dropping/grabbing'! acceptDroppingMorph: aMorph event: evt "Allow the user to add submorphs just by dropping them on this morph." | item | (aMorph isKindOf: MenuMorph) ifTrue: [ item := (self morphsAt: evt cursorPoint) detect: [:each | each isKindOf: MenuItemMorph] ifNone: []]. item == nil ifTrue: [^super acceptDroppingMorph: aMorph event: evt]. item subMenu: aMorph. aMorph delete! ! !MorphicEvent methodsFor: 'private'! setMousePoint: aPoint buttons: anInteger lastEvent: lastEvent hand: hand cursorPoint _ aPoint. buttons _ anInteger. keyValue _ 0. sourceHand _ hand. self anyButtonPressed ifTrue: [ lastEvent anyButtonPressed ifTrue: [type _ #mouseMove] ifFalse: [type _ #mouseDown]. ] ifFalse: [ lastEvent anyButtonPressed ifTrue: [type _ #mouseUp] ifFalse: [type _ #mouseMove]]. ! ! !Symbol methodsFor: 'menus'! dispatchAsMenuActionTo: receiver ^receiver perform: self! dispatchAsMenuActionTo: receiver with: argument ^self numArgs = 0 ifTrue: [receiver perform: self] ifFalse: [receiver perform: self with: argument]! ! MenuItemMorph initialize! --------------64880EEB773C24486F5992E1--

Post a reply.

Go back to index.



Date: 97 May 14 9:16:21 am From: Dan Ingalls <DanI@wdi.disney.com> To: "David N. Smith" <dnsmith@watson.ibm.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <v03102803af9f82361441@[129.34.225.178]> Subject: Re: Casing the joint >Two methods in Object, #case: and #case:otherwise: seem not to be used >anywhere in the image (1.19d). > >Are they still needed? > >They seem to take a parameter that is an instance of >BlockAssociationCollection but there is no class with that name. > >Dave David, and all -- Squeak has a brace construct that was put in by Larry Tesler, in the early= days of Apple Smalltalk. It is not part of the ST-80 standard. = Consequently, we do not use it in the system, and we have never encouraged= its use. Moverover some of the lateral support in the Decompiler, etc., no= longer works, though neither should it be hard to fix. It's pretty simple. The syntax is=20 { any number expressions separated by '.' } The result is an array with the values of the expressions. Thus z :=3D {1@2. 3@4. 5@6}. stores into z a new array containing 3 points. It compiles the following co= de: <76> pushConstant: 1 <77> pushConstant: 2 <BB> send: @ <20> pushConstant: 3 <23> pushConstant: 4 <BB> send: @ <24> pushConstant: 5 <25> pushConstant: 6 <BB> send: @ <41> pushLit: Array <20> pushConstant: 3 <E2> send: fromBraceStack: <68> popIntoTemp: 0. Array>>fromBraceStack: nElements allocates a new array, and then pops the= elements off the stack of its sender, storing them into itself. Clearly= this construct is limited by stack depth considerations. If you buy into brace construct, then you can make up dictionaries on the= fly using the -> association message, as in dict :=3D {#green -> #go. #yellow -> #slow. #red -> #stop} as: Dictionary. Also, if you feel the need for a CASE construct, you can get it by= assembling arrays of blocks this way: z :=3D someColor caseOf: {[#green]->[1+1]. ['yellow' asSymbol]->[2+2]. [#red]->[3+3]}. The compiler recognizes this construct and compiles it in-line so that a= large case construct won't blow the stack depth limit. In so doing, it= also avoids the execution overhead of the block evaluations. There are a number of examples in comments that you can find beginning with= Object>>caseOf: and BraceConstructor class>>example. For the most part it= all works, and we use it for scratch programming (you'll find a couple in= WarpBlt examples). It's as good as anything similar I've seen proposed for= Smalltalk, but we haven't pursued it because it involves syntax that is not= standard. David is right to bring this up. We ought to "embrace" the brace construct,= document it, and use it, or strip it out now before it creates any more= confusion. It's begninning to feel like Squeak may well become its own= standard, so I think the real question is, do we like it, more than, is it = compatible. - Dan

Post a reply.

Go back to index.



Date: 97 May 14 9:21:43 am From: Dan Ingalls <DanI@wdi.disney.com> To: Squeak@create.ucsb.edu Subject: Fixes for Pen Computing --============_-1348490133==_============ Content-Type: text/plain; charset="us-ascii" Attached are two methods (one from Blair McGlashan) which are needed for Squeak's UI to function well with touch pens, as on the Cassiopeia. Such pens do not provide any mouse movement input except when the "button is pressed". With these fixes, things seem to run fine, all except that you don't see cursor changes on mouse-over. I'll include these in the next release. - Dan --============_-1348490133==_============ Content-Type: text/plain; name="PenChanges-di.cs"; charset="us-ascii" Content-Disposition: attachment; filename="PenChanges-di.cs" 'From Squeak 1.19d of April 13, 1997 on 12 May 1997 at 1:34:30 pm'! !ScrollController methodsFor: 'scrolling'! scroll "Check to see whether the user wishes to jump, scroll up, or scroll down." | savedCursor | savedCursor _ sensor currentCursor. [self scrollBarContainsCursor] whileTrue: [Processor yield. sensor cursorPoint x <= self downLine ifTrue: [self scrollDown] ifFalse: [sensor cursorPoint x <= self upLine ifTrue: [self scrollAbsolute] ifFalse: [sensor cursorPoint x <= self yellowLine ifTrue: [self scrollUp] ifFalse: [sensor cursorPoint x <= scrollBar right ifTrue: "Might not be, with touch pen" [self changeCursor: Cursor menu. sensor anyButtonPressed ifTrue: [self changeCursor: savedCursor. self anyButtonActivity]]]]]]. savedCursor show! ! !StandardSystemController methodsFor: 'borders'! adjustWindowBorders | side | VBorderCursor showWhile: [ [side _ view displayBox sideNearestTo: sensor cursorPoint. self cursorOnBorder and: [(side = #left) | (side = #right)]] whileTrue: [(sensor redButtonPressed and: [self cursorOnBorder]) ifTrue: [side = #left ifTrue: [view newFrame: [:f | f withLeft: sensor cursorPoint x]]. side = #right ifTrue: [view newFrame: [:f | f withRight: sensor cursorPoint x]]]]]. HBorderCursor showWhile: [ [side _ view displayBox sideNearestTo: sensor cursorPoint. self cursorOnBorder and: [(side = #top) | (side = #bottom)]] whileTrue: [(sensor redButtonPressed and: [self cursorOnBorder]) ifTrue: [side = #top ifTrue: [view newFrame: [:f | f withTop: sensor cursorPoint y]]. side = #bottom ifTrue: [view newFrame: [:f | f withBottom: sensor cursorPoint y]]. ]]]! ! --============_-1348490133==_============--

Post a reply.

Go back to index.



Date: 97 May 14 10:25:27 am From: joel@ObjectPeople.com To: Dan Ingalls <DanI@wdi.disney.com> Cc: Squeak@create.ucsb.edu Subject: Re: Casing the joint > If you buy into brace construct, then you can make up dictionaries on the fly using the -> association message, as in > dict := {#green -> #go. #yellow -> #slow. #red -> #stop} as: Dictionary. > > Also, if you feel the need for a CASE construct, you can get it by assembling arrays of blocks this way: > z := someColor caseOf: > {[#green]->[1+1]. > ['yellow' asSymbol]->[2+2]. > [#red]->[3+3]}. > The compiler recognizes this construct and compiles it in-line so that a large case construct won't blow the stack depth limit. In so doing, it also avoids the execution overhead of the block evalu > tions. > > There are a number of examples in comments that you can find beginning with Object>>caseOf: and BraceConstructor class>>example. For the most part it all works, and we use it for scratch programmin > (you'll find a couple in WarpBlt examples). It's as good as anything similar I've seen proposed for Smalltalk, but we haven't pursued it because it involves syntax that is not standard. > > David is right to bring this up. We ought to "embrace" the brace construct, document it, and use it, or strip it out now before it creates any more confusion. It's begninning to feel like Squeak m > y well become its own standard, so I think the real question is, do we like it, more than, is it compatible. I think this is a great idea, and I like it. This is one area in which I think Smalltalk has fallen short, and they can be very useful. IBM/OTI has started an approach similar to this, I believe of the form ##( Time now seconds ), where ##( expression) makes a compile time constant, evaluating the 'expression'. Joel Joel Lucuik | The Object People Joel@ObjectPeople.com | Your Smalltalk Experts 613.225.8812 (V) 613.225.5943 (F) | http://www.objectpeople.on.ca "Where's the kaboom? The EARTH-SHATTERING kaboom???? -Marvin the Martian"

Post a reply.

Go back to index.



Date: 97 May 14 12:42:08 pm From: Ranjan Bagchi <ranjan.bagchi@pobox.com> To: Dan Ingalls <DanI@wdi.disney.com> Cc: "David N. Smith" <dnsmith@watson.ibm.com>, Squeak@create.ucsb.edu Subject: Re: Casing the joint Dan Ingalls wrote: > David, and all -- > > Squeak has a brace construct that was put in by Larry Tesler, in > the early days of Apple Smalltalk. It is not part of the ST-80 > standard. Consequently, we do not use it in the system, and we have > never encouraged its use. Moverover some of the lateral support in > the Decompiler, etc., no longer works, though neither should it be > hard to fix. > > It's pretty simple. The syntax is > { any number expressions separated by '.' } Thanks for sending this -- I noticed years ago that VisualWorks' square-brace/parenthesis/quote matching was sensitive to braces also, and was puzzled -- since I couldn't find it used anywhere. I also know a dozen places I could use this (or could have, since I don't do Smalltalk professionally anymore) -- I'd used streaming to build up collections of complicated objects, and brace-notation appears to be more pleasing to the reader. I'll have to play with it. Cool.. I appreciate the history. -rj

Post a reply.

Go back to index.



Date: 97 May 14 2:02:24 pm From: Randal Schwartz <merlyn@stonehenge.com> To: Dan Ingalls <DanI@wdi.disney.com> Cc: "David N. Smith" <dnsmith@watson.ibm.com>, Squeak@create.ucsb.edu In-Reply-To: Dan Ingalls's message of Wed, 14 May 1997 09:47:50 -0800 Subject: Re: Casing the joint >>>>> "Dan" == Dan Ingalls <DanI@wdi.disney.com> writes: Dan> David is right to bring this up. We ought to "embrace" the brace Dan> construct, document it, and use it, or strip it out now before it Dan> creates any more confusion. It's begninning to feel like Squeak Dan> may well become its own standard, so I think the real question Dan> is, do we like it, more than, is it compatible. Well, for what it's worth, QKS-smalltalk has had that construct from the beginning as well. It seems much more natural than Array with: with: with... -- Name: Randal L. Schwartz / Stonehenge Consulting Services (503)777-0095 Keywords: Perl training, UNIX[tm] consulting, video production, skiing, flying Email: <merlyn@stonehenge.com> Snail: (Call) PGP-Key: (finger merlyn@ora.com) Web: <A HREF="http://www.stonehenge.com/merlyn/">My Home Page!</A> Quote: "I'm telling you, if I could have five lines in my .sig, I would!" -- me

Post a reply.

Go back to index.



Date: 97 May 14 3:23:46 pm From: Ward Cunningham <ward@c2.com> To: joel@ObjectPeople.com Cc: Dan Ingalls <DanI@wdi.disney.com>, Squeak@create.ucsb.edu Subject: Re: Casing the joint > I think this is a great idea, and I like it. This is one area in > which I think Smalltalk has fallen short, and they can be very > useful. > > IBM/OTI has started an approach similar to this, I believe > of the form ##( Time now seconds ), where ##( expression) > makes a compile time constant, evaluating the 'expression'. I've heard that such features have caused no end of problems in the lisp community. For example, I imagine code like {Form fromUser} display could be handy in development but hard to maintain. -- Ward -- Ward Cunningham v 503-245-5633 mailto:ward@c2.com f 503-246-5587 http://c2.com/

Post a reply.

Go back to index.



Date: 97 May 14 3:46:56 pm From: Ian Piumarta <piumarta@prof.inria.fr> To: ward@c2.com Cc: Squeak@create.ucsb.edu Subject: Re: Casing the joint > I've heard that such features have caused no end of problems in the lisp > community. Quasiquote? It's the best thing since sliced time! I suspect that any problems with it might only be due to incrementality in the programming environment, and a very loose notion of when "compile time" actually is. If not, then I'd be interested to hear more details... Ian ------------------------------- projet SOR ------------------------------- Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87 ----------------------- Systemes a Objets Repartis -----------------------

Post a reply.

Go back to index.



Date: 97 May 14 9:19:23 pm From: Dan Ingalls <DanI@wdi.disney.com> To: Squeak@create.ucsb.edu Subject: New Arithmetic Coercion Mechanism After some six months of not getting around to it, I have finally redone= Squeak's ungainly arithmetic coercion. To quote from the file header... This order-dependent fileIn replaces the coercion mechanism in Squeak with a= much more efficient mechanism described in the new comment for class= Number. The net result is that careless mixed-mode arithmetic such as= 355.0 / 113 is nearly as fast as careful pre-conversion, as in 355.0 / (113= asFloat). The intention is that many explicit conversion messages can now= be eliminated, resulting in simpler code. In many cases the simpler code= will also be faster, since values that are already the correct type will= not even be examined. This will be in the next image, but interested parties are welcome to try it= critique it, and tell me of any bugs you encounter. Caution is advised= since I did the work in a later version thatn 1.19d, but I did file it in= to 1.19 and it seemed to be OK. Enjoy - Dan P.S. As another incentive to clean out gratuitous conversions, a= Float-tolerant BitBlt is on the way...

Post a reply.

Go back to index.



Date: 97 May 14 9:21:11 pm From: Dan Ingalls <DanI@wdi.disney.com> To: Squeak@create.ucsb.edu Subject: ...and now the file (blush)... --============_-1348446936==_============ Content-Type: text/plain; charset="us-ascii" --============_-1348446936==_============ Content-Type: text/plain; name="NewCoercion-di.cs"; charset="us-ascii" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="NewCoercion-di.cs" 'From Squeak 1.19d of April 13, 1997 on 14 May 1997 at 1:48:35 pm'! "Change Set: NewCoercion Date: 14 May 1997 Author: Dan Ingalls This order-dependent fileIn replaces the coercion mechanism in Squeak with a= much more efficient mechanism described in the new comment for class= Number. The net result is that careless mixed-mode arithmetic such as= 355.0 / 113 is nearly as fast as careful pre-conversion, as in 355.0 / (113= asFloat). The intention is that many explicit conversion messages can now= be eliminated, resulting in simpler code. In many cases the simpler code= will actually be faster, since values that are already the correct type= will not even be examined."! Number comment: 'I am an abstract representation of a number. My subclasses Float, Fraction,= and Integer, and their subclasses, provide concrete representations of a= numeric quantity. All my subclasses participate in a simple type coercion mechanism that= supports mixed-mode arithmetic and comparisons. It works as follows: If self<typeA> op: arg<typeB> fails because of incompatible types, then it is retried in the following gui= se: (arg adaptTypeA: self) op: arg adaptToTypeA. This gives the arg of typeB an opportunity to resolve the incompatibility,= knowing exactly what two types are involved. If self is more general, then= arg will be converted, and viceVersa. This mechanism is extensible to any= new number classes that one might wish to add to Squeak. The only= requirement is that every subclass of Number must support a pair of= conversion methods specific to each of the other subclasses of Number.'! !Number methodsFor: 'testing'! isFloat ^ false! isFraction ^ false! ! !Number methodsFor: 'converting'! adaptFloat: aFloat "If I am involved in arithmetic with a Float, I must know whether to= convert it." self subclassResponsibility! adaptFraction: aFraction "If I am involved in arithmetic with a Fraction, I must know whether to= convert it." self subclassResponsibility! adaptInteger: anInteger "If I am involved in arithmetic with an Integer, I must know whether to= convert it." self subclassResponsibility! adaptToFloat "If I am involved in arithmetic with a Float, I must know whether to be con= verted." self subclassResponsibility! adaptToFraction "If I am involved in arithmetic with a Fraction, I must know whether to be = converted." self subclassResponsibility! adaptToInteger "If I am involved in arithmetic with an Integer, I must know whether to be = converted." self subclassResponsibility! ! !Float methodsFor: 'truncation and round off'! fractionPart "Primitive. Answer a Float whose value is the difference between the=20 receiver and the receiver's asInteger value. Optional. See Object=20 documentation whatIsAPrimitive." <primitive: 52> ^self - self truncated asFloat! ! !Float methodsFor: 'converting'! adaptFraction: aFraction "If I am involved in arithmetic with a Fraction, convert the Fraction." ^ aFraction asFloat! adaptInteger: anInteger "If I am involved in arithmetic with an Integer, convert the Integer." ^ anInteger asFloat! adaptToFraction "If I am involved in arithmetic with a Fraction, do not convert me." ^ self! adaptToInteger "If I am involved in arithmetic with an Integer, do not convert me." ^ self! isFloat ^ true! ! !Fraction methodsFor: 'converting'! adaptFloat: aFloat "If I am involved in arithmetic with a Float, do not convert the Float." ^ aFloat! adaptInteger: anInteger "If I am involved in arithmetic with an Integer, convert the Integer." ^ anInteger asFloat! adaptToFloat "If I am involved in arithmetic with a Float, convert me to a Float." ^ self asFloat! adaptToInteger "If I am involved in arithmetic with an Integer, do not convert me." ^ self! isFraction ^ true! ! !Integer methodsFor: 'converting'! adaptFloat: aFloat "If I am involved in arithmetic with a Float, do not convert the Float." ^ aFloat! adaptFraction: aFraction "If I am involved in arithmetic with a Fraction, do not convert the Fractio= n." ^ aFraction! adaptToFloat "If I am involved in arithmetic with a Float, convert me to a Float." ^ self asFloat! adaptToFraction "If I am involved in arithmetic with a Fraction, convert me to a Fraction." ^ self asFraction! ! !SmallInteger methodsFor: 'converting'! adaptToFloat "Fast conversion equivalent to self asFloat." <primitive: 40> self primitiveFailed! ! Integer removeSelector: #coerceToPoint! Number comment: 'I am an abstract representation of a number. My subclasses Float, Fraction,= and Integer, and their subclasses, provide concrete representations of a= numeric quantity. All my subclasses participate in a simple type coercion mechanism that= supports mixed-mode arithmetic and comparisons. It works as follows: If self<typeA> op: arg<typeB> fails because of incompatible types, then it is retried in the following gui= se: (arg adaptTypeA: self) op: arg adaptToTypeA. This gives the arg of typeB an opportunity to resolve the incompatibility,= knowing exactly what two types are involved. If self is more general, then= arg will be converted, and viceVersa. This mechanism is extensible to any= new number classes that one might wish to add to Squeak. The only= requirement is that every subclass of Number must support a pair of= conversion methods specific to each of the other subclasses of Number.'! !Float methodsFor: 'arithmetic'! * aNumber=20 "Primitive. Answer the result of multiplying the receiver by aNumber. Fail if the argument is not a Float. Essential. See Object documentation whatIsAPrimitive." <primitive: 49> ^ (aNumber adaptFloat: self) * aNumber adaptToFloat! + aNumber=20 "Primitive. Answer the sum of the receiver and aNumber. Essential. Fail if the argument is not a Float. See Object documentation whatIsAPrimitive." <primitive: 41> ^ (aNumber adaptFloat: self) + aNumber adaptToFloat! - aNumber=20 "Primitive. Answer the difference between the receiver and aNumber. Fail if the argument is not a Float. Essential. See Object documentation whatIsAPrimitive." <primitive: 42> ^ (aNumber adaptFloat: self) - aNumber adaptToFloat! / aNumber=20 "Primitive. Answer the result of dividing receiver by aNumber. Fail if the argument is not a Float. Essential. See Object documentation whatIsAPrimitive." <primitive: 50> aNumber =3D 0 ifTrue: [self error: 'attempt to divide by zero'] ifFalse: [^ (aNumber adaptFloat: self) / aNumber adaptToFloat]! ! !Float methodsFor: 'comparing'! < aNumber=20 "Primitive. Compare the receiver with the argument and return true if the receiver is less than the argument. Otherwise return false. Fail if the argument is not a Float. Essential. See Object documentation whatIsAPrimitive." <primitive: 43> ^ (aNumber adaptFloat: self) < aNumber adaptToFloat! <=3D aNumber=20 "Primitive. Compare the receiver with the argument and return true if the receiver is less than or equal to the argument. Otherwise return false. Fail if the argument is not a Float. Optional. See Object documentation whatIsAPrimitive." <primitive: 45> ^ (aNumber adaptFloat: self) <=3D aNumber adaptToFloat! =3D aNumber=20 "Primitive. Compare the receiver with the argument and return true if the receiver is equal to the argument. Otherwise return false. Fail if the argument is not a Float. Essential. See Object documentation whatIsAPrimitive." <primitive: 47> aNumber isNumber ifFalse: [^ false]. ^ (aNumber adaptFloat: self) =3D aNumber adaptToFloat! > aNumber=20 "Primitive. Compare the receiver with the argument and return true if the receiver is greater than the argument. Otherwise return false. Fail if the argument is not a Float. Essential. See Object documentation whatIsAPrimitive." <primitive: 44> ^ (aNumber adaptFloat: self) > aNumber adaptToFloat! >=3D aNumber=20 "Primitive. Compare the receiver with the argument and return true if the receiver is greater than or equal to the argument. Otherwise return false. Fail if the argument is not a Float. Optional. See Object= documentation=20 whatIsAPrimitive. " <primitive: 46> ^ (aNumber adaptFloat: self) >=3D aNumber adaptToFloat! ! !Fraction methodsFor: 'arithmetic'! * aNumber "Answer the result of multiplying the receiver by aNumber." aNumber isFraction ifTrue: [^ (Fraction numerator: numerator * aNumber numerator denominator: denominator * aNumber denominator) reduced] ifFalse: [^ (aNumber adaptFraction: self) * aNumber adaptToFraction]! + aNumber "Answer the sum of the receiver and aNumber." | commonDenominator newNumerator | aNumber isFraction ifTrue:=20 [denominator =3D aNumber denominator ifTrue: [ ^ (Fraction=20 numerator: numerator + aNumber numerator denominator: denominator) reduced]. commonDenominator _ denominator lcm: aNumber denominator. newNumerator _ (numerator * (commonDenominator / denominator)) + (aNumber numerator * (commonDenominator / aNumber denominator)). ^ (Fraction=20 numerator: newNumerator=20 denominator: commonDenominator) reduced] ifFalse: [^ (aNumber adaptFraction: self) + aNumber adaptToFraction]! - aNumber "Answer the difference between the receiver and aNumber." aNumber isFraction ifTrue: [^ self + aNumber negated] ifFalse: [^ (aNumber adaptFraction: self) - aNumber adaptToFraction]! / aNumber "Answer the result of dividing the receiver by aNumber." aNumber isFraction ifTrue: [^self * aNumber reciprocal] ifFalse: [^ (aNumber adaptFraction: self) / aNumber adaptToFraction]! ! !Fraction methodsFor: 'comparing'! < aNumber aNumber isFraction ifTrue: [aNumber numerator =3D 0 ifTrue: [^numerator < 0] ifFalse: [^self - aNumber < 0]] ifFalse: [^ (aNumber adaptFraction: self) < aNumber adaptToFraction]! =3D aNumber aNumber isNumber ifFalse: [^ false]. aNumber isFraction ifTrue: [aNumber numerator =3D 0 ifTrue: [^numerator =3D 0] ifFalse: [^aNumber numerator =3D numerator=20 and: [aNumber denominator =3D denominator]]] ifFalse: [^ (aNumber adaptFraction: self) =3D aNumber adaptToFraction]! ! !Integer methodsFor: 'arithmetic'! * aNumber "Refer to the comment in Number * "=20 aNumber isInteger ifTrue: [^ self digitMultiply: aNumber=20 neg: self negative ~~ aNumber negative] ifFalse: [^ (aNumber adaptInteger: self) * aNumber adaptToInteger]! + aNumber "Refer to the comment in Number + " aNumber isInteger ifTrue: [self negative =3D=3D aNumber negative ifTrue: [^(self digitAdd: aNumber) normalize] ifFalse: [^self digitSubtract: aNumber]] ifFalse: [^ (aNumber adaptInteger: self) + aNumber adaptToInteger]! - aNumber "Refer to the comment in Number - " aNumber isInteger ifTrue: [self negative =3D=3D aNumber negative ifTrue: [^ self digitSubtract: aNumber] ifFalse: [^ (self digitAdd: aNumber) normalize]] ifFalse: [^ (aNumber adaptInteger: self) - aNumber adaptToInteger]! / aNumber "Refer to the comment in Number / " | quoRem | aNumber isInteger ifTrue: [quoRem _ self digitDiv: aNumber=20 neg: self negative ~~ aNumber negative. (quoRem at: 2) =3D 0 ifTrue: [^(quoRem at: 1) normalize] ifFalse: [^(Fraction numerator: self denominator: aNumber) reduced]] ifFalse: [^ (aNumber adaptInteger: self) / aNumber adaptToInteger]! quo: aNumber=20 "Refer to the comment in Number quo: " | ng quo | aNumber isInteger ifTrue:=20 [ng _ self negative =3D=3D aNumber negative =3D=3D false. quo _ (self digitDiv: aNumber neg: ng) at: 1. ^ quo normalize] ifFalse: [^ (aNumber adaptInteger: self) quo: aNumber adaptToInteger]! ! !Integer methodsFor: 'comparing'! < aNumber aNumber isInteger ifTrue: [self negative =3D=3D aNumber negative ifTrue: [self negative ifTrue: [^(self digitCompare: aNumber) > 0] ifFalse: [^(self digitCompare: aNumber) < 0]] ifFalse: [^self negative]] ifFalse: [^ (aNumber adaptInteger: self) < aNumber adaptToInteger]! =3D aNumber aNumber isNumber ifFalse: [^ false]. aNumber isInteger ifTrue: [aNumber negative =3D=3D self negative ifTrue: [^ (self digitCompare: aNumber) =3D 0] ifFalse: [^ false]] ifFalse: [^ (aNumber adaptInteger: self) =3D aNumber adaptToInteger]! > aNumber aNumber isInteger ifTrue: [self negative =3D=3D aNumber negative ifTrue: [self negative ifTrue: [^(self digitCompare: aNumber) < 0] ifFalse: [^(self digitCompare: aNumber) > 0]] ifFalse: [^ aNumber negative]] ifFalse: [^ (aNumber adaptInteger: self) > aNumber adaptToInteger]! ! Number removeSelector: #retry:coercing:! Number removeSelector: #generality! Number removeSelector: #coerce:! =46loat removeSelector: #coerce:! =46loat removeSelector: #generality! =46raction removeSelector: #coerce:! =46raction removeSelector: #generality! Integer removeSelector: #coerce:! Integer removeSelector: #generality! Number class removeSelector: #newFrom:! SmallInteger removeSelector: #generality! SmallInteger removeSelector: #coerce:! Smalltalk removeEmptyMessageCategories! --============_-1348446936==_============--

Post a reply.

Go back to index.



Date: 97 May 14 11:09:38 pm From: lstrand@concentric.net To: "David N. Smith" <dnsmith@watson.ibm.com>, "Michael Ackerman" <mack@sfo.com> Cc: <squeak@create.ucsb.edu> Subject: Re: Which Smalltalk is Squeak? David Smith wrote: >Why? Because, unlike C++ where MI seems to be important for reasons I don't >quite get, it is not important in Smalltalk. Look at the Commander example in the Blue/Purple book (in the "Pens" chapter) -- particularly the section "Additional Protocol for Commander Pen". (A Commander simply accepts messages from Pen's protocol and broadcasts them to a bunch of pens, each pen drawing in parallel.) Even though Commander is a subclass of Array and not of Pen, with the additional Pen protocol it may be used anywhere a Pen may be used. Because messages are bound at runtime in Smalltalk, anything that conforms to Pen's protocol may effectively be considered a Pen. So in Smalltalk MI isn't absolutely necessary. In C++, Commander would have to be a subclass of Pen in order to be used as a Pen; the compiler enforces this. One has to use MI to get the desired effect (a class which can be used both as an Array and a Pen). In this case, I would choose Pen as a superclass, and add an instance variable to refer to an Array of Pens, just to avoid MI. But other cases (e.g., ReadWriteStream) beg the use of MI. It is facinating to me how many features of C++ are forced by its rigid compile-time checks. If you were to design a "static Smalltalk", right away you would be forced to add templates and MI... very quickly you would have a language which is ten times as complicated but no more powerful. --Leif

Post a reply.

Go back to index.



Date: 97 May 14 11:59:45 pm From: Georg Gollmann <gollmann@edvz.tuwien.ac.at> To: Squeak@create.ucsb.edu In-Reply-To: <v03007800af9faa1feff6@[206.16.10.79]> Subject: Re: Casing the joint At 9:47 Uhr -0800 14.5.1997, Dan Ingalls wrote: > >It's pretty simple. The syntax is > { any number expressions separated by '.' } GemStone Smalltalk has this with the syntax #[ any number expressions separated by ',' ] >David is right to bring this up. We ought to "embrace" the brace construct, >document it, and use it, or strip it out now before it creates any more >confusion. It's begninning to feel like Squeak may well become its own >standard, so I think the real question is, do we like it, more than, is it >compatible. I am very much in favour of having an array constructor, the current syntax is fine with me. Georg ---- Dipl.Ing. Georg Gollmann TU-Wien, EDV-Zentrum phon:(+43-1) 58801 - 5848 fax: (+43-1) 587 42 11 mail:gollmann@edvz.tuwien.ac.at http://ftp.tuwien.ac.at/~go/Gollmann.html

Post a reply.

Go back to index.



Date: 97 May 15 12:02:31 am From: Georg Gollmann <gollmann@edvz.tuwien.ac.at> To: Dan Ingalls <DanI@wdi.disney.com>, Squeak@create.ucsb.edu In-Reply-To: <v03007804afa05368b776@[206.16.10.79]> Subject: Re: New Arithmetic Coercion Mechanism (Buglet) At 21:51 Uhr -0800 14.5.1997, Dan Ingalls wrote: >After some six months of not getting around to it, I have finally redone >Squeak's ungainly arithmetic coercion. To quote from the file header... > Fraction>adaptInteger: converts its argument to Float, it should convert to Fraction. Georg ---- Dipl.Ing. Georg Gollmann TU-Wien, EDV-Zentrum phon:(+43-1) 58801 - 5848 fax: (+43-1) 587 42 11 mail:gollmann@edvz.tuwien.ac.at http://ftp.tuwien.ac.at/~go/Gollmann.html

Post a reply.

Go back to index.



Date: 97 May 15 12:23:08 am From: mack@sfo.com (Michael Ackerman) To: squeak@create.ucsb.edu Subject: Blue Book What is the Blue/Purple book? Michael Ackerman

Post a reply.

Go back to index.



Date: 97 May 15 5:30:16 am From: Anthony Lander <anthony@objectPeople.com> To: squeak@create.ucsb.edu Subject: Correcting long-standing problems Once everyone (i.e. Dan) is busy correcting long-standing problems, such as hashing and coersion, could I convince you to tackle one more? #mustBeBoolean Man, this bothers me. I've reimplemented #doesNotUnderstand: more times than you can shake a stick at. You simply cannot build a good proxy object in Smalltalk because of this message. Can the VM be changed such that messages like #and: fail by really sending the #and: message (not inlined) instead of sending #mustBeBoolean? -Anthony Lander -----Proof of the Comming Java Backlash-------------------------------- All device drivers will be Java in a few years, at least the ones that might have been in C. This is because Java can be faster than C and because it is portable. -found in comp.lang.java

Post a reply.

Go back to index.



Date: 97 May 15 5:42:25 am From: joel@ObjectPeople.com To: Ward Cunningham <ward@c2.com> Cc: Dan Ingalls <DanI@wdi.disney.com>, Squeak@create.ucsb.edu Subject: Re: Casing the joint > Date: Wed, 14 May 1997 15:42:13 -0700 > From: Ward Cunningham <ward@c2.com> > Organization: Cunningham & Cunningham, Inc. > To: joel@ObjectPeople.com > Cc: Dan Ingalls <DanI@wdi.disney.com>, Squeak@create.ucsb.edu > Subject: Re: Casing the joint > > I think this is a great idea, and I like it. This is one area in > > which I think Smalltalk has fallen short, and they can be very > > useful. > > > > IBM/OTI has started an approach similar to this, I believe > > of the form ##( Time now seconds ), where ##( expression) > > makes a compile time constant, evaluating the 'expression'. > > I've heard that such features have caused no end of problems in the lisp > community. For example, I imagine code like > > {Form fromUser} display > > could be handy in development but hard to maintain. -- Ward > I can see where compile-time constants could be hard to maintain. It would be easy to detect these, as a senders-like utility. For an array constructor, I think the advantages of useability/readability outweigh the problems. Perhaps 2 syntaxes would be good: ##( expression ) - for compile-time constants and, { element1 element2 ... } - for array construction Joel Joel Lucuik | The Object People Joel@ObjectPeople.com | Your Smalltalk Experts 613.225.8812 (V) 613.225.5943 (F) | http://www.objectpeople.on.ca "Where's the kaboom? The EARTH-SHATTERING kaboom???? -Marvin the Martian"

Post a reply.

Go back to index.



Date: 97 May 15 6:16:11 am From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: RE: hashing What is better? A faster hash function or a more disperse hash function? (an efficient hash function or an effective one?) When you test for the equality of two sets you iterate over each of the = elements. So, a slow hash function does not essentially change the = complexity of the test. However, as a general rule, hashing is supposed = to be fast, so it should be fast. //Leandro

Post a reply.

Go back to index.



Date: 97 May 15 6:25:10 am From: Ward Cunningham <ward@c2.com> To: Ian Piumarta <piumarta@prof.inria.fr> Cc: Squeak@create.ucsb.edu Subject: Re: Casing the joint Ian Piumarta wrote: > > > I've heard that such features have caused no end of problems in the lisp > > community. > > Quasiquote? It's the best thing since sliced time! Ian -- Your right. My statement left no room for argument. I am just repeating a warning that was given to me by a lisp implementor around 1985. I should have challenged him then. "What kind of trouble?" I should have asked. But I didn't. I thought I knew. I had added the evaluated literal feature to Tektronix Smalltalk. It's really a sweet little mod to the scanner that everyone should try. My syntax was: #[ an expression ] which seemed to express literal (#) and unusual evaluation ([]) nicely. I was concerned about the variety of evaluation contexts, but didn't figure it was any worse than the special handling of class initialize methods. This extension was mentioned in a casual meeting with our visitor. (I'm not being coy here. I'm actually having trouble remembering who. It might have been Steele. It was at least someone who had seen quite a few lisps and knew their weaknesses. A scheme guy for sure.) The warning was immediate. I let the subject drop. I kept the feature in my own image for quite a while, but I don't remember using it, or missing it. -- Ward -- Ward Cunningham v 503-245-5633 mailto:ward@c2.com f 503-246-5587 http://c2.com/

Post a reply.

Go back to index.



Date: 97 May 15 6:47:36 am From: Thierry Goubier <Thierry.Goubier@enst-bretagne.fr> To: Anthony Lander <anthony@objectPeople.com> Cc: squeak@create.ucsb.edu In-Reply-To: <3.0.32.19970515085754.00912140@mail.objectPeople.com> Subject: Re: Correcting long-standing problems On Thu, 15 May 1997, Anthony Lander wrote: > Once everyone (i.e. Dan) is busy correcting long-standing problems, such as > hashing and coersion, could I convince you to tackle one more? > > #mustBeBoolean > Man, this bothers me. I've reimplemented #doesNotUnderstand: more times > than you can shake a stick at. You simply cannot build a good proxy object > in Smalltalk because of this message. Can the VM be changed such that > messages like #and: fail by really sending the #and: message (not inlined) > instead of sending #mustBeBoolean? I have maybe a question on this. The error will only happen if you have a proxy standing as the result of a test, if I'm right. For example, it will happen with : aProxy and: [<another test>], and probably in similar cases. The question is what is the meaning of this expression ? I'd say that either this is a programming error (would happen with something else than a proxy) or an environment where your proxy has replaced true or false. I've never dared doing the latter... For my persistent store, I heavily rely on proxys, and have never managed to fall on this (I take great care not to proxify objects like true or false, however). Can you give an example of proxy uses when you managed to get this error ? Thierry. ___________________Thierry.Goubier@enst-bretagne.fr__________________ But to look for heaven is to live here in hell [Sting] http://www-info.enst-bretagne.fr/~goubier/

Post a reply.

Go back to index.



Date: 97 May 15 6:54:10 am From: Ian Piumarta <piumarta@prof.inria.fr> To: caniglia@mate.dm.uba.ar, squeak@create.ucsb.edu Subject: RE: hashing > What is better? A faster hash function or a more disperse hash function? That depends on the density of collections. If all my (unordered) collections have only one element in them, then the fastest hash function possible is what I want. If all my collections are almost full, then the most dispersed hash function is what I want. There's no "correct" answer to the question: it will always be a compromise between generating a fast initial probe index, and the number of reprobes needed to find the target element (or nil ;-). Maybe the question should be: "Does anyone know what the optimal compromise is for the average collection in Squeak, taking into account whatever happens to be the "grow threshold" for collections this week?" Ian PS: As usual you can trade space for time: setting the threshold low, so that collections grow when they're e.g. 10% full, lets you get away with a much faster (less disperse) hash function.

Post a reply.

Go back to index.



Date: 97 May 15 7:25:12 am From: Anthony Lander <anthony@objectPeople.com> To: Thierry Goubier <Thierry.Goubier@enst-bretagne.fr> Cc: squeak@create.ucsb.edu Subject: Re: Correcting long-standing problems >[re: #mustBeBoolean being sent to a proxy object] > >I have maybe a question on this. The error will only happen if you have a >proxy standing as the result of a test, if I'm right. For example, it will >happen with : aProxy and: [<another test>], and probably in similar cases. Sure. But that's not necessarily a bad thing. From the rest of your message, I gather tha you don't think you should ever proxy sole-instance objects (true, false, nil). You are assuming that people only ever use proxies as message forwarders. I have a counter-example: The specific case I'm thinking of uses a proxy object to catch the messages it is sent so that it can build a build parse tree from them. The parse tree is used to cross-compile expressions into another language. This opens another can of worms with respect to #== and #identityHash, and with respect to the transparency of compiler optimizations. I'll save all that for another time. I have to get my thoughts on the subject in order before I post them. >For my persistent store, I heavily rely on proxys, and have never managed to fall >on this (I take great care not to proxify objects like true or false, however). Of course. With repect to persistence, you shouldn't proxy objects that aren't part of the application domain....well, except for maybe collections of domain objects. -Anthony ------------------------------------------------------------ Remember the five-step response of all experts when first confronted with a new development in their field: IGNORE, RIDICULE, ATTACK, COPY, STEAL. -Arthur Jones

Post a reply.

Go back to index.



Date: 97 May 15 8:12:56 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: mack@sfo.com (Michael Ackerman) Cc: squeak@create.ucsb.edu In-Reply-To: <v01510100afa07ee17752@[207.33.216.16]> Subject: Re: Blue Book (and Orange, and a Trivia Question) At 4:51 -0400 5/15/97, Michael Ackerman wrote: >What is the Blue/Purple book? > >Michael Ackerman It's two books, one with a big blue rectangle in the center of its cover, and one with a similar but purple rectangle. The Blue Book is: Smalltalk-80: the Language and Its Implementation, Goldberg & Robson, Addison-Wesley, ca 1983. It is out of print but Powells in Portland sometimes has it used. (http://www.powells.portland.or.us/) You might also try Amazon.com who now carries used books, and does used book searches. The Purple Book is: Smalltalk-80: The Language, Goldberg & Robson, Addison-Wesley, ca 1987. It is still in print so far as I know. It is the blue book less a section in which Smalltalk is implemented in Smalltalk, clearly a dumb idea! :-) If you can find one, get the Blue Book. I have two and would not part with either an any price anyone would pay, but you might find someone who will sell. There are two others: the Orange Book and the Green Book. The Orange Book is Smalltalk-80: The Interactive Programming Environment; it tells how to use Smalltalk-80. The Green Book is Smallalk-80: Bits of History and Words of Advice, a set of papers about implementing Smalltalk. Both are old, though the Orange Book probably describes how to use early versions of Squeak fairly well. (I haven't relly looked at it in years.) Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 15 8:19:22 am From: Hans-Martin Mosner <hmm@heeg.de> To: Squeak Mailing List <squeak@create.ucsb.edu> Subject: Debugger Bug Hello Squeakers, there's a little bug in the code related to single stepping in the debugger. Symptom: The bug can manifest itself in various forms. In my case, I got a #primitiveFail when I was trying to access an instance variable through a simple getter method, but you could conceivably get much more nasty effects. Cause: The method ContextPart>>doPrimitive:receiver:args stuffs the primitive number into a pre-existing method and then calls that method. After modifying the method, it should flush the method lookup cache using "Class flushCache", but this statement is commented out. Fix: To fix, just remove the comment quote around this statement. Hans-Martin

Post a reply.

Go back to index.



Date: 97 May 15 8:30:55 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: joel@ObjectPeople.com Cc: Ward Cunningham <ward@c2.com>, Dan Ingalls <DanI@wdi.disney.com>, Squeak@create.ucsb.edu In-Reply-To: <13073955100300@objectpeople.com> Subject: Re: Casing the joint At 5:11 -0400 5/15/97, joel@ObjectPeople.com wrote: >> Date: Wed, 14 May 1997 15:42:13 -0700 >> From: Ward Cunningham <ward@c2.com> >> Organization: Cunningham & Cunningham, Inc. >> To: joel@ObjectPeople.com >> Cc: Dan Ingalls <DanI@wdi.disney.com>, Squeak@create.ucsb.edu >> Subject: Re: Casing the joint > >> > I think this is a great idea, and I like it. This is one area in >> > which I think Smalltalk has fallen short, and they can be very >> > useful. >> > >> > IBM/OTI has started an approach similar to this, I believe >> > of the form ##( Time now seconds ), where ##( expression) >> > makes a compile time constant, evaluating the 'expression'. I hear that this construct, never documented except in the 3rd printing of my IBM Smalltalk book, is no longer recommended due to some kind of problem when developing on platform A an application intended for Platform B. (Like building an image on Windows intended to run on MVS). The expression runs on the development plaform and might answer, say, an IEEE float, but the image runs on MVS which has a different float format. (IBM Smalltalk normally requires loading an application into a development environment for a target machine and then generation of a new runtime for that machine; images are not portable; Envy applications are portable.) I still think it is a nice construct and would suggest that Squeak use it or some functional equivalent. Note that one can build most anything, including dictionaries, and no aditional odd syntax is needed. For some examples. see: http://www.dnsmith.com/dnsmith/DNSSL2/htmlForAW/ver3new.html and scroll down a screen or so. >> I've heard that such features have caused no end of problems in the lisp >> community. For example, I imagine code like >> >> {Form fromUser} display >> >> could be handy in development but hard to maintain. -- Ward Some people can screw up anything! Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 15 9:13:33 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: Ian Piumarta <piumarta@prof.inria.fr> Cc: squeak@create.ucsb.edu In-Reply-To: <199705151419.QAA26273@prof.inria.fr> Subject: RE: hashing At 10:19 -0400 5/15/97, Ian Piumarta wrote: >> What is better? A faster hash function or a more disperse hash function? > >That depends on the density of collections. If all my (unordered) >collections have only one element in them, then the fastest hash function >possible is what I want. If all my collections are almost full, then the >most dispersed hash function is what I want. There's no "correct" answer >to the question: it will always be a compromise between generating a fast >initial probe index, and the number of reprobes needed to find the target >element (or nil ;-). > >Maybe the question should be: "Does anyone know what the optimal >compromise is for the average collection in Squeak, taking into account >whatever happens to be the "grow threshold" for collections this week?" > >Ian > >PS: As usual you can trade space for time: setting the threshold low, so >that collections grow when they're e.g. 10% full, lets you get away with >a much faster (less disperse) hash function. If a hash answers the same value a lot then lots of collisions will occur. Look in all the #scanFor: methods in collections. They all do sequential searches from the 'hash point' to the end, and then wrap. I've only examined Float (and I have a new version of Float>>#hash with a better hash value and better measurements comming soon) but the original hash distribution was awful. For example, here is one of my tests: Float testHashSize: 100000 from: -20.0 to: 20.0 by: 0.0001 #hash Samples 400001 Zeros 97491 Min 1 Avg 4 Max 431 Dev 35.17 #hasnDNS Samples 400001 Zeros 34471 Min 1 Avg 4 Max 14 Dev 3.26 #hashDNS2 Samples 400001 Zeros 2079 Min 1 Avg 4 Max 13 Dev 1.98 The expression tests three hash algorithms using a bucket test with 100,000 buckets, the original, mine of a few days ago, and my new one. Zeros are the number of empty buckets after generating 400,000 hash values. Min/Avg/Max apply to non-zero buckets. With 400,000 different float values and 100,000 buckets into which to put the hashes: * the original managed to answer (100,000-97,491) = 2509 different values * my improved version, distributed by Dan recently, answered (100,000-34471) = 65529 different answers (and it CAN answer only 65536 different answers since it answers a 16 bit number; I was surprised at how well it did!) * and the unreleased hash (30 bit answers) answered (100,000-2079) = 97921 different answers. In the worst case, the newer algorithms at most answered the same value 14 times (though there is no way to tell now many times it did that). The original managed to answer at least one hash value 431 times. A bad hash slows everything down. Good hash values are hard to obtain (and Float is probably an easy case). I think it is worth paying a bit more for a decent hash value up front to prevent a lot of sequential searches trying to find an empty slot. (My newest version is slower than the original by a factor of 3 or less.) The real problem here is the equal test that is required by Set/Bag & friends. In other posts I've suggested that equality testing (#=) should not be used in hashed collections since it leads to bad hashes and bizare results. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 15 10:04:15 am From: gregory@eng.adaptec.com (Greg Gritton x2386) To: Thierry.Goubier@enst-bretagne.fr, anthony@objectPeople.com Cc: squeak@create.ucsb.edu Subject: Re: Correcting long-standing problems Another use of a proxy for such basic objects such as true or false is a "future". A future is a placeholder for a time-consuming operation that is started in another thread (perferably on another processor) and is ongoing. This is an easy to use construct for parallelizing programs. For example: doTwoOperationsInParallel | a b | a := self anotherThreadsOperation. b := self someOtherLongOperation. a ifTrue: [ ^0 ] ifFalse: [ ^b ] Suppose anotherThreadsOperation returned a proxy immediately, and replaced that proxy with the actual result when the operation was complete. A parallel system would be able to execute anotherThreadsOperation and someOtherLongOperation at the same time. The programmer would't have to worry about syncronizing them. The two threads could occur in parallel until a message was sent to the result of one of the threads. In this example, the ifTrue:ifFalse: message is sent to "a". If anotherThreadsOperation wasn't complete, this statement would send the message ifTrue:ifFalse: to the proxy, which would then stall until the actual value was available. This example might not be directly applicable to Squeak now (which I don't believe supports multiple CPUs), but illustrates the general principle of replacing optimized message sends with the actual message if the receiver isn't a boolen, rather than simply responding with #mustBeBoolean. It would seem the logically correct thing to do. On the other hand, if doing this impacted the performance for the vast majority of ifTrue:ifFalse: sends where the variable is a boolean, it might be best to leave it the way it is. It is a tradeoff. However, if there is no performance penalty to re-sending the correct message rather than #mustBeBoolean, it would be useful for some things. Greg Gritton When

Post a reply.

Go back to index.



Date: 97 May 15 10:16:05 pm From: Travis Griggs <tkc@bmi.net> To: Thierry Goubier <Thierry.Goubier@enst-bretagne.fr> Cc: Anthony Lander <anthony@objectPeople.com>, squeak@create.ucsb.edu Subject: Re: Correcting long-standing problems Thierry Goubier wrote: > > On Thu, 15 May 1997, Anthony Lander wrote: > > > Once everyone (i.e. Dan) is busy correcting long-standing problems, such as > > hashing and coersion, could I convince you to tackle one more? > > > > #mustBeBoolean > > Man, this bothers me. I've reimplemented #doesNotUnderstand: more times > > than you can shake a stick at. You simply cannot build a good proxy object > > in Smalltalk because of this message. Can the VM be changed such that > > messages like #and: fail by really sending the #and: message (not inlined) > > instead of sending #mustBeBoolean? > > I have maybe a question on this. The error will only happen if you have a > proxy standing as the result of a test, if I'm right. For example, it will > happen with : aProxy and: [<another test>], and probably in similar cases. > > The question is what is the meaning of this expression ? I'd say that > either this is a programming error (would happen with something else > than a proxy) or an environment where your proxy has replaced true or > false. I've never dared doing the latter... This is true. Most proxy schemes make special exceptions for some (if not all) immutable object types (nil, true, false, SmallInt, character, String, ByteArray) by creating local copies. Some even go further and add quasi-immutable types as well (other number types, etc). -- Travis or Kerrin Griggs Key Technology (509) 529-2161 tkc@bmi.net (509) 527-8743

Post a reply.

Go back to index.



Date: 97 May 17 1:36:31 am From: Hans-Martin Mosner <hm.mosner@cww.de> To: Squeak Mailing List <squeak@create.ucsb.edu> Subject: Color dithering (performance improvement) Dies ist eine mehrteilige Nachricht im MIME-Format. --------------5899337C242C Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Here is a new version of the color dithering code I sent out earlier. The determination of te dither pixel values should be a bit faster, and the method is slightly less convoluted. Hans-Martin --------------5899337C242C Content-Type: text/plain; charset=us-ascii; x-mac-type="54455854"; x-mac-creator="522A6368" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ColorDithering.cs" 'From Squeak 1.19d of April 13, 1997 on 17 May 1997 at 10:59:46 am'! "Change Set: ColorDithering Date: 17 May 1997 Author: Hans-Martin Mosner <hmm@heeg.de> Enables dithering for 8-bit color, resulting in more color shades."! !Color methodsFor: 'conversions'! bitPatternForDepth: depth "The raw call on BitBlt needs a Bitmap to represent this color. Return the color at the destination Form depth as a Bitmap. Patterns return longer Bitmaps. 6/14/96 tk For the bits that are in a single pixel, use pixelValueAtDepth:. For a 32-bit integer of (32/depth) pixels, use pixelWordAtDepth:" | brightness | depth == cachedDepth ifTrue: [^ cachedBitPattern]. cachedDepth _ depth. depth > 1 ifTrue: [^ cachedBitPattern _ self computeBitPatternForDepth: depth]. "Spatial halftones for depth 1" brightness _ self luminance. brightness < 0.2 ifTrue: [ ^ cachedBitPattern _ Bitmap with: 16rFFFFFFFF]. "black" brightness < 0.4 ifTrue: [ ^ cachedBitPattern _ Bitmap with: 16rBBBBBBBB with: 16rEEEEEEEE]. "dark gray" brightness < 0.6 ifTrue: [ ^ cachedBitPattern _ Bitmap with: 16r55555555 with: 16rAAAAAAAA]. "medium gray" brightness < 0.8 ifTrue: [ ^ cachedBitPattern _ Bitmap with: 16r44444444 with: 16r11111111]. "light gray" ^ cachedBitPattern _ Bitmap with: 16r0. "white"! computeBitPatternForDepth: depth | pixels | depth = 8 ifFalse: [^Bitmap with: (self pixelWordForDepth: depth)]. pixels := self fourPixelValuesForDither: depth. ^Bitmap with: (16r10001 * (pixels at: 1)) + (16r1000100 * (pixels at: 3)) with: (16r10001 * (pixels at: 2)) + (16r1000100 * (pixels at: 4))! fourPixelValuesForDither: depth "This only works in the 8-bit color cube." "Color allInstancesDo: [:each | each bitPatternForDepth: 4]" "flush existing cached patterns" | r g b rPlus gPlus bPlus rBase gBase bBase | depth = 8 ifFalse: [^Array new: 4 withAll: (self pixelValueForDepth: depth)]. rgb = 0 ifTrue: [^ Array new: 4 withAll: 1]. "Special case for black, very common" rgb = 16r3FFFFFFF ifTrue: [^ Array new: 4 withAll: 0 "255"]. "Special case for white, very common" self privateRed = self privateGreen ifTrue: [ self privateRed = self privateBlue ifTrue: [^Array new: 4 withAll: self closestPixelValue8]]. r := (self privateRed * 20) + HalfComponentMask // ComponentMask. g := (self privateGreen * 20) + HalfComponentMask // ComponentMask. b := (self privateBlue * 20) + HalfComponentMask // ComponentMask. rBase := r // 4. rPlus := r \\ 4. gBase := g // 4. gPlus := g \\ 4. bBase := b // 4. bPlus := b \\ 4. ^(0 to: 3) collect: [:i | (rBase + (i >= rPlus ifTrue: [0] ifFalse: [1]) * 36) + (bBase + (i >= bPlus ifTrue: [0] ifFalse: [1]) * 6) + (gBase + (i >= gPlus ifTrue: [0] ifFalse: [1])) + 40] ! ! --------------5899337C242C--

Post a reply.

Go back to index.



Date: 97 May 17 8:55:33 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: Characters in intervals All: (A not too high-priority suggestion.) This works fine: | a | a := OrderedCollection new: 10. $1 asciiValue to: $9 asciiValue do: [ :ch | a add: ch asCharacter ]. a OrderedCollection ($1 $2 $3 $4 $5 $6 $7 $8 $9 ) But this does not (on Squeak or IBM or VW or others): | a | a := OrderedCollection new: 10. $1 to: $9 do: [ :ch | a add: ch ]. All fail trying to add a 1 to a character (or subtracting 1 from a character!!). However, put parentheses around the interval and it works again: | a | a := OrderedCollection new: 10. ($1 to: $9) do: [ :ch | a add: ch ]. ($1 $2 $3 $4 $5 $6 $7 $8 $9 ) I think the second version should work too and it should be easy to fix with a new method in Character (similarily to how #to: is fixed): to: other do: aBlock "(DNS May97)" | collection | collection := (self asciiValue to: other asciiValue) collect: [:ascii | Character value: ascii]. collection do: aBlock except that #do:to: is compiled inline. This works: | a | a := OrderedCollection new: 10. $1 perform: #to:do: with: $9 with: [ :ch | a add: ch ]. ($1 $2 $3 $4 $5 $6 $7 $8 $9 ) I would like to suggest that any magnitude that answers a collection from the expression (a to: b) also work properly with with #to:do:. Anything else violates the principle of lease surprise. (Actually Character seems, on a quick look, to be the only other magnitude that supports #to:.) Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 17 2:48:27 pm From: Dan Ingalls <DanI@wdi.disney.com> To: "David N. Smith" <dnsmith@watson.ibm.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <v0310280cafa38609cdc6@[129.34.225.178]> Subject: Re: Characters in intervals >I think the second version should work too and it should be easy to fix >with a new method in Character (similarily to how #to: is fixed): > >to: other do: aBlock > "(DNS May97)" > | collection | > collection :=3D (self asciiValue to: other asciiValue) collect: > [:ascii | Character value: ascii]. > collection do: aBlock I'm with you regarding uniform behavior. In this case, though, I'd keep it = simple: <Magnitude> to: other do: aBlock ^ (self to: other) do: aBlock What keeps it from being a simple fix is that the compiler has to check= whether or not to compile to:do: inline. Right now it always does. We= could check for non-integer constants, which would work for your example. = But we still wouldn't be able to do "a to: b do: [...]" correctly, unless= we stop compiling all cases of to:do: inline. Another use for type inferen= ce. - D

Post a reply.

Go back to index.



Date: 97 May 17 4:47:22 pm From: johnson@cs.uiuc.edu (Ralph E. Johnson) To: squeak@create.ucsb.edu Subject: Re: Correcting long-standing problems At 8:57 AM 5/15/97, Anthony Lander wrote: >Once everyone (i.e. Dan) is busy correcting long-standing problems, such as >hashing and coersion, could I convince you to tackle one more? > > #mustBeBoolean >Man, this bothers me. I've reimplemented #doesNotUnderstand: more times >than you can shake a stick at. You simply cannot build a good proxy object >in Smalltalk because of this message. Can the VM be changed such that >messages like #and: fail by really sending the #and: message (not inlined) >instead of sending #mustBeBoolean? This is not just a VM change. The compiler optimizes #and by generating in-line branches. So, there is no block for the VM to use as the argument of the message. I suppose the compiler could generate two versions of the method, and the #mustBeBoolean message could restart the slower version of the method. Alternatively, the compiler could just not optimizie #and:. I bet it wouldn't make much of a difference to most of the image. It is pretty easy to hack the compiler to tell it not to optimize certain methods. It has a table of methods that it optimizes, and you can just change the table. -Ralph

Post a reply.

Go back to index.



Date: 97 May 19 11:36:27 am From: lnotarfr@dc.uba.ar (Luciano Esteban Notarfrancesco) To: piumarta@prof.inria.fr (Ian Piumarta) Cc: squeak@create.ucsb.edu In-Reply-To: <199705151419.QAA26273@prof.inria.fr> from "Ian Piumarta" at May 15, 97 04:19:06 pm Subject: Re: hashing > > > What is better? A faster hash function or a more disperse hash function? > > That depends on the density of collections. If all my (unordered) > collections have only one element in them, then the fastest hash function > possible is what I want. If all my collections are almost full, then the > most dispersed hash function is what I want. There's no "correct" answer > to the question: it will always be a compromise between generating a fast > initial probe index, and the number of reprobes needed to find the target > element (or nil ;-). > > Maybe the question should be: "Does anyone know what the optimal > compromise is for the average collection in Squeak, taking into account > whatever happens to be the "grow threshold" for collections this week?" Actually, the problem here is related to the hash implementation for unordered collection. For Sets, for example, I found only two ways to do it: the easy one, that involves none of the elements of the Set (e.g., ^self size) and the hard (slow) solution, that involves all the elements of the Set (e.g., ^self inject: 0 into: [ :hashValue :each | hashValue + each hash]). I don't know what to do in this case. May be the problem here is not the iteration over all the elements of the Set. The problem might be the hash function of the elements. I mean, if the elements are all Integers or Symbols (objects with fast hash functions) then it could be good (disperse and still fast) to iterate over all of them and answer the sum of all the hashes. A way to solve this (and probably a bad idea) is to implement another hash guarrantied to be fast. For example, Object could implement fastHash ^self hash ! and that Set could do fastHash ^self size ! hash ^self inject: 0 into: [ :hashValue :each | hashValue + each fastHash ] ! ... it's just the first alternative solution I found. -- Luciano.

Post a reply.

Go back to index.



Date: 97 May 19 1:01:57 pm From: "Terry Raymond" <traymond@craftedsmalltalk.com> To: "squeak" <squeak@create.ucsb.edu> Subject: OS/2 port of Squeak? Hi I just subscribed to this list and would like to know if there is an OS/2 port of Squeak or is there one in progress? Terry Raymond Crafted Smalltalk (401) 846-6573 http://www.craftedsmalltalk.com

Post a reply.

Go back to index.



Date: 97 May 20 4:55:22 am From: Ian Piumarta <piumarta@prof.inria.fr> To: squeak@create.ucsb.edu Subject: New VM for Unix is in the usual place Squeakers, I've finally got round to copying the 1.19 VM from my laptop to the FTP server. (It should have "made in Italy" stamped on it -- I was at a conference when I first built it. ;-) On alix.inria.fr, in the directory /pub/squeak/unix/Squeak-1.19d, you will find: images/Squeak1.19.{image,changes} // as per Mac 1.19d distribution images/SqueakV1.sources // as per Mac 1.19d distribution (It's the "plain" 1.19d image with none of the patches sent to this list since the original distribution.) bin/SqueakVM-1.19-decAlpha-osf1_3.0* // stripped, etc... bin/SqueakVM-1.19-i586-freebsd2.1.5 bin/SqueakVM-1.19-i586-linux1.2 bin/SqueakVM-1.19-sparc-solaris2.5* bin/SqueakVM-1.19-sparc-sunos4.1* src/...the...usual...stuff... // no gcc "goto" hacks applied The mirrors on the other sites should catch up presently. Please let me know immediately if you find any problems with any of these VMs. (I've run each one briefly, and printed "Float pi", and they seem OK.) New features include (and, apart from being built from the latest Interpreter sources, are limited to): - the image name now appears in the title bar/icon/whatever... - the "-lazy" option has gone back in, with "busy" being the default Luciano has implemented sound for Linux, but I've not had time to put the support into the VM yet. Hopefully in the next couple of days. (I'll try to do FreeBSD while I'm at it -- Luciano thinks that they're fairly similar.) Also, if there's anyone out there with experience of NetAudio, and who would like to implement support for it in Squeak, please get in touch. People with other architectures are cordially invited to compile a VM, strip it, and deposit the result in: ftp://alix.inria.fr/pub/incoming (then send me email to let me know that it's there!) That's it. Enjoy! Ian ------------------------------- projet SOR ------------------------------- Ian Piumarta, INRIA Rocquencourt, Internet: Ian.Piumarta@inria.fr BP105, 78153 Le Chesnay Cedex, FRANCE Voice: +33 1 39 63 52 87 ----------------------- Systemes a Objets Repartis -----------------------

Post a reply.

Go back to index.



Date: 97 May 20 9:26:45 am From: Maloney <johnm@wdi.disney.com> To: "Terry Raymond" <traymond@craftedsmalltalk.com> Cc: "squeak" <squeak@create.ucsb.edu> In-Reply-To: <199705192028.QAA24803@web2.idt.net> Subject: Re: OS/2 port of Squeak? At 1:23 PM -0400 5/19/97, Terry Raymond wrote: >I just subscribed to this list and would like to know if there is an >OS/2 port of Squeak or is there one in progress? Not that I know of. -- John

Post a reply.

Go back to index.



Date: 97 May 22 4:15:41 pm From: "Terry Raymond" <traymond@craftedsmalltalk.com> To: "squeak" <squeak@create.ucsb.edu> Subject: Neon := Smalltalk + Forth Hi I just finished reading the archived messages and was suprised that with all the discussion about Forth and Smalltalk no one mentioned Neon. Neon was produced in the mid80's and it combined Forth and Smalltalk syntax. It was available on the Mac only. Now, there are three follow on packages that are available, all are free, Yerk, MOPS, and Win32Forth. Yerk and MOPS are still Mac only packages. If you want to know more go to dejanews and do a search in the c.l.f group. You can also get information at www.forth.org. Terry Raymond Crafted Smalltalk (401) 846-6573 http://www.craftedsmalltalk.com

Post a reply.

Go back to index.



Date: 97 May 22 5:41:30 pm From: bbennett@unixg.ubc.ca To: "squeak" <squeak@create.ucsb.edu> In-Reply-To: <199705222342.TAA01863@web2.idt.net> Subject: Re: Neon := Smalltalk + Forth "Terry Raymond" <traymond@craftedsmalltalk.com> wrote: >I just finished reading the archived messages and was suprised that with all >the discussion about Forth and Smalltalk no one mentioned Neon. Neon >was produced in the mid80's and it combined Forth and Smalltalk syntax. >It was available on the Mac only. Now, there are three follow on packages >that are available, all are free, Yerk, MOPS, and Win32Forth. Yerk and >MOPS are still Mac only packages. <snip> Mops is not entirely Mac-only any longer. Mike Hore, the author of Mops, has recently made an "adaptation of Andrew McKewans's OOP system for ANS Standard Forth, to add further extensions as provided by the Mops language." <ftp://ftp.taygeta.com/Forth/ANS/classM10.txt> <ftp://ftp.taygeta.com/Forth/ANS/classM10.zip> -- Bruce Bennett <bbennett@unixg.ubc.ca>

Post a reply.

Go back to index.



Date: 97 May 22 6:33:04 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: RE: New Arithmetic Coercion Mechanism I have an observation about multiplication of fractional numbers. It may = be not very critical in some applications but I think it must be = considered here. The traditional implementation of #* in the Fraction class uses = something like this: (Fraction numerator: numerator * aNumber numerator denominator: denominator * aNumber denominator) reduced With this code the reduction is performed with a numerator and a = denominator unnecessary "big" since this numbers are obtained by = multiplication. =20 Now consider this code | f1 f2| f1 :=3D numerator / aNumber denominator. f2 :=3D aNumber numerator / denominator. ^Fraction numerator: f1 numerator * f2 numerator denominator: f1 denominator * f2 denominator In this second version you change one reduction of possible big numbers = with two reductions of smaller numbers. This alternative version is a bit slower when all the numbers are small = but is realy faster (10 times or so) than the traditional one when = LargeIntegers are involved. Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 22 8:29:21 pm From: "Hal Hildebrand" <horus@pacbell.net> To: "Squeak mailing list" <squeak@create.ucsb.edu> Subject: Threaded interpreter Is there some effort afoot (or ahand) at converting the Squeak interpreter into a threaded interpreter? Hoping to avoid duplication of effort... Cheers, Hal __ Time is when the day is like a play by Sartre When it seems that book burning's in perfect order http://www.hellblazer.com (Web) mailto:hal@parcplace.com (Business) mailto:horus@pacbell.net (Personal)

Post a reply.

Go back to index.



Date: 97 May 22 10:30:48 pm From: gregory@eng.adaptec.com (Greg Gritton x2386) To: squeak@create.ucsb.edu, horus@pacbell.net Subject: Re: Threaded interpreter There is probably a lot of work that can be done before turning squeak into a threaded interpreter. There is still a lot of time spent in such methods as - activateNewMethod - lookupInMethodCacheSelclass - recycleContextIfPossiblemethodContextClass - fetchClassOf - primitiveAt Reorganizing the context structure to use stacks, the object format to get rid of the special class format where the class is encoded into the header word (with a lot of overhead every time a class is fetched, which is required for dynamic dispatch), combining commonly used bytecodes, etc. We can probably achieve a significant speedup by doing these things without sacrificing portability. Of course, a threaded interpreter would add additional perfoemance. Greg Gritton

Post a reply.

Go back to index.



Date: 97 May 23 1:02:18 am From: "Han-earl -Zappaphile- Park" <8947020@arran.sms.ed.ac.uk> To: squeak@create.ucsb.edu Subject: Re: Neon := Smalltalk + Forth >"Terry Raymond" <traymond@craftedsmalltalk.com> wrote: > >>I just finished reading the archived messages and was suprised that with all >>the discussion about Forth and Smalltalk no one mentioned Neon. Neon >>was produced in the mid80's and it combined Forth and Smalltalk syntax. >>It was available on the Mac only. Now, there are three follow on packages >>that are available, all are free, Yerk, MOPS, and Win32Forth. Yerk and >>MOPS are still Mac only packages. ><snip> For those interested in these things, there's at least one other Forth-Smalltalk hybrid: HMSL (Hierarchical Music Specification Laguage) developed by Phil Burk, Larry Polansky and David Rosenboom (and others). HMSL is avilable for the Mac and Amiga (the OOP section was available separately as ODE on the Amiga version).

Post a reply.

Go back to index.



Date: 97 May 23 9:32:27 am From: Aaron Rosenzweig <recurve@xombi.wizard.net> To: squeak@create.ucsb.edu Cc: recurve@resourceful.com Subject: Thanks! I used Squeak in my computer science 330 class at the University of Maryland this past semester. It was great! The class would have been many times more unpleasant without it. --- SW Son of Ginger and Harry, Aaron Rosenzweig SW http://www.wam.umd.edu/~recurve/ SW... recurve@resourceful.com SWN?

Post a reply.

Go back to index.



Date: 97 May 23 12:58:51 pm From: Ian Piumarta <piumarta@prof.inria.fr> To: gregory@eng.adaptec.com, hal@parcplace.com Cc: squeak@create.ucsb.edu Subject: Re: Threaded interpreter Squeakers (Hal and Greg in particular), Maybe it's time I explained to the list exactly what I've been doing these past few weeks. Here's a very brief overview of the progress so far. I currently have two streams of VM development going on. The first concerns dynamic translation. I have implemented this directly in Squeak, writing it all in Smalltalk rather than trying to build support for it in C or assembler. To be fair, about 10 lines of compiler/architecture specific code are required in the sq.h header file to support this, although the GCC support is generic and will work on any platform (including the Mac if you have either MachTen, [Mk]Linux[-pmac], or CodeWarrior 11 [which allegedly comes with GCC]). [Aside for John, if he's listening: the function call and "pointer glue" code in the CW threaded dispatch costs almost nothing. I succeeded in linking a GCC/MachTen-compiled interp.o (which has inlined dispatches and no pointer glue) with the rest of the CW stuff in the PPC project, and the performance is the same on all the Macs (5400, 6400, 7600) that I've tried.] We thought it would be interesting (at least initially) to see how many of the management tasks could be performed using existing parts of the system. For example, by translating CompiledMethods into real Squeak obects the regular GC can take care of "flushing" stale translated methods out of the object memory. Currently, CompiledMethods are dynamically translated into a triplet consisting of: - an Array containing the addresses of (direct) threaded code entry points, inlined operands for jump offsets, temp/receiver variable indices, literal constants, and association pointers for literal variables. The "opcode" addresses look like SmallIntegers (many RISC architectures ignore the bottom 2 bits in jump addresses) which allows the GC to take care of remapping the inline "operands". - a Bitmap containing a map of bytecode PC to threaded code PC - a Bitmap containing a map of threaded code PC to bytecode PC. The two PC maps are used for fetching and storing the context registers, and for fetching the original bytecode when failing special primitives. Both of these require further attention: e.g. it would be nice to be able to store "raw" pointers into translated methods and convert them into GC-safe forms only during a GC, and into the Smalltalk-friendly forms only when it is known that a context will be manipulated from Smalltalk. (More about this later.) CompiledMethods are translated when they are first brought into the method cache (there is an extra slot in each cache line to hold a pointer to the translated method) during a send. For returns, the translated method is also stored in a slot in MethodContexts. The implementation of each opcode (there are currently about 70 opcodes, half of which are for the common and arithmetic sends) is split into two parts to make simulation (in Smalltalk) easier. First there is a definition part, which is used to initialise a table of opcode entry points. Each opcode has an initialisation method that looks like this: oiMyOpcode (self defineOp: MyOpcode) ifTrue: [ self beginOp: MyOpcode. self opMyOpcode. self endOp. ]. "MyOpcode" is a class variable containing an integer unique to this opcode. In the compiled translator this is used to initialise the correct slot in the opcode table with the address of the entry point for the opcode, defined by the call to beginOp. "endOp" is the threading operation, which causes the next instruction to be dispatched. (endOp can be called anywhere within an opcode implementation; e.g. if a special arithmetic opcode finds an integer reveiver and argument that yield an integer result, the stack is updated and endOp is called "internally" to elide the redundant jump to the end of the opcode implementation.) Second, the actual work of the opcode is performed in the implementation method "opMyOpcode". Many of these look similar to the implementations of the bytecodes in the current Interpreter. The translator framework is written in such a way as to make the bytecode-to-threaded code transformation as flexible as possible. Several "common sequence" optimisations are already implemented, and adding more is trivial. I also have a paper design for an inline cache which should reduce the impact of the fetchClassOf overhead by using several different "send" opcodes, specialised on the kind of receiver. For example, the generic "send" opcode checks the class of the receiver, and if it finds that it is a SmallInteger it replaces the opcode with a different "send" specialised on SmallIntegers. This latter "send" need only check the tag bit to decide if the cache has hit or missed. It's obvious how this copes with the various kinds of non-immediate objects having (for example) compact class headers, etc... Two passes are currently required to perform the translation. The first pass "sizes" the translated code and builds the bytecode to threaded PC map. The second pass generates the translated code, resolving jump destinations using the map generated in the first pass, and builds the threaded to bytecode PC map. Threaded code performs about 10-20% better than byecodes on my Performa, depending on the kind of work being done. (The figures are better on the "serious" machines that we have at work -- mainly, I suspect, because most of the gains are being swamped by the overheads on my Mac due to its relatively low main memory bandwidth and sluggish 2nd level cache.) The second stream of development is concerned with adding "volatile" contexts to Squeak. (I also noticed that the majority of the time in Squeak was being spent in message send and return.) I have added a shared stack to the interpreter, which allows the majority of message sends to avoid copying arguments. When a new method is activated, a new "volatile" context is allocated for it. None of the indexable fields of this context are used. Instead, a volatile context contains two pointers: a "frame pointer" which points to the first argument in the shared stack that is associated with its activation, and a "stack pointer" which works just like the current stackPointer, except that it points into the shared stack too. The only loop needed during message sending is to store nil into the temporary variable locations in the shared stack. The interpreter also has a homePointer, which points at the first temporary location for the active method/block (which could be either in the shared stack, or inside the indexable part of the home context). When an activation returns, its volatile context is placed on the head of a free context list -- in much the same way as Squeak does things at the moment. An important characteristic of this scheme is that volatile contexts on the free list always have nil in their indexable fields, so the loop in the current interpreter which clears these fields is no longer needed. Contexts are "stabilised" whenever they might outlive their activations. Stabilisation involves copying the associated region of the shared stack into the indexable part of the context. Stable contexts are never recycled. I considered using a scheme similar to BrouHaHa, but it turned out to be impossible (or at least very expensive during stabilisation) with the direct pointer object memory used in Squeak. (BrouHaHa benefits, at least in this respect, from having an object table.) I've "ruthlessly" hand-tuned the activateNewMethod and return:to: methods, and am now looking at the remainder of the send code to find other areas where it could be made faster. One thing which I will implement in the next day or two is a change to the way blocks are activated, so that the stored BlockContext is copied into a new volatile context instead of being reactivated -- avoiding the need to stablise the entire stack. A (rather unintentional ;-) side effect of this will be that blocks become re-entrant. (From there it will hopefully be trivial to integrate Hans Martin's closure work, at some later date.) There is a lot more performance to be gained from working on contexts. However, these initial steps already show measurable performance improvements during activities with both low and high allocation rates: benchmark: 30 benchFib Intepreter compileAll units: calls/sec milliseconds original Squeak: 459085 14350 volatile contexts: 503466 13408 gain: 10% 7% (The benchFibs result is interesting: Squeak with volatile contexts on a 333MHz DEC AXP has almost exactly the same activation performance as ObjectWorks 4.1 on a Sparc IPX. ;-) ;-) ;-) I've kept the context and translation work separate for the moment in the hope that we'll be able to release a version of the Interpreter that offers the new context handling without the additional overheads implied by dynamic translation. In particular, the people working on implementations for machines with small memories pobably wouldn't want to pay the price of a larger object memory just to store the translated code. I'll keep you all updated w.r.t. further developments. Ian

Post a reply.

Go back to index.



Date: 97 May 23 1:41:02 pm From: James McCartney <james@clyde.as.utexas.edu> To: Ian Piumarta <piumarta@prof.inria.fr>, squeak@create.ucsb.edu Cc: squeak@create.ucsb.edu In-Reply-To: <199705232025.WAA03394@prof.inria.fr> Subject: Re: Threaded interpreter At 1:25 PM -0700 5/23/97, Ian Piumarta wrote: >Threaded code performs about 10-20% better than byecodes on my >Performa, depending on the kind of work being done. (The figures are >better on the "serious" machines that we have at work -- mainly, I >suspect, because most of the gains are being swamped by the overheads >on my Mac due to its relatively low main memory bandwidth and sluggish >2nd level cache.) Or perhaps it is that due to indirect function calls going through the __ptr_glue() function on the PowerPC, it is not much faster to do an indirect call than it is to switch(). --- james mccartney james@clyde.as.utexas.edu james@lcsaudio.com If you have a PowerMac check out SuperCollider, a real time synth program: ftp://mirror.apple.com//mirrors/Info-Mac.Archive/gst/snd/super-collider-demo.hqx

Post a reply.

Go back to index.



Date: 97 May 24 5:49:37 am From: Ian Piumarta <piumarta@prof.inria.fr> To: james@clyde.as.utexas.edu Cc: squeak@create.ucsb.edu Subject: Re: Threaded interpreter > Or perhaps it is that due to indirect function calls going through > the __ptr_glue() function on the PowerPC, it is not much faster to do > an indirect call than it is to switch(). I don't think this is a problem. Using an interp.o compiled with GCC under MachTen (which generates an *inlined* dispatch that involves neither function call nor pointer glue), linked with the regular CodeWarrior PPC files under MacOS, the performance is the same. (This is quite surprising in itself, considering the rather poor code generated by the CW compiler for all the convoluted constants in the arithmetic for fetch/storePointer: etc...) The PPC has an impressive bunch of pre-fetch logic that may well be reducing the overhead of the function call to something approaching zero. Ian

Post a reply.

Go back to index.



Date: 97 May 24 11:21:27 am From: Paul Fernhout <kfsoft@netins.net> Cc: squeak@create.ucsb.edu, pmueller@decrc.abb.de Subject: Re: mobile robot language Peter Mueller <pmueller@decrc.abb.de> wrote: > > I built a small mobile robot and searching for a 'language' to programm > its movements. > > My idea is to have a (script)-language like this: > > move to point x,y > set speed to z > drive circular path .. > ... > .. > > I plan to download this as 'text' and interpred it by the robot. Is > there a general used language like this? Is there a simulator for such > script-languages (to predict the path)? > > Peter Mueller Peter - If your robot is going to have PC based controller (running Windows 95, Unix, or Apple O/S) your could try using Squeak, which is available for free at one of these sites (one is in Germany): http://www.research.apple.com/research/proj/learning_concepts/squeak/ ftp://ftp.cs.uni-magdeburg.de/pub/Smalltalk/free/squeak/win32/ ftp://alix.inria.fr:/pub/squeak/ Squeak is a version of Smalltalk which includes complete source code and has very few restrictions on commerical use. You can recompile the VM (using a C compiler) and add primitives to do I/O. The biggest drawback to the current version of Squeak is that is runs about 40X - 60X slower than compiled C code. However, people are working on the improving the speed, and for many applications, speed is not a major issue, or you can delegate the computationally intensive part to a C coded primitive. You could write an interpreter for a language like what you described fairly easily in Smalltalk (once you learned the language and something about writing interpreters in it - a freeware library of Smalltalk code called TGEN might help with this). Alternatively, and more easily, since a Squeak run-time may include the Smalltalk compiler, you could send Smalltalk code directly to your onboard Squeak environment, such as: robot moveToPoint: x @ y. "move to point x,y" robot setSpeedTo: z. "set speed to z" robot driveCircularPath. "drive circular path" The performance of such code sent directly to Squeak (even given its slow performance) would likely be as good or better than the performance from any interpreter you were to write from scratch in the near term. On the subject of simulating paths: to use some object oriented programming jargon, you could create two types of concrete robot classes under a common superclass: AbstractRobot RealRobot SimulatedRobot A simulated robot instance "robot := SimulatedRobot newForWindow: aRobotSimulationWindow" could be used to test your code in a graphical window (implemented using Squeak's graphical pen, which acts as 2D turtle). A real robot instance "robot := RealRobot newForController: aRobotIOController" would call I/O routines instead. Both could have the same interface, defined in the class AbstractRobot. Squeak comes with a complete range of tools to speed development (debugger, inspector, browser, garbage collector, limited version control). Smalltalk allows you to select expressions from a text window and by choosing "do it" from a menu, the expression is compiled and executed. This is useful for testing your robot code one step at a time via simulation. If your robot is tethered to a development workstation, you can test it interactively, either by having the desktop workstation talk to the motor controller directly, or by just sending arbitray snippets of code through to the robot as you select them or type them on the workstation. Someone else in this thread on comp.robotics.misc mentioned using Forth, which is another good solution, and would have a much smaller learning curve, and run well on less powerful machines. Forth is easier to use to get started in doing real time control, and in the past I have used it (via an onboard Forth computer) to send commands to a mobile robot from a PC. However, Squeak offers a much more powerful programming environment for complex systems than Forth (including an portable graphics and windowing system), which might be an advantage in the long term. Ideally, someday I would like to see a mixture of Forth and Smalltalk somehow combining the best features of both for use in simulation, knowledge engineering, and real-time control. -Paul Fernhout Kurtz-Fernhout Software kfsoft@netins.net ======================================== Download a public beta release of our garden simulator at: http://www.gardenwithinsight.com

Post a reply.

Go back to index.



Date: 97 May 24 12:09:48 pm From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: Bug in Fraction readFrom: Hi: Number>>#readFrom: does not handle fractions, leading to: Fraction readFrom: '2/3' producing the value 2. Here is a corrected version of Number>>#readRemainderOf: which has four new lines near the end for fractions. It doesn't fix the oddity of: Fraction readFrom: '2.3' producing the floating value 2.3! This is a general problem with #readFrom: that, if fixed, would require splitting #readRemainderOf: into parts and putting them in various classes, meanwhile probably breaking something else. It also doesn't fix the oddity of '2asf' being 2, but that is another story. If you can't read the following, widen your mail window; in mine the default tabs are 8 spaces and it looks awful in a narrow window. readRemainderOf: integerPart from: aStream base: base "Read optional fractional part and exponent, and return the final result" | value fraction fracpos | value _ integerPart. (aStream peekFor: $.) ifTrue: ["<integer>.<fraction>" (aStream atEnd not and: [aStream peek digitValue between: 0 and: base - 1]) ifTrue: [fracpos _ aStream position. fraction _ Integer readFrom: aStream base: base. fraction _ fraction asFloat / (base raisedTo: aStream position - fracpos). value _ value asFloat + (value < 0 ifTrue: [fraction negated] ifFalse: [fraction])] ifFalse: ["oops - just <integer>." aStream skip: -1. "un-gobble the period" ^ value "Number readFrom: '3r-22.2'"]]. (aStream peekFor: $e) ifTrue: ["<integer>e<exponent>" ^ value * (base raisedTo: (Integer readFrom: aStream))]. (aStream peekFor: $/) "DNS added four lines here *************************************" ifTrue: ["<integer>/integer" ^ value / (Integer readFrom: aStream)]. ^ value Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 24 1:50:44 pm From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu In-Reply-To: <v03102800afacf0784526@[129.34.225.178]> Subject: Re: Bug in Fraction readFrom: At 15:37 -0400 5/24/97, David N. Smith wrote: >If you can't read the following, widen your mail window; in mine the >default tabs are 8 spaces and it looks awful in a narrow window. Seemed lke a good idea :-) Turns out that something folded all the lines and it's a mess. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 24 1:54:13 pm From: "Hal Hildebrand" <horus@pacbell.net> To: "Paul Fernhout" <kfsoft@netins.net> Cc: <squeak@create.ucsb.edu>, <pmueller@decrc.abb.de> Subject: Re: mobile robot language Peter Mueller <pmueller@decrc.abb.de> wrote: > > I built a small mobile robot and searching for a 'language' to programm > its movements. > > My idea is to have a (script)-language like this: > > move to point x,y > set speed to z > drive circular path .. > ... > .. > > I plan to download this as 'text' and interpred it by the robot. Is > there a general used language like this? Is there a simulator for such > script-languages (to predict the path)? > > Peter Mueller Peter, for what it's worth, this seems like an ideal application of "turtle" geometry. Just like the Logo guys did. Smalltalk is an excellent language for building these simulations. Hal __ Time is when the day is like a play by Sartre When it seems that book burning's in perfect order http://www.hellblazer.com (Web) mailto:hal@parcplace.com (Business) mailto:horus@pacbell.net (Personal)

Post a reply.

Go back to index.



Date: 97 May 25 7:56:04 am From: "Hal Hildebrand" <horus@pacbell.net> To: <gregory@eng.adaptec.com>, "Ian Piumarta" <piumarta@prof.inria.fr> Cc: <squeak@create.ucsb.edu> Subject: Re: Threaded interpreter Okay, so this is a lot of work. It's going to take me a while to get the big picture on the current translator architecture. But, this is fun. The approach I prefer is to use 32 bit opcodes directly, rather than bytecodes. You have a canonical form for image saves, and method creates. But, when the method is first run, the translation to machine specific addresses happens "in place", overwriting the compiled method's bytes. Upon image save, these compiled methods are reconverted to the canonical form. Using a wide op code space allows you to create a CISC-like interpreter, encoding the common bytecode sequences directly by the compiler. My preference, anyway. I like Ian's idea of making as much use of ST as one can in creating a dynamic translator. Some guys I know did the same thing with Java. Worked out pretty well. A key to speed is the stack, however. One can provide the illusion of full closures without paying the cost. You just have to be willing to provide support for "thisContext" entirely through primitives, and you can never store "thisContext" into a variable. Oh well, lot's to do. Lot's to do. Thanks, all, for such a wonderful system to play with. It's pretty cool. Hal __ Time is when the day is like a play by Sartre When it seems that book burning's in perfect order http://www.hellblazer.com (Web) mailto:hal@parcplace.com (Business) mailto:horus@pacbell.net (Personal)

Post a reply.

Go back to index.



Date: 97 May 25 7:02:38 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: [Windows] arrow keys Hi. The arrow keys do not move the cursor in my 1.19d for Windows (I am using NT 4.0). The same problem happens with Home, End, Page Up and Page Down. Has anybody else found these difficulties? Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 25 7:19:01 pm From: johnson@cs.uiuc.edu (Ralph E. Johnson) To: "Hal Hildebrand" <horus@pacbell.net> Cc: <squeak@create.ucsb.edu> Subject: Re: Threaded interpreter So, you have discovered Squeak! I signed up on the list some time ago and got one of the versions of Squeak, but I haven't had time to do much more than just look around. It is neat to have a free Smalltalk-80, it is neat that it is implemented in itself, and there is a neat community forming around it. I'm glad you are interested. But how do you have the time to play with it? -Ralph

Post a reply.

Go back to index.



Date: 97 May 26 8:51:42 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: Decompiled code is wrong; more float problems I ran this code from a workspace: | from to mult | from := 1.0e-200. to := 1.0e200. mult := 5.0. [ from <= to ] whileTrue: [ from asTrueFraction2. from := from * mult ]. Since it took a while, I command-dotted it and saw this, not so equivalent, source code: DoIt | t1 t2 t3 | t1 _ 1.00000000000002e-200. t2 _ 9.99999999999968e199. [t1 <= t2] whileTrue: [t1 asTrueFraction2. t1 _ t1 * t3]. t3 _ 5.0. ^ nil Note the t3 := 5.0 AFTER the loop. Somehow it got moved... Also, the floating point constants are a bother. Take 1.0e200, select it, and successively do Command-P. You get a series of numbers like this: 1.0e200 9.99999999999968e199 9.99999999999936e199 9.99999999999904e199 9.99999999999872e199 9.9999999999984e199 Thus, recompiling the decompiled code causes the values to become different. So, I thought, use printStringBase: to produce a value in hex and output the decimal value as a comment. This will take the original version's binary equivalent and faithfully reproduce it. 1.0e200 printStringBase: 16 '1.4E718D7D762Ae166' This hex result requires a leading '16r', so I added one: 16r1.4E718D7D762Ae166 Evaluating that got: 1.30642017663028 which means that the exponent is being totally ignored. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 26 10:45:39 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: Update to asTrueFraction; faster; better comments All: Here is an improved asTrueFraction to replace the version of a few weeks ago. I profiled it on IBM Smalltalk V4 and found several places to increase its performance. Profiling it on Squeak showed that most of the time (70%) is spent in #gcd:. I also added comments, hopefully to make it less opaque for those who don't carry IEEE float formats around intheir heads. :-) 'From Squeak 1.19d of April 13, 1997 on 26 May 1997 at 12:40:59 pm'! !Float methodsFor: 'converting'! asTrueFraction2 " Answer a fraction that EXACTLY represents self, a double precision IEEE floating point number. Floats are stored in the same form on all platforms. (Does not handle gradual underflow or NANs.) " | shifty sign exp fraction result | " Extract the bits of an IEEE double float " shifty := ((self basicAt: 1) bitShift: 32) + (self basicAt: 2). " Extract the sign and the biased exponent " sign := (shifty bitShift: -63) = 0 ifTrue: [1] ifFalse: [-1]. exp := (shifty bitShift: -52) bitAnd: 16r7FF. " Extract fractional part; answer 0 if this is a true 0.0 value " fraction := shifty bitAnd: 16r000FFFFFFFFFFFFF. ( exp=0 and: [(fraction=0) & (self=0.0)] ) ifTrue: [ ^ 0 ]. " Replace omitted leading 1 in fraction; unbias exponent " fraction := fraction bitOr: 16r0010000000000000. exp := exp - 16r3FF. " Form the result; (this is faster than more obvious code) " result := exp <= 52 ifTrue: [ sign * fraction / (1 bitShift: 52 - exp) ] ifFalse: [ sign * fraction * (1 bitShift: exp - 52) ]. " Validate the result (low cost; optional); answer result " result asFloat = self ifFalse: [self error: 'asTrueFraction validation failed' ]. ^ result! ! The timings below are shown for Squeak 1.19d and VW 2.5 on the same machine. The absolutely horrrible results for 1.0E-200 seem to be due to very slow long integer support in Squeak, and the necessity of invoking the fancy #gcd: which aggravates the problem when values are very large. (It's 1/3 the speed of Eucled's algorithm for the fractional components of 1.0e-200, though much faster on, say, Float pi). Tests and timings on PPC 9600/200, V1.19d ========================================= New version (asTrueFraction2): Time millisecondsToRun: [ 1000 timesRepeat: [ Float pi asTrueFraction2 ] ] 9134 Time millisecondsToRun: [ 1000 timesRepeat: [ 3.14159262e200 asTrueFraction2 ] ] 6833 Time millisecondsToRun: [ 1000 timesRepeat: [ 3.14159262e-200 asTrueFraction2 ] ] 317160 Old version (asTrueFraction): Time millisecondsToRun: [ 1000 timesRepeat: [ Float pi asTrueFraction ] ] 18084 Time millisecondsToRun: [ 1000 timesRepeat: [ 3.14159262e200 asTrueFraction ] ] 60050 Time millisecondsToRun: [ 1000 timesRepeat: [ 3.14159262e-200 asTrueFraction ] ] 641000 Original version (asFraction): Time millisecondsToRun: [ 1000 timesRepeat: [ Float pi asFraction ] ] 267 Time millisecondsToRun: [ 100 timesRepeat: [ 3.14159262e200 asFraction ] ] "Runs out of memory" Time millisecondsToRun: [ 100 timesRepeat: [ 3.14159262e-200 asFraction ] ] "Runs out of memory" Tests and timings on PPC 9600/200, VW 2.5 ========================================= Time millisecondsToRun: [ 1000 timesRepeat: [ Double pi asTrueFraction2 ] ] 483 Time millisecondsToRun: [ 1000 timesRepeat: [ 3.14159262d200 asTrueFraction2 ] ] 916 Time millisecondsToRun: [ 1000 timesRepeat: [ 3.14159262d-200 asTrueFraction2 ] ] 933 Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 26 11:26:26 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: squeak@create.ucsb.edu Subject: Profiler & Messed up windows All: I used the profiler in squeak for the first time today and: (1) it worked and I got useful results, but (2) it left the windowing system in a real mess. Even after closing the profiler and saving the image and restarting it is still messed up. It seems to forget what window is active, it leaves garbage laying around, blacks out overlayed parts of windows, pastes to the wrong place, etc. One can get a window active by selecting in it several times and then redrawing the whole screen and things work OK for a while, until you change windows. Has anyone else seen this behavior or have I screwed something up? I've not been messing with windowing nor have I loaded any new stuff. I'm on 1.19d. Here is the message I evaluated: MessageTally spyOn: [10 timesRepeat: [ 3.14159262e-200 asTrueFraction2 ]] Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 26 1:45:45 pm From: Dan Ingalls <DanI@wdi.disney.com> To: "David N. Smith" <dnsmith@watson.ibm.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <v03102807afaf84b2bfba@[129.34.225.178]> Subject: Re: Profiler & Messed up windows >All: > >I used the profiler in squeak for the first time today and: > >(1) it worked and I got useful results, but > >(2) it left the windowing system in a real mess. As far as I know, the profiler (MessageTally) in Squeak works well and= behaves well, PROVIDED THAT the expression you give it to evaluate= terminates normally. If it encounters an error, a process switch occurs in= putting up a debugger, and the pending delays in the profiling process can= run amok. I have had this happen myself, and experienced a very similar ef= fect. The obvious solution is to call the messageTally and arrange for an orderly= shut-down before scheduling the debugger window. Right now I'm tied up= doing fun things in Morphic [hope to put out an image for Morphic followers= to experiment with in a few days], but I'll put this one on my list for the= next release. David, by all means let me know again if you experience this behavior with= well-terminated profiles. - Dan

Post a reply.

Go back to index.



Date: 97 May 27 4:07:13 am From: Ian Piumarta <piumarta@prof.inria.fr> To: dnsmith@watson.ibm.com, squeak@create.ucsb.edu Subject: Re: Decompiled code is wrong; more float problems The decompiler is severely broken in various subtle ways. Try holding down the shift key while browsing CharacterScanner>>scanCharsFrom:to:... For a more drastic demonstration, remove your sources file and then try to recompile the image. Ian

Post a reply.

Go back to index.



Date: 97 May 27 8:57:36 am From: lnotarfr@dc.uba.ar (Luciano Esteban Notarfrancesco) To: squeak@create.ucsb.edu Subject: degreeSin Integer implements degreeSin ^self asFloat degreesToRadians sin ! but this fails for big integers. It's better to do: degreeSin ^(self \\ 360) asFloat degreesToRadians sin ! Furthermore, I saw that sqrt is not reimplemented in Integer, but it should be ("anInteger squared sqrt" must answer "anInteger"). Regards, --- Luciano.

Post a reply.

Go back to index.



Date: 97 May 27 7:59:15 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: How to sum fractions 2 times faster Some messages ago I pointed out how to multiply two Fractions improving = the speed of calculation in a noticeably factor. Today Luciano and me = tested the following code for the sum #++ ++ aFraction "Answer the sum of the receiver and aFraction." | crossProduct denGcd crossGcd leftDen rightDen | (aFraction isMemberOf: Fraction) ifTrue: [ denGcd _ denominator gcd: aFraction denominator. leftDen _ denominator // denGcd. rightDen _ aFraction denominator // denGcd. crossProduct _ numerator * rightDen + (aFraction numerator * leftDen). crossGcd _ crossProduct gcd: denGcd. ^Fraction numerator: crossProduct // crossGcd denominator: leftDen * rightDen * (denGcd // crossGcd)] ifFalse: [^ self retry: #+ coercing: aFraction] The results of our tests were interesting also in this case. With a = number of fractions made up of random small integers the sum #++ = evaluated twice as faster than the traditional #+. With bigger integers = the velocity was three times faster. This is the code we used for testing 'From Squeak 1.19d of April 13, 1997 on 27 May 1997 at 4:24:34 pm'!! Fraction class methodsFor: 'examples'! testSum "Compare the implementation of #+ with that of #++" | delta initial interval random t tt t0 answer | delta _ 100. initial _ 1000000. answer _ FillInTheBlank request: 'Magnitude of the numbers' initialAnswer: initial printString. answer isNil ifFalse: [initial _ answer asNumber]. interval _ (initial to: initial + delta). random _ (1 to: delta) collect: [:each | (interval atRandom / interval atRandom) asFraction @ (interval atRandom / interval atRandom) asFraction]. t _ Time millisecondsToRun: [random do: [:each | each x + each y]]. tt _ Time millisecondsToRun: [random do: [:each | each x ++ each y]]. t0 _ Time millisecondsToRun: [random do: [:each | each x. each y]]. ^ t - t0 / (tt - t0) asFloat ! ! Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 27 11:06:46 pm From: Maloney <johnm@wdi.disney.com> To: gregory@eng.adaptec.com (Greg Gritton x2386) Cc: squeak@create.ucsb.edu In-Reply-To: <9705230556.AA26747@eng.adaptec.com> Subject: Re: Threaded interpreter Re: >There is probably a lot of work that can be done before turning squeak >into a threaded interpreter. Yes, we know. Squeak is 50-60 times slower than optimized C on the PowerPC. Digitalk Smalltalk (a very good interpreter) is 15-20 times slower than optimized C on a 68020. So, one should be able to get a factor of three or so without using threaded code. However, it may be easier to get a similar or greater speedup via threading. Ian Piumarta has been working on that, as you know. It may turn out that his context handling improvements give us the most bang for the buck, in which case we may abandon the threading idea. I love the fact that he's pursuing the two optimizations independently. By the way, what platform have you been doing your profiling on and what kind of profiler is it (e.g., PC-sampling on clock interrupts). Also, what benchmarks were you measuring? Your hot list looks pretty familiar except the fetchClassOf. But my profiler (CodeWarrior on the Mac) is not very trustworthy; it tries to measure the time per method but it doesn't properly factor out the cost of the profiler code itself. -- John >There is probably a lot of work that can be done before turning squeak >into a threaded interpreter. There is still a lot of time spent in >such methods as > > - activateNewMethod > - lookupInMethodCacheSelclass > - recycleContextIfPossiblemethodContextClass > - fetchClassOf > - primitiveAt > >Reorganizing the context structure to use stacks, the object format >to get rid of the special class format where the class is encoded into >the header word (with a lot of overhead every time a class >is fetched, which is required for dynamic dispatch), >combining commonly used bytecodes, etc. We can probably achieve >a significant speedup by doing these things without sacrificing >portability. Of course, a threaded interpreter would add >additional perfoemance. > >Greg Gritton

Post a reply.

Go back to index.



Date: 97 May 28 12:28:53 am From: "Hal Hildebrand" <horus@pacbell.net> To: "Greg Gritton x2386" <gregory@eng.adaptec.com>, "Maloney" <johnm@wdi.disney.com> Cc: <squeak@create.ucsb.edu> Subject: Re: Threaded interpreter John, >However, it may be easier to get a similar or greater speedup via >threading. Ian Piumarta has been working on that, as you know. It >may turn out that his context handling improvements give us the >most bang for the buck, in which case we may abandon the threading >idea. I love the fact that he's pursuing the two optimizations >independently. Agreed. Building frames faster, with a C-style stack, will do wonders for the system. It'll be interesting to see what the speed gains are just from that optimization. Hal __ Time is when the day is like a play by Sartre When it seems that book burning's in perfect order http://www.hellblazer.com (Web) mailto:hal@parcplace.com (Business) mailto:horus@pacbell.net (Personal)

Post a reply.

Go back to index.



Date: 97 May 28 5:15:32 am From: Jean Francois Veillette <jfv@hasc.com> To: squeak@create.ucsb.edu Subject: Problem with BlockContext. Sorry if it's a beginner question, but I am. Why the following code doesn't work ? | fib | fib := [:va | va == 1 ifFalse:[ ^ va + ( fib value:va - 1)]. ^ 1.]. fib value:5 I'm running it in workspace and squeak finish with a "Message not understood: *" error, why ? Thank's ! - jfv Jean-Francois Veillette

Post a reply.

Go back to index.



Date: 97 May 28 6:35:16 am From: Thierry Goubier <Thierry.Goubier@enst-bretagne.fr> To: squeak@create.ucsb.edu Subject: File out with shared pools Hello all, Trying to file out with squeak (1.19d), I find something which looked like an error in the code to file out a shared pool variable. I corrected it with the following, changing an 'asSortedCollection do:' with 'associationsDo:'. 'From Squeak 1.19d of April 13, 1997 on 28 May 1997 at 1:26:05 pm'! !Class methodsFor: 'fileIn/Out'! fileOutPool: aPool onFileStream: aFileStream | aPoolName | aPoolName _ Smalltalk keyAtValue: aPool. Transcript cr; show: aPoolName. aFileStream nextPutAll: 'Transcript show: ''' , aPoolName , '''; cr!!'; cr. aFileStream nextPutAll: 'Smalltalk at: #' , aPoolName , ' put: Dictionary new!!'; cr. aPool associationsDo: [ :anItem | aFileStream nextPutAll: aPoolName , ' at: #' , anItem key asString , ' put: '. (anItem value isKindOf: Number) ifTrue: [anItem value printOn: aFileStream] ifFalse: [aFileStream nextPutAll: '('. anItem value printOn: aFileStream. aFileStream nextPutAll: ')']. aFileStream nextPutAll: '!!'; cr]. aFileStream cr! ! ___________________Thierry.Goubier@enst-bretagne.fr__________________ But to look for heaven is to live here in hell [Sting] http://www-info.enst-bretagne.fr/~goubier/

Post a reply.

Go back to index.



Date: 97 May 28 12:18:32 pm From: "David N. Smith" <dnsmith@watson.ibm.com> To: Dan Ingalls <DanI@wdi.disney.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <v0300781cafafac2fcbbf@[206.16.10.79]> Subject: Re: Profiler & Messed up windows At 18:11 -0400 5/26/97, Dan Ingalls wrote: >>All: >> >>I used the profiler in squeak for the first time today and: >> >>(1) it worked and I got useful results, but >> >>(2) it left the windowing system in a real mess. > > ...SNIP... >David, by all means let me know again if you experience this behavior with >well-terminated profiles. > > - Dan Dan: I must have tried to stop the profiler. I can reproduce the mess by stopping it and not otherwise. Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 28 1:31:56 pm From: "David N. Smith" <dnsmith@watson.ibm.com> To: Jean Francois Veillette <jfv@hasc.com> Cc: squeak@create.ucsb.edu In-Reply-To: <199705281241.IAA16911@karm.hasc.com> Subject: Re: Problem with BlockContext. (SYSTEM BUGS FOUND) At 8:41 -0400 5/28/97, Jean Francois Veillette wrote: >Sorry if it's a beginner question, but I am. > >Why the following code doesn't work ? > >| fib | >fib := [:va | va == 1 ifFalse:[ ^ va + ( fib value:va - 1)]. > ^ 1.]. >fib value:5 > > >I'm running it in workspace and squeak finish with a "Message not >understood: *" error, >why ? > >Thank's ! > >- jfv > >Jean-Francois Veillette I think there are four problems here: * Blocks are not closures in Squeak, so the variable va is 'global' to the method. * Squeak doesn't support recursive block invocations (I suspect). * You don't want to use returns. (See below). * Your algorithm has a bug. You don't want to use a return since a return from a block returns from the method and you don't want to do that. You really wanted something like this (which runs fine on IBM Smalltalk and answers 15, though that's not right): | fib | fib := [:va | va == 1 ifTrue: [ 1 ] ifFalse:[ va + ( fib value: va - 1)] ]. fib value:5 15 This produces the correct answer: | fib | fib := [:va | va < 3 ifTrue: [ 1 ] ifFalse:[ (fib value: va - 2) + ( fib value: va - 1)] ]. fib value: 5 5 I tried to rewrite your code to eliminate returns and then show what it really does with the local variable: | fib va | fib := [ va == 1 ifTrue: [ 1 ] ifFalse:[ va := va - 1. fib value. va := va + va ] ]. va := 5. fib value This isn't quie right but it causes Squeak to get a system error (on my PPC 9500 with MacOS 7.5.5) and takes MacOS down. I quit trying! :-) This still doesn't answer what your code is doing (though I get a plus operator, not a multiplication). I suspect that Squeak doesn't allow recursive invocations of blocks either, though someone who knows might let us know. I also found a bug in the debugger with your code: when I ask for a full stack there is no thumb in the scroll bar. This simply means that there are too many stack levels (though the debugger is wrong). It looks like the code is in an infinite loop and dies a strange death. Welcome to Smalltalk! Not all first encounters are like this. :-) Fib is better implemented as a method. This one returns one term of the series: fibonacci " Answer the self'th fibonacci number: 5 fibonacci " self < 3 ifTrue: [ ^ 1 ]. ^ (self - 1) fibonacci + (self - 2) fibonacci Trying it: 4 fibonacci 3 Then I used #collect: to get a series (1 to: 20) collect: [ : term | term fibonacci ] (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 ) Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 28 2:33:11 pm From: Dan Ingalls <DanI@wdi.disney.com> To: "David N. Smith" <dnsmith@watson.ibm.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <v03102800afb2418056cc@[129.34.225.178]> Subject: Re: Problem with BlockContext. (SYSTEM BUGS FOUND) > | fib va | > fib :=3D [ va =3D=3D 1 > ifTrue: [ 1 ] > ifFalse:[ va :=3D va - 1. fib value. va :=3D va + va ] ]. > va :=3D 5. > fib value > >This isn't quie right but it causes Squeak to get a system error (on my PPC >9500 with MacOS 7.5.5) and takes MacOS down. I quit trying! :-) Just to let you know, this problem was reported by the folks at Interval,= and has been fixed in our working VM and image, and thus will be in the= next release. [The code to fix it is in my "Three fileIns" message of May= 12, but it requires building a new VM]. I ran your example here and it= gave a well-behaved interrupt with the message "Attempt to evaluate a block= that is already active".

Post a reply.

Go back to index.



Date: 97 May 28 8:41:55 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: RE: Problem with BlockContext. (SYSTEM BUGS FOUND) David N. Smith wrote >Fib is better implemented as a method. This one returns one term of the = series: > > fibonacci > " Answer the self'th fibonacci number: 5 fibonacci " > self < 3 ifTrue: [ ^ 1 ]. > ^ (self - 1) fibonacci + (self - 2) fibonacci Dave, your explanation was so clear that I think it would be nice to = note something interesting about this recursive implementation of = #fibonacci. Let me compare the recursive implementation with the following iterative = version: #iterativeFibonacci | prev actual swap | self < 2 ifTrue: [^self]. prev _ 0. actual _ 1. self - 1 timesRepeat: [ swap _ actual. actual _ actual + prev. prev _ swap]. ^actual The two methods are equivalent in the sense that both answer the same = Fibonacci numbers. The recursive version looks simpler than the = iterative. But, if we look at the speed of calculation, we obtain = serious differences: Dividing the speed (time) of evaluation of [n fibonacci] by the speed of = evaluation of [n iterativeFibonacci], one obtains something like this n Relative speed 10 8=20 20 470 30 40000 (forty thousand) 35 400000 (four houndred thousand) Thus, if [30 iterativeFibonacci] takes, say, 1 millisecond to evaluate, = then [30 fibonacci] takes about 40 seconds. The recursive Fibonacci is so slow that it makes no sense to use it. In = fact, for relative small integers all the time of the Universe, counted = from the Big Bang, is not enough to perform the recursive evaluation. Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 28 8:41:51 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: RE: [Windows] arrow keys Maloney wrote > Hmm. I think someone fixed the arrow keys; check the mail archive. > I'm not sure Home, End, Page Up and Page Down have ever worked. But > it's probably not too hard to add them yourself... :-> My copy of the VM was old. With a newer version now I have the keys working. Thank you. > Thanks for all the fraction code suggestions, by the way. It was funny to do that! Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 28 8:41:59 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: RE: [Windows] arrow keys Andreas Raab wrote > If these values are not correct you should try a newer VM version > (from the 1.19 directory). Thank you! With the newer VM the arrow, home and end keys begun to work fine. Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 29 5:51:04 am From: Jean Francois Veillette <jfv@hasc.com> To: squeak@create.ucsb.edu In-Reply-To: <v03102800afb2418056cc@[129.34.225.178]> from "David N. Smith" at May 28, 97 04:59:05 pm Subject: Re: Problem with BlockContext. (SYSTEM BUGS FOUND) The code fragment suggested that I was trying to implement fibonacci, but I wasn't. I was just currious about block recursion, and wrote a small example about it. > I think there are four problems here: > * Blocks are not closures in Squeak, so the variable va is 'global' to the method. > * Squeak doesn't support recursive block invocations (I suspect). > * You don't want to use returns. (See below). > You don't want to use a return since a return from a block returns from the > method and you don't want to do that. You really wanted something like this > (which runs fine on IBM Smalltalk and answers 15, though that's not right): thank's for all those precision information, - jfv

Post a reply.

Go back to index.



Date: 97 May 29 8:37:29 am From: Joel Lucuik <Joel@ObjectPeople.com> To: Squeak@create.ucsb.edu Subject: Squeak on Hand-held machine Someone spoke a while ago about a port of squeak to, I think, the Casseopeia (or maybe it was another hand-held machine). Was the port successful? What were the memory requirements? How stripped down was the base system? What base classes where included? Joel

Post a reply.

Go back to index.



Date: 97 May 29 8:37:31 am From: "David N. Smith" <dnsmith@watson.ibm.com> To: Leandro Caniglia <caniglia@mate.dm.uba.ar> Cc: "'Squeak'" <squeak@create.ucsb.edu> In-Reply-To: <01BC6BCD.169480B0@ts1-bsas-linea12.microstar.com.ar> Subject: RE: Problem with BlockContext. (SYSTEM BUGS FOUND) At 21:06 -0400 5/28/97, Leandro Caniglia wrote: >David N. Smith wrote > >>Fib is better implemented as a method. This one returns one term of the >>series: >> >> fibonacci >> " Answer the self'th fibonacci number: 5 fibonacci " >> self < 3 ifTrue: [ ^ 1 ]. >> ^ (self - 1) fibonacci + (self - 2) fibonacci > >Dave, your explanation was so clear that I think it would be nice to note >something interesting about this recursive implementation of #fibonacci. > >Let me compare the recursive implementation with the following iterative >version: > >#iterativeFibonacci > | prev actual swap | > self < 2 ifTrue: [^self]. > prev _ 0. > actual _ 1. > self - 1 timesRepeat: [ > swap _ actual. > actual _ actual + prev. > prev _ swap]. > ^actual > >The two methods are equivalent in the sense that both answer the same >Fibonacci numbers. The recursive version looks simpler than the iterative. >But, if we look at the speed of calculation, we obtain serious differences: > >Dividing the speed (time) of evaluation of [n fibonacci] by the speed of >evaluation of [n iterativeFibonacci], one obtains something like this > > n Relative speed > 10 8 > 20 470 > 30 40000 (forty thousand) > 35 400000 (four houndred thousand) > >Thus, if [30 iterativeFibonacci] takes, say, 1 millisecond to evaluate, >then [30 fibonacci] takes about 40 seconds. > >The recursive Fibonacci is so slow that it makes no sense to use it. In >fact, for relative small integers all the time of the Universe, counted >>from the Big Bang, is not enough to perform the recursive evaluation. > >Saludos, >Leandro I agree and I should have noted that. Aa an aside, an example in my IBM Smalltalk book uses inject:into: to compute the fibonacci series. It takes 6534 ms (PPC 9500/200) to compute the first 5000 terms. I wrote it as an example of injecting something besides a zero! | nterms | nterms := 50. ^ (3 to: nterms) inject: (OrderedCollection with: 1 with: 1) into: [ :inj :n | inj addLast: ( (inj at: n - 2) + (inj at: n - 1) ); yourself ] OrderedCollection (1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597 2584 4181 6765 10946 17711 28657 46368 75025 121393 196418 317811 514229 832040 1346269 2178309 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155 165580141 267914296 433494437 701408733 1134903170 1836311903 2971215073 4807526976 7778742049 12586269025 ) Interestingly, yours takes 6150 ms to compute the 5000th term, making them quite similar; actually surprisingly similar. I expected the inject:into: to be slower, and the growing of the ordered collection to take more time. (VW 2.5 takes 484 ms on the same machine.) Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 29 10:46:44 am From: Dan Ingalls <DanI@wdi.disney.com> To: Joel Lucuik <Joel@objectpeople.com> Cc: Squeak@create.ucsb.edu In-Reply-To: <3.0.32.19970529120548.0090e100@mail.ObjectPeople.com> Subject: Re: Squeak on Hand-held machine >Someone spoke a while ago about a port of squeak to, I think, the >Casseopeia (or maybe it was another hand-held machine). Yes, it was the Cassiopeia >Was the port successful? In my opinion, yes. It was done by Blair McGlashen. At the time he still= needed permission to release it, and was going to bring it forward to 1.19.= I think he has been too busy to do that. However, I have been running an= early 1.19 image on his 1.18 interprter, and it works fine. >What were the memory requirements? I've forgotten exactly. The image is about 600k, and the interpreter about= 200k and when I ask for spaceLeft, I get 470k bytes (on a 4M Casio). >How stripped down was the base system? >What base classes where included? See the quote below from my message of April 14. - Dan ------------------------------------------------ The result is a 644k image which exhibits every normal aspect of Squeak --= all flavors of code browsers, compiler, text editor with fancy fonts and= lots of commands, debugger, inspectors, single-step bytecode simulation,= MessageTally time and counts, Floats and LargeIntegers, full color support,= WarpBlt and Turtle demos. What is more, that 644k includes my magic= sources facility, which will gladly cough up some 820k of readable source= code out of those same bits. I remember saying last year that, when we got a chance, we would put out a= Squeak that would run in one megabyte, including the VM. Voila! - Dan [What is NOT there, you ask? The interpreter anc C translator, music, and= change sorters, the formEditor and character recognizer, projects and the= ClairVaux font set, as well as all comments and class organizations. = However, full comments and organization are retained for code that you= subsequently fileIn or write in the system, and all changes file facilities= are still there, including browsing of old versions]

Post a reply.

Go back to index.



Date: 97 May 29 12:55:41 pm From: Travis Griggs <tgriggs@keyww.com> To: "Squeak@create.ucsb.edu" <Squeak@create.ucsb.edu> Subject: RE: Squeak on Hand-held machine >Someone spoke a while ago about a port of squeak to, I think, the >Casseopeia (or maybe it was another hand-held machine). Yes, it was the Cassiopeia >Was the port successful? In my opinion, yes. It was done by Blair McGlashen. At the time he = still needed permission to release it, and was going to bring it forward = to 1.19. I think he has been too busy to do that. However, I have = been running an early 1.19 image on his 1.18 interprter, and it works = fine. >What were the memory requirements? I've forgotten exactly. The image is about 600k, and the interpreter = about 200k and when I ask for spaceLeft, I get 470k bytes (on a 4M = Casio). >How stripped down was the base system? >What base classes where included? Does this mean that squeak could be ported to an E-mate 300? Hmm.... Travis Griggs KeyTechnology

Post a reply.

Go back to index.



Date: 97 May 29 1:15:52 pm From: Maloney <johnm@wdi.disney.com> To: Leandro Caniglia <caniglia@mate.dm.uba.ar> Cc: squeak@create.ucsb.edu In-Reply-To: <01BC6BCD.169480B0@ts1-bsas-linea12.microstar.com.ar> Subject: RE: Problem with BlockContext The recursive fibonacci function is so message-send bound that it is often used as a benchmark of message sending (or procedure calling). Even in C, the arithmetic performed is trivial compared to the cost of the two recursive calls. You'd see a similar ever-widening gap between the iterative and recursive versions in any Smalltalk implementation. (And most other languages as well, I believe.) So, if you need high performance, you'd use the iterative version. However, the recursive version is nice for demonstrating the elegance of recursion. -- John At 1:06 AM +0000 5/29/97, Leandro Caniglia wrote: >Let me compare the recursive implementation with the following iterative version: > >#iterativeFibonacci > | prev actual swap | > self < 2 ifTrue: [^self]. > prev _ 0. > actual _ 1. > self - 1 timesRepeat: [ > swap _ actual. > actual _ actual + prev. > prev _ swap]. > ^actual > >The two methods are equivalent in the sense that both answer the same Fibonacci numbers. The recursive version looks simpler than the iterative. But, if we look at the speed of calculation, we obtain serious differences: > >Dividing the speed (time) of evaluation of [n fibonacci] by the speed of evaluation of [n iterativeFibonacci], one obtains something like this > > n Relative speed > 10 8 > 20 470 > 30 40000 (forty thousand) > 35 400000 (four houndred thousand) > >Thus, if [30 iterativeFibonacci] takes, say, 1 millisecond to evaluate, then [30 fibonacci] takes about 40 seconds.

Post a reply.

Go back to index.



Date: 97 May 30 2:33:40 am From: "Andreas Raab" <raab@isg.cs.uni-magdeburg.de> To: squeak@create.ucsb.edu Subject: Teaching Smalltalk Hello Smalltalkers, I need some help to defend "the honour of Smalltalk". We're using ST (Squeak,VW) for our students in the Computational Visualistics program. Now, there has been rumour not to use ST anymore but instead C. The main arguments were that ST would be "to complicated" the students would not "get much better" and things like that. I personally completely disagree with the above. However, I'd be interested in collecting arguments pro ST. In particular, I'm looking for any published studies, comparing the performance of beginners when using procedural (i.e. C,Pascal) or object-oriented programming. What I'm looking for are studies discussing the differences in a way like * What did people achive after using this programming language * What time was needed to achieve comparable results * How well could people describe what they'd done and things like that. I'd be happy if you could point me to any literature. Thanks, Andreas -- Linear algebra is your friend - Trigonometry is your enemy. +===== Andreas Raab ============= (raab@isg.cs.uni-magdeburg.de) =====+ I Department of Simulation and Graphics Phone: +49 391 671 8065 I I University of Magdeburg, Germany Fax: +49 391 671 1164 I +=============< http://simsrv.cs.uni-magdeburg.de/~raab >=============+

Post a reply.

Go back to index.



Date: 97 May 30 6:05:00 am From: Aaron Rosenzweig <recurve@xombi.wizard.net> To: "Andreas Raab" <raab@isgnw.cs.Uni-Magdeburg.DE> Cc: squeak@create.ucsb.edu Subject: Re: Teaching Smalltalk The Technical University of Nova Scotia (TUNS) I think the url is http://www.tuns.edu/ As I understand it they did a lot of research in how people learn to program and what sorts of things were important in programming. Ultimately "Prograph" came out of their work. I'd say they're worth talking to. I haven't done it yet but I plan on contacting them myself as well. --- SW Son of Ginger and Harry, Aaron Rosenzweig SW http://www.wam.umd.edu/~recurve/ SW... recurve@resourceful.com SWN?

Post a reply.

Go back to index.



Date: 97 May 30 6:06:52 am From: Aaron Rosenzweig <recurve@xombi.wizard.net> To: "Andreas Raab" <raab@isgnw.cs.Uni-Magdeburg.DE> Cc: squeak@create.ucsb.edu Subject: Re: Teaching Smalltalk Sorry, it's: http://www.tuns.ca/ For some reason I have the following url in OmniWeb's bookmarks: http://www.tuns.ca/~gradwww/research.html It might get more specific for what you want faster. --- SW Son of Ginger and Harry, Aaron Rosenzweig SW http://www.wam.umd.edu/~recurve/ SW... recurve@resourceful.com SWN?

Post a reply.

Go back to index.



Date: 97 May 30 7:04:57 am From: Tansel <tansel@rase.com> To: Andreas Raab <raab@isgnw.cs.Uni-Magdeburg.DE> Cc: squeak@create.ucsb.edu Subject: Re: Teaching Smalltalk Andreas Raab wrote: > > Hello Smalltalkers, > > I need some help to defend "the honour of Smalltalk". We're using ST > (Squeak,VW) for our students in the Computational Visualistics > program. Now, there has been rumour not to use ST anymore but instead C. > The main arguments were that ST would be "to complicated" the > students would not "get much better" and things like that. > > I personally completely disagree with the above. However, I'd be > interested in collecting arguments pro ST. In particular, I'm looking > for any published studies, comparing the performance of beginners when > using procedural (i.e. C,Pascal) or object-oriented programming. What > I'm looking for are studies discussing the differences in a way like > * What did people achive after using this programming language > * What time was needed to achieve comparable results > * How well could people describe what they'd done > and things like that. > > I'd be happy if you could point me to any literature. > Thanks, > Andreas > -- Andreas, I had posted some material on the net a few months ago about the state of OO in general. Parts of that may be relevant. The URL for the pages is : http://www.rase.com/oodebate/ more relevant pages may be http://www.rase.com/oodebate/history.htm http://www.rase.com/oodebate/choices.htm By the way, does anyone do any work on Squeak with FPGAs? Tansel ----------------------------------------------------------------------- RASE Inc. New York NY USA Voice: (212) 431 5069 mailto:tansel@rase.com Fax: (212) 334 1846 http://www.rase.com/ ----Sufficiently advanced technology is indistinguishable from magic--- -------------------------------A.C. Clarke-----------------------------

Post a reply.

Go back to index.



Date: 97 May 30 8:12:41 am From: guzdial@cc.gatech.edu (Mark Guzdial) To: "Andreas Raab" <raab@isgnw.cs.Uni-Magdeburg.DE> Cc: squeak@create.ucsb.edu Subject: Re: Teaching Smalltalk >In particular, I'm looking >for any published studies, comparing the performance of beginners when >using procedural (i.e. C,Pascal) or object-oriented programming. What >I'm looking for are studies discussing the differences in a way like >* What did people achive after using this programming language >* What time was needed to achieve comparable results >* How well could people describe what they'd done >and things like that. In general, this is comparing apples-and-oranges. You can only make this comparison if you can somehow equivalence the experience of programming procedural and object-oriented programming language: The *ONLY* difference is the kind of programming. But you can't do that -- if you switch paradigms, you switch *EVERYTHING*: The way you analyze, the way you design, the kinds of tools you use, the syntax of the language, etc. Similarly, researchers in education have given up on making these kinds of comparisons with respect to media: Is there a difference between teaching with video and teaching with text? Yes, because you teach *DIFFERENT* things with video than with text -- they're not equivalent. If you want to make this argument (that the answer to the question is "Mu" -- the question makes no sense), the papers to reference are: Kozma, R. (1993). Will media influence learning? Reframing the debate. Educational Technology Research and Development. Kozma, R. B. (1991). Learning with media. Review of Educational Research, 61(2), 179-211. That said, people have tried to make the argument that O-O more naturally meshes with the way that we think about the world. The best paper that I know on that is: Rosson, M. B., & Alpert, S. R. (1990). The cognitive consequences of object-oriented design. Human-Computer Interaction, 5, 345-379. ON THE OTHER HAND (it's good to know what ammunition the other side might use), there are things that we know are really hard to learn in O-O and Smalltalk: * Students have a really tough time with class/instance distinctions. Carroll & Rosson talk about this some in their work with Smalltalk: Carroll, J. M., Singer, J. A., Bellamy, R. K. E., & Alpert, S. R. (1990). A View Matcher for learning Smalltalk. In J. C. Chew & J. Whiteside (Eds.), Proceedings of CHI'90: Human Factors in Computing Systems (Vol. Seattle, April 1-5, pp. 431-437). New York: ACM Press. Rosson, M. B., Carroll, J. M., & Sweeney, C. (1991, ). Demonstrating a view matcher for reusing Smalltalk classes. Paper presented at the CHI'91: ACM Conference on Human Factors in Computing Systems, New Orleans. Rosson, M. B., Carroll, J. M., & Sweeney, C. (1991). A View Matcher for reusing Smalltalk classes. In S. P. Robertson, G. M. Olson, & J. S. Olson (Eds.), Proceedings of CHI'91: Human Factors in Computing Systems (Vol. New Orleans, April 27-May 2, pp. 277-283). New York: ACM Press. * Students have a really tough time with interactions between objects. Mitchel Resnick of MIT described this in his MultiLogo paper (appeared in Journal of the Learning Sciences, but I don't have the ref. at hand), and he and Michael Eisenberg (at U. Colorado-Boulder) wrote about similar problems of students moving from a functional to an O-O perspective in one of the Empirical Studies of Programmer's Workshops. * Students have a tough time distributing responsibility -- that's the reason why many C++ programs are actually one huge class. Mitchel called this the "centralized mindset" and I found that the characteristics he described were also common to my Smalltalk students. Guzdial, M. (1995). Centralized mindset: A student problem with object-oriented programming, ACM SIGCSE Technical Symposium 1995 (pp. 182-185). New York: ACM Press. Finally, I just had a paper accepted to the OOPSLA Educators' Symposium on the work I'm doing in my Smalltalk classes to address problems in learning O-O. I've got a version of that paper linked to my papers page: http://guzdial.cc.gatech.edu/papers/ Mark -------------------------- Mark Guzdial : Georgia Tech : College of Computing : Atlanta, GA 30332-0280 (404) 894-5618 : Fax (404) 894-0673 : guzdial@cc.gatech.edu http://www.cc.gatech.edu/gvu/people/Faculty/Mark.Guzdial.html

Post a reply.

Go back to index.



Date: 97 May 30 9:51:16 am From: johnson@cs.uiuc.edu (Ralph E. Johnson) To: "Andreas Raab" <raab@isgnw.cs.Uni-Magdeburg.DE>, squeak@create.ucsb.edu Subject: Re: Teaching Smalltalk The place with the most experience teaching Smalltalk as an intro language is Carleton University. Their experience is completely positive. They think it is much, much better than C as an intro language. I think they teach Smalltalk first, C second. Talk to John Pugh <70524.3613@CompuServe.COM> about it. He was one of the ones who started Smalltalk at Carleton, and was head of the deparment for a while, but now mostly does consulting. He started the Object People, which is a successful company and so takes a lot of time. -Ralph

Post a reply.

Go back to index.



Date: 97 May 30 3:09:45 pm From: "David N. Smith" <dnsmith@watson.ibm.com> To: lnotarfr@dc.uba.ar (Luciano Esteban Notarfrancesco) Cc: squeak@create.ucsb.edu In-Reply-To: <m0wWHVv-000j1uC@milagro.dc.uba.ar> Subject: Re: degreeSin At 4:21 -0400 5/27/97, Luciano Esteban Notarfrancesco wrote: >Integer implements > >degreeSin > ^self asFloat degreesToRadians sin >! > >but this fails for big integers. >It's better to do: > >degreeSin > ^(self \\ 360) asFloat degreesToRadians sin >! > >Furthermore, I saw that sqrt is not reimplemented in Integer, but it >should be ("anInteger squared sqrt" must answer "anInteger"). > >Regards, > --- Luciano. The problem with large integers seems to be overflow. If the number of bits in the integer is greater than the exponent size then the answer becomes 1.0000000000000e400 and further operations answer the same value. This value is not a valid fp number and causes all sorts of trouble when Squeak tries to operate on it. I have a workaround which checks the size of the integer first before trying to convert it. It is not perfect in that there are a few integers that could convert which this won't convert, but they are all within a few bits of failing. There is room for improvement since the high order byte might have unused bits. The algorithm below assumes all bits are used. Thus, it computes size*8 as the number of bits (and thus the exponent size) but a better solution is (size-1)*8 and then add the position of the left most bit in the high order word. This algorithm is probably good enough. There is a new variable, size, and three new lines, starting with the first reference to size. asFloat2 "Answer a Float that represents the value of the receiver. Integers that are too big to convert to a IEEE double raise an error. IEEE doubles will hold integers up to about 308 decimal digits." | factor sum size | sum _ 0.0. factor _ self sign asFloat. size := self size. size * 8 > 1022 ifTrue: [ self error: 'Integer too large to convert to Float' ]. 1 to: size do: [:i | sum _ (self digitAt: i) * factor + sum. factor _ factor * 256.0]. ^sum Tests: the first one works and the second one fails. ( 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 ) asFloat2 ( 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 * 12765127651287651287651287651287651287651287652187656854 ) asFloat2 Testing the limits by computing a value (alternating 1 and 0 bits) which will just barely convert using asFloat: | bi n | n := 0. bi := 1. [n <= 1022 ] whileTrue: [ n := n + 1. bi := (bi<<1) bitOr: (n bitAnd: 1) ]. bi asFloat 1.49807761238524e308 In hex (my printHex method): '1.AAAAAAAAAAAABe3FF' Dave _______________________________ David N. Smith IBM T J Watson Research Center Hawthorne, NY _______________________________ Any opinions or recommendations herein are those of the author and not of his employer.

Post a reply.

Go back to index.



Date: 97 May 30 5:54:21 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: RE: Teaching Smalltalk Andreas Raab wrote > I need some help to defend "the honour of Smalltalk". Ten suggestions for the Smalltalk defender* 1. Transmit your own enthusiasm, not only your arguments. 2. Do not communicate only abstract concepts. In Smalltalk it is easy to = find surprising examples related to the interest of your audience. = Improvise a simple model and demonstrate how it works. 3. Do no fix your arguments in the facilities of learning Smalltalk, but = in the possibilities of a Smalltalker. 4. Have at hand some successful experiences on actual projects known to = you. 5. Take the point of view of someone that wants to diffuse, not to = convince. 6. Do not forget that the conceptual simplicity of Smalltalk does not = make it easy. All the Euclidean Geometry is built up from only 5 simple = axioms, it is clear an beautiful but it is not easy. 7. Give examples on how Smalltalk has influenced other programming = languages. 8. Cite names, places and dates. Smalltalk has a rich history. 9. Tell about bibliography, user groups, Internet lists and other = activities that you know. Invite your audience to participate. 10. Open your clothes and show the Smalltalk logo stamped in your = T-shirt :-) Saldudos, Leandro ----------- *translations to good English are welcome

Post a reply.

Go back to index.



Date: 97 May 31 9:55:13 am From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: On the #gcd: method Hi! I have some remarks on the #gcd: method in the Integer class: 1. [anInteger gcd: 0] and [0 gcd: anInteger] give a division by 0 error = message when they should answer [anInteger abs]. (This may be considered = a bug). 2. The method begins with this code: m _ self abs max: anInteger abs. n _ self abs min: anInteger abs. m \\ n =3D 0 ifTrue: [^n]. "easy test, speeds up rest" but it is better not to forget the remainder m \\ n once it has been = computed. Instead, one can write: n _ self abs max: anInteger abs. m _ self abs min: anInteger abs. (n _ m \\ m) =3D 0 ifTrue: [^m]. "easy test, speeds up rest" saving the remainder and replacing with it the maximum of the two = original values. (Note the swap between n and m). This is not suggested = by me but by Knuth in the same pages of Vol 2 where the binary algorithm = used en Squeak is explained. 3. The proofs I've made in Squeak show that this remainder-saving = version is a 15% faster than the "forgeting" one. 4. Taking into account the "bug" and the saving one should modify the = begining of the #gcd: method with: n _ self abs max: anInteger abs. m _ self abs min: anInteger abs. m =3D 0 ifTrue: [^n]. (n _ m \\ m) =3D 0 ifTrue: [^m]. "easy test, speeds up rest" {the original code follows} Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 31 1:11:40 pm From: Jecel Assumpcao Jr <jecel@lsi.usp.br> To: squeak@create.ucsb.edu Subject: Re: Teaching Smalltalk Ralph E. Johnson wrote: > > The place with the most experience teaching Smalltalk as an intro > language is Carleton University. Their experience is completely > positive. They think it is much, much better than C as an intro > language. I think they teach Smalltalk first, C second. > > Talk to John Pugh <70524.3613@CompuServe.COM> about it. He was > one of the ones who started Smalltalk at Carleton, and was head > of the deparment for a while, but now mostly does consulting. > He started the Object People, which is a successful company and > so takes a lot of time. There was an article about this in the Nov/Dec 1990 Journal of Object Oriented Programming (JOOP) ( Vol 3 No 4 ). I can't find it right now as things around here are a bit messy, but I will summarize what they said: The introduction to programming course became more enjoyable due to the ability to use various data structure objects (collections, mainly) as black boxes - this allowed less trivial programming exercises to be attempted. These black boxed would be opened in the second year in the Data Structure course. One side effect from the move from Pascal to Smalltalk was that the students with previous experience in programming paid more attention because the language was as new to them as to their "novice" classmates. One problem they had with Smalltalk was its integrated nature - even a trivial example might lead (by accident) into an exploration of low level stuff way before the students are ready for it. The instructors found it nearly impossible to break the material down into isolated chunks (special browsers and debuggers can help with this). They used C in the middle of the course as an introduction to computer architecture. Explaining pointers and stuff was a neat way to approach the hardware level. If you (Andreas) can find the article, I really recomend it (though it would be interesting to look at what has happened since then). As for using C to teach, I like to compare it to using a jet fighter to teach how to fly. It is a great way to lose most of your students. C is a great language for what it was designed to do. But having a student figure out that he left out a "*" from that fact that the screen fills up with little purple dots right before locking up is not my idea of a good educational method. -- Jecel

Post a reply.

Go back to index.



Date: 97 May 31 3:22:56 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: RE: Teaching Smalltalk Bert wrote B> LC> Ten suggestions for the Smalltalk defender* B> =20 B> LC> [... nine "serious" points ...] B> LC> 10. Open your clothes and show the Smalltalk logo stamped in your = T-shirt :-) B> I like the 10th most :-) B> By logo I assume you mean the balloon from BYTE cover? But I couldn't = get B> access to it _without_ the BYTE heading. Do you know any source? All = other B> renditions I have seen are, uhmm, rather ugly, I'd say ... Of course, I did meant the BYTE balloon. I don't know any source without = the heading. I have read somewhere in the Net form Ralph Johnson that = "Someone should talk with Robert Tinney about making his cover into a = poster". Probably that poster exists (in such case please don't forget = that I WANT MINE!). At any case, I consider the heading as part of a = testimonial form of art. Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 31 3:23:01 pm From: Leandro Caniglia <caniglia@mate.dm.uba.ar> To: 'Squeak' <squeak@create.ucsb.edu> Subject: RE: On the #gcd: method Ralph E. Jhonson wrote RJ> LC> n _ self abs max: anInteger abs. RJ> LC> m _ self abs min: anInteger abs. RJ> LC> m = 0 ifTrue: [^n]. RJ> LC> (n _ m \\ m) = 0 ifTrue: [^m]. RJ> LC> "easy test, speeds up rest" RJ> LC> {the original code follows} RJ> m \\ m is always 1. Shouldn't that be "n _ n \\ m"? Ralph, you are right. It should be n_ n \\ m. Tanks for your remark! BTW let me note that m \\ m is never 1, it is always 0 ;-) Sorry. I repeat the correct form here gcd: anInteger | n m d | n _ self abs max: anInteger abs. m _ self abs min: anInteger abs. m = 0 ifTrue: [^n]. (n _ n \\ m) = 0 ifTrue: [^m]. "easy test, speeds up rest" {the original code follows} Saludos, Leandro

Post a reply.

Go back to index.



Date: 97 May 31 6:51:25 pm From: Sam Adams <ssadams@us.ibm.com> To: <squeak@create.ucsb.edu> Subject: RE: Smalltalk Ballon.....was Teaching Smalltalk Bert wrote B> LC> Ten suggestions for the Smalltalk defender* B> B> LC> [... nine "serious" points ...] B> LC> 10. Open your clothes and show the Smalltalk logo stamped in your T-shirt :-) B> I like the 10th most :-) B> By logo I assume you mean the balloon from BYTE cover? But I couldn't get B> access to it _without_ the BYTE heading. Do you know any source? All other B> renditions I have seen are, uhmm, rather ugly, I'd say ... Leandro wrote: >Of course, I did meant the BYTE balloon. I don't know any source without the >heading. I have read somewhere in the Net form Ralph Johnson that "Someone >should talk with Robert Tinney about making his cover into a poster". Probably >that poster exists (in such case please don't forget that I WANT MINE!). At any >case, I consider the heading as part of a testimonial form of art. I have an old catalog from Georg Heeg that has a clean image of the Smalltalk balloon on the over. It looks like the original artwork sans BYTE heading. Perhaps they have a source for the art. Anyone over there listening? On the teaching issue, I always found that a little magic was worth a mountain of logic when it came to convincing folks about the value of Smalltalk. Regards, Sam

Post a reply.

Go back to index.



Send mail to the CREATE web master

[Author: Stephen Travis Pope, stp@create.ucsb.edu]
Created: 1996.11.08; LastEditDate: 1996.11.11