When is ##() used?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

When is ##() used?

Costas Menico
I am trying to understand the purpose of ##().  I can't find any
documentation for it.

I tried

x :=##(Transcript show: 'xxx')  

and

x :=Transcript show: 'xxx'

To me it looks like they do the same thing. Why would one use one over
the other?

Any help is appreciated.

Costas Menico


Reply | Threaded
Open this post in threaded view
|

Re: When is ##() used?

Ian Bartholomew
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


Reply | Threaded
Open this post in threaded view
|

Re: When is ##() used?

Costas Menico
>
>S := 'xxx'.
>
>and then explain (to yourself) why the following prints 'xxx'
>
>S := 'yyy'.
>##(Transcript nextPutAll: S; cr)


Ian thanks for this excellent explanation of ##() (as well as the
prior explanation of ASCII codes.)

Perl has a similar concept to execute code at compile time.  It makes
for some interesting programming.

Here is a fun one.

S:=1.

3 timesRepeat: [S :=S+1.
##(Transcript nextPutAll: S printString; cr)]

Not only it doesn't print 3 times but the Transcript shows 1.

Costas