Costas,
"Costas Menico" <
[hidden email]> wrote in message
news:
[hidden email]...
> I am trying to understand the purpose of ##(). I can't find any
> documentation for it.
[..]
> To me it looks like they do the same thing. Why would one use one over
> the other?
##() indicates that the expression within the brackets should be evaluated
when the statement is compiled and (in effect) replaced with a literal value
representing that result.
So, evaluating
Time millisecondsToRun: [1000 timesRepeat: [1234 factorial * 5]]
takes 8403 mS on my machine - not surprising as 1234 factorial * 5 is
calculated 1000 times. On the other hand
Time millisecondsToRun: [1000 timesRepeat: [##(1234 factorial) * 5]]
takes 12 mS to complete. When the code is compiled (when you execute doIt)
1234 factorial is calculated once and the result inserted in the block in
it's place . The timed code is then effectively
Time millisecondsToRun: [1000 timesRepeat: ["aBigNumber" * 5]]
which is obviously much quicker.
Note that I could have put the whole expression inside the brackets ##(1234
factorial * 5) but then the example above always evaluates in 0 mS which
isn't very instructive <g>
When to use ##()
- Optimising constants. As above, a _constant_ expression evaluated once at
compile time obviously takes less time than one evaluated n times at run
time.
- Dolphin uses it a lot for defining constants e.g. self state: ##(XY_BLUE |
XY_LARGE). As well as the performance boost it, arguably, clarifies the fact
that the expression is a constant.
- Defining tables. Rather than initialising a _constant_ table and storing
it in a variable of some sort it is sometime clearer to create the table at
compile time
When you can't use ##()
- When any of the components are not constant. e.g. ratio := ##(self view
extent / self itemCount) would not make sense. The return values are only
valid at run time and the ##() expression would probably not compile anyway.
There is one more use of ##() (which revolves around what #self is bound to
when the expression is compiled) which is probably not worth going into
here.
One final thing - a little test <g>. Evaluate the following, creating a
global
S := 'xxx'.
and then explain (to yourself) why the following prints 'xxx'
S := 'yyy'.
##(Transcript nextPutAll: S; cr)
Ian