More about ifNil: [was: [UPDATES] 30 new...]

Dan Ingalls Dan.Ingalls at disney.com
Mon Feb 7 15:50:28 UTC 2000


Torge -

[First of all, SMA mentioned you are helping to cull contributions for updates.  Thanks for that!]

>Hi SqC,
>I'm really amazed how fast you can answer our needs.
>One Question, though:
>Would it eat up all of the space savings if you just included the
>appropriate symbol out of #(ifNotNil: ifNotNil:ifNilifNil: ifNil:ifNotNil:)
>in the literal frame the way Vassily used to do with his assertions ?!
>It would really help finding the senders if ever anybody would want so.

Yes, it would.  This is a nice hack, and it could certainly be used for ifTrue: and the few other patterns that we compile in-line as well.  One could also write a bytecode scanner (as we do to find, eg, all stores into a given instVar) to find the patterns.  However, IMNSHO, there is hardly any point to it for these constructs (as opposed to assertions) because the only patterns that get compiled in this manner are tantamount to built-in control primitives of the language, and therefore of no real interest as searchable content.

>P.S.: anybody in programmatically rewriting all "..== nil ifTrue:[.." to
>"..ifNil:[.."? ;-)

Interesting that you should ask.  Here follows an internal message that I sent, more to record the results of an hour's investigation than to call for immediate action.

	- D

-------- nerd factor 8 follows ----------
>Date: Sun, 30 Jan 2000 14:42:21 -0800
>To: John, ted, scott, andreas, alex, mike
>From: Dan Ingalls <Dan.Ingalls at disney.com>
>Subject: Report from the Type Police
>
>Hi, guys -
>
>I spent some time this weekend getting ifNil: and its variants to compile in-line (Andrew Greenberg did most of the work).  This actually works now, although decompiling it turns out to be harder than compiling it, and I haven't finished that yet.  There are 1758 methods that include one or more occurrences of these messages, each of which (the ifNil: messages) will get 3 to 8 times faster!
>
>Along the way, it occurred to me to browse all the methods that might want to use the new construct.  These include the patterns,
>	foo == nil
>	foo ~~ nil
>	foo = nil
>	foo ~= nil
>I thought you might be interested in my findings...
>
>foo == nil
>There are 829 methods with this pattern.  It is efficient as it stands, so there's not much reason to rewrite it unless you prefer ifNil: as the way to test this.
>
>foo ~~ nil
>There are 186 methods with this pattern.  These will all run much faster and be more compact if converted to ifNil:/ifNotNil: tests.
>
>foo = nil, foo ~= nil
>There are 85 and 21 methods with these patterns respectively.  Worse than cosmetic problems, many of these are basically type violations.  They run slowly, since they look up = in Object, and they will cause errors if their recievers ever happen to be numbers.  I realize that a number of these examples are in SLANG code, wherein comparison of oops must use = since they may be LargeInts for which == will not work.  Except for the SLANG cases, these should all be converted to ifNil:/ifNotNil:, or at least to ==.
>
>foo == number, foo ~~ number
>In passing, I noticed several of these.  I just want to remind everyone that == and ~~ should NEVER be used for arithmetic comparison.  Neither will give correct results with LargeInts, and ~~ will be much slower whether it is delivering correct results or not.
>
>
>I wound up deciding not to tackle the cleanup job right now.  I think I'll assemble some automatic tools and maybe run them just before a release when there won't be such a large chance of overlap with other changes.  But meantime, you can all help with any future changes or additions until then.
>
>Thanks
>	- Dan
>
>PS:  If this stuff interests you, I found '~~ nil' (and the same without a space -- there are only 3) by searching the sources.  The other three patterns are found by the following method which can be edited in the obvious manner to only find one at a time.
>-----------------
>!Compiler class methodsFor: 'accessing' stamp: 'di 1/30/2000 13:19'!
>browseIfNilCandidates  "Compiler browseIfNilCandidates"
>	"Get the rest by source searches for '~~nil' and '~~ nil' "
>
>	| scanner |
>	Smalltalk browseAllSelect:
>		[:cm |
>		scanner _ InstructionStream on: cm.
>		scanner scanFor: [:instr | instr = 115 "push nil" and: [#(182 "=" 183 "~=" "198 "==") includes: scanner followingByte]]]! !






More information about the Squeak-dev mailing list