error trap

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

error trap

Davide Arrigo
hi guys, I want to implement an "error trap" in Squeak, something like "on
error goto:" in other  languages.
When a method encounter an error during execution of a block of code  (an
error like: square root or logarithm of a negative numbers, division by zero
and so on..) I want only a message, send to Transcript, without any dialog
box ask to me if I want to proceed, stop or debug. I wouldn't halt the
program but always proceed automatically with the next block of code
evaluation.
Is it  possible?
Thanks in advance.

--
---------------
Davide Arrigo
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: error trap

Ron Teitelbaum
Hi Davide,

I just wrote up something like this for Sedar:
http://lists.squeakfoundation.org/pipermail/beginners/2006-August/000701.htm
l

To answer your question directly the answer is yes and no.

The easiest way to do what you want is to write your own handler for each
line.  Without doing that you would be counting on an implementation of the
exception.  Not all exceptions are resumable, and it would be difficult to
know what value to resume with that would not cause the error.

For example:

[10/0.
 -5 raisedTo: 1.5.
 2 raisedToInteger: 1/2.
] on: Exception do: [:ex | Transcript show: ex; cr. ex resume: 1].

Look at the exception ZeroDivide and notice that it is written to be
resumable whereas the others are not.  So resume: 1 works for ZeroDivide and
not for the others.

You could use ifError: on BlockContext for each line to do what you want.

[10/0] ifError: [:ex | Transcript cr; show: ex.].
[ -5 raisedTo: 1.5] ifError: [:ex | Transcript cr; show: ex.].
[ 2 raisedToInteger: 1/2] ifError: [:ex | Transcript cr; show: ex.]

If you don't like the amount of extra text on each line you could implement
your behavior on BlockContext (don't tell anyone I said to do this).

BlockContext >> protect
"evaluate the block and print the exception in the transcript if there is an
error"
self ifError: [:ex | Transcript cr; show: ex.].

then you could use:

[10/0] protect.
[ -5 raisedTo: 1.5] protect.
[ 2 raisedToInteger: 1/2] protect.

Notice that this:
[10/0.
 -5 raisedTo: 1.5.
 2 raisedToInteger: 1/2] protect.

Still doesn't work since the block exits on the first error.

The proper way to do this would be to write your own class to extend
BlockContext instead of changing BlockContext itself.

ProtectBlock class>> evaluate: aBlock
        "evaluate the block and print the exception in the transcript if
there is an error"
        aBlock ifError: [:ex | Transcript cr; show: ex.].

But then you have more writing and clutter, but it is more proper since you
are not cluttering up BlockContext with your transcript print code.

ProtectBlock evaluate: [10/0].
ProtectBlock evaluate: [-5 raisedTo: 1.5].
ProtectBlock evaluate: [ 2 raisedToInteger: 1/2].

Hope that helps some,

Happy coding!

Ron Teitelbaum
President / Principal Software Engineer
US Medical Record Specialists
[hidden email]  


> -----Original Message-----
> From: [hidden email] [mailto:beginners-
> [hidden email]] On Behalf Of Davide Arrigo
> Sent: Wednesday, August 09, 2006 9:54 AM
> To: [hidden email]
> Subject: [Newbies] error trap
>
> hi guys, I want to implement an "error trap" in Squeak, something like "on
> error goto:" in other  languages.
> When a method encounter an error during execution of a block of code  (an
> error like: square root or logarithm of a negative numbers, division by
> zero
> and so on..) I want only a message, send to Transcript, without any dialog
> box ask to me if I want to proceed, stop or debug. I wouldn't halt the
> program but always proceed automatically with the next block of code
> evaluation.
> Is it  possible?
> Thanks in advance.
>
> --
> ---------------
> Davide Arrigo
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: error trap

Brian Murphy-Dye-3
Ron, another crazy possibility comes to mind when reading your  
excellent description: making each line it's own block.

{[10/0].
  [2 raisedToInteger: 1/2].
  [-5 raisedTo: 1.5]
} do: [:each | [each value] on: Exception do: [:ex | Transcript show:  
ex; cr]].

Brian.


On Aug 9, 2006, at 12:16 PM, Ron Teitelbaum wrote:

> Hi Davide,
>
> I just wrote up something like this for Sedar:
> http://lists.squeakfoundation.org/pipermail/beginners/2006-August/ 
> 000701.htm
> l
>
> To answer your question directly the answer is yes and no.
>
> The easiest way to do what you want is to write your own handler  
> for each
> line.  Without doing that you would be counting on an  
> implementation of the
> exception.  Not all exceptions are resumable, and it would be  
> difficult to
> know what value to resume with that would not cause the error.
>
> For example:
>
> [10/0.
>  -5 raisedTo: 1.5.
>  2 raisedToInteger: 1/2.
> ] on: Exception do: [:ex | Transcript show: ex; cr. ex resume: 1].
>
> Look at the exception ZeroDivide and notice that it is written to be
> resumable whereas the others are not.  So resume: 1 works for  
> ZeroDivide and
> not for the others.
>
> You could use ifError: on BlockContext for each line to do what you  
> want.
>
> [10/0] ifError: [:ex | Transcript cr; show: ex.].
> [ -5 raisedTo: 1.5] ifError: [:ex | Transcript cr; show: ex.].
> [ 2 raisedToInteger: 1/2] ifError: [:ex | Transcript cr; show: ex.]
>
> If you don't like the amount of extra text on each line you could  
> implement
> your behavior on BlockContext (don't tell anyone I said to do this).
>
> BlockContext >> protect
> "evaluate the block and print the exception in the transcript if  
> there is an
> error"
> self ifError: [:ex | Transcript cr; show: ex.].
>
> then you could use:
>
> [10/0] protect.
> [ -5 raisedTo: 1.5] protect.
> [ 2 raisedToInteger: 1/2] protect.
>
> Notice that this:
> [10/0.
>  -5 raisedTo: 1.5.
>  2 raisedToInteger: 1/2] protect.
>
> Still doesn't work since the block exits on the first error.
>
> The proper way to do this would be to write your own class to extend
> BlockContext instead of changing BlockContext itself.
>
> ProtectBlock class>> evaluate: aBlock
> "evaluate the block and print the exception in the transcript if
> there is an error"
> aBlock ifError: [:ex | Transcript cr; show: ex.].
>
> But then you have more writing and clutter, but it is more proper  
> since you
> are not cluttering up BlockContext with your transcript print code.
>
> ProtectBlock evaluate: [10/0].
> ProtectBlock evaluate: [-5 raisedTo: 1.5].
> ProtectBlock evaluate: [ 2 raisedToInteger: 1/2].
>
> Hope that helps some,
>
> Happy coding!
>
> Ron Teitelbaum
> President / Principal Software Engineer
> US Medical Record Specialists
> [hidden email]
>
>
>> -----Original Message-----
>> From: [hidden email] [mailto:beginners-
>> [hidden email]] On Behalf Of Davide Arrigo
>> Sent: Wednesday, August 09, 2006 9:54 AM
>> To: [hidden email]
>> Subject: [Newbies] error trap
>>
>> hi guys, I want to implement an "error trap" in Squeak, something  
>> like "on
>> error goto:" in other  languages.
>> When a method encounter an error during execution of a block of  
>> code  (an
>> error like: square root or logarithm of a negative numbers,  
>> division by
>> zero
>> and so on..) I want only a message, send to Transcript, without  
>> any dialog
>> box ask to me if I want to proceed, stop or debug. I wouldn't halt  
>> the
>> program but always proceed automatically with the next block of code
>> evaluation.
>> Is it  possible?
>> Thanks in advance.
>>
>> --
>> ---------------
>> Davide Arrigo
>> _______________________________________________
>> Beginners mailing list
>> [hidden email]
>> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners

smime.p7s (3K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: error trap

Klaus D. Witzel
On Wed, 09 Aug 2006 19:59:41 +0200, Brian Murphy-Dye wrote:
> Ron, another crazy possibility comes to mind when reading your
> excellent description: making each line it's own block.
>
> {[10/0].
>   [2 raisedToInteger: 1/2].
>   [-5 raisedTo: 1.5]
> } do: [:each | [each value] on: Exception do: [:ex | Transcript show:
> ex; cr]].

Excellent, Brian. Why do you still write in the beginners list ;-)
...
Ah, now I can see why: Transcript endEntry is missing from the above :)  
</joke>

/Klaus

> Brian.

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: Re: error trap

Ron Teitelbaum
Brian,

Yes I agree it's a great suggestion, although a few changes:
Literal blocks to not parse into collections automatically.

Also the code   [each value] on: ... is very interesting, so I thought I'd
spend a moment on it.

Each in this case is already a block.  It doesn't look like a block so
people sometimes feel the need to encase a block in a block.  This can cause
a lot of problems, when your block doesn't evaluate since aBlock value:
[aBlock] returns aBlock not the blocks value.  Try this and see:

myTrueBlock := [Transcript show: 'That''s TRUE!'; cr; endEntry].

true ifTrue: [myTrueBlock]  

Now try this,

true ifTrue: myTrueBlock.

Now consider this: myTrueBlock value.

So in your example:

[each] would not work since [] value returns a block each.
[each value] does work since it is really doing [] value -> each value.

But since aBlock on: do: does aBlock value, only aBlock is needed.

Only each is needed.  So here is a version that works.

(OrderedCollection new
add: [10/0];
add: [2 raisedToInteger: 1/2];
add: [-5 raisedTo: 1.5]; yourself
) do: [:each | each on: Exception do: [:ex | Transcript show: ex; cr;
endEntry]].

endEntry is for Klaus!

It is a very good suggestion Brian!

Ron Teitelbaum

> -----Original Message-----
> From: [hidden email] [mailto:beginners-
> [hidden email]] On Behalf Of Klaus D. Witzel
> Sent: Wednesday, August 09, 2006 2:32 PM
> To: [hidden email]
> Subject: [Newbies] Re: error trap
>
> On Wed, 09 Aug 2006 19:59:41 +0200, Brian Murphy-Dye wrote:
> > Ron, another crazy possibility comes to mind when reading your
> > excellent description: making each line it's own block.
> >
> > {[10/0].
> >   [2 raisedToInteger: 1/2].
> >   [-5 raisedTo: 1.5]
> > } do: [:each | [each value] on: Exception do: [:ex | Transcript show:
> > ex; cr]].
>
> Excellent, Brian. Why do you still write in the beginners list ;-)
> ...
> Ah, now I can see why: Transcript endEntry is missing from the above :)
> </joke>
>
> /Klaus
>
> > Brian.
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Re: error trap

Klaus D. Witzel
On Wed, 09 Aug 2006 21:11:40 +0200, Ron Teitelbaum wrote:
> Brian,
>
> Yes I agree it's a great suggestion, although a few changes:
> Literal blocks to not parse into collections automatically.

Ron, please: a literal Array is a subclass of Collection and so the blocks  
in

  { [nil]. [true]. [false] }

parse "into collections automatically". You didn't inspectIt for verifying  
your (false) claim, didn't you. Also, have a look at the implementors of  
#caseOf: and #caseOf:otherwise:, they are heavy users of literal blocks in  
Collections ...

...
> Each in this case is already a block.

Yes. And, into the other direction, even in good core methods one often  
finds things like

  ^ dict at: aKey ifAbsent: [nil]

There seems to be a "natural" confusion between "object" value and block  
"value". Not a big surprise since Java and other procedural-oriented  
friends do not offer block values. So any demo of using blocks "as if"  
they where any other object, as Brian has shown, is a sign for the ability  
to master the subject 8-)

> Only each is needed.

Absolutely.

> So here is a version that works.
>
> (OrderedCollection new
> add: [10/0];
> add: [2 raisedToInteger: 1/2];
> add: [-5 raisedTo: 1.5]; yourself
> ) do: [:each | each on: Exception do: [:ex | Transcript show: ex; cr;
> endEntry]].
>
> endEntry is for Klaus!

Hhm, endEntry is too expensive within any and every loop. Just put  
Transcript endEntry after the loop. I mentioned endEntry because  
Transcript almost always does not display the last lines (they are  
buffered) and people get confused and believe that either their code or  
Squeak is wrong (but both is not the case).

> It is a very good suggestion Brian!

Indeed, and Briant's use of literal blocks in a literal Array is perfect  
(in the sense of: cannot be made better).

/Klaus

> Ron Teitelbaum

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: error trap

Davide Arrigo
In reply to this post by Ron Teitelbaum
Alle 18:16, mercoledì 9 agosto 2006, Ron Teitelbaum ha scritto:
> Hi Davide,
>
> I just wrote up something like this for Sedar:
> http://lists.squeakfoundation.org/pipermail/beginners/2006-August/000701.ht
>m l
>
> To answer your question directly the answer is yes and no.
>
MAny thanks to all of you, now it's clear what I have to do.
I'll try to modify my method.
Best Regards                          
--
---------------
Davide Arrigo
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

RE: Re: Re: error trap

Ron Teitelbaum
In reply to this post by Klaus D. Witzel

> From: Klaus D. Witzel
>
> On Wed, 09 Aug 2006 21:11:40 +0200, Ron Teitelbaum wrote:
> > Brian,
> >
> > Yes I agree it's a great suggestion, although a few changes:
> > Literal blocks to not parse into collections automatically.
>
> Ron, please: a literal Array is a subclass of Collection and so the blocks
> in
>
>   { [nil]. [true]. [false] }

Learn something every day!

>
> parse "into collections automatically". You didn't inspectIt for verifying
> your (false) claim, didn't you.

No I didn't!  The { } just looked so wrong and like C!  I'm used to #()
which of course doesn't work.

 Also, have a look at the implementors of
> #caseOf: and #caseOf:otherwise:, they are heavy users of literal blocks in
> Collections ...

I will!

>
> ...
> > Each in this case is already a block.
>
> Yes. And, into the other direction, even in good core methods one often
> finds things like
>
>   ^ dict at: aKey ifAbsent: [nil]

I started to write this too but thought about some of the errors that people
receive about wrong form of block and didn't want to scare people.  

>
> There seems to be a "natural" confusion between "object" value and block
> "value". Not a big surprise since Java and other procedural-oriented
> friends do not offer block values. So any demo of using blocks "as if"
> they where any other object, as Brian has shown, is a sign for the ability
> to master the subject 8-)
>
> > Only each is needed.
>
> Absolutely.
>
> > So here is a version that works.
> >
> > (OrderedCollection new
> > add: [10/0];
> > add: [2 raisedToInteger: 1/2];
> > add: [-5 raisedTo: 1.5]; yourself
> > ) do: [:each | each on: Exception do: [:ex | Transcript show: ex; cr;
> > endEntry]].
> >
> > endEntry is for Klaus!
>
> Hhm, endEntry is too expensive within any and every loop. Just put
> Transcript endEntry after the loop. I mentioned endEntry because
> Transcript almost always does not display the last lines (they are
> buffered) and people get confused and believe that either their code or
> Squeak is wrong (but both is not the case).
>
> > It is a very good suggestion Brian!
>
> Indeed, and Briant's use of literal blocks in a literal Array is perfect
> (in the sense of: cannot be made better).
>

Thanks for your correction Klaus!  With programming always keep an open
mind, there is lots more to learn!

Ron



_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: error trap

Roel Wuyts
Note: no need for the endEntry when using show: it does it already  
(see TranscriptStream>>#show: )

Use a 'manual' endEntry when you would use nextPutAll: or print: etc.  
on the Transcript (which most people do not use anyway).


On 10 Aug 2006, at 17:02, Ron Teitelbaum wrote:

>
>> From: Klaus D. Witzel
>>
>> On Wed, 09 Aug 2006 21:11:40 +0200, Ron Teitelbaum wrote:
>>> Brian,
>>>
>>> Yes I agree it's a great suggestion, although a few changes:
>>> Literal blocks to not parse into collections automatically.
>>
>> Ron, please: a literal Array is a subclass of Collection and so  
>> the blocks
>> in
>>
>>   { [nil]. [true]. [false] }
>
> Learn something every day!
>
>>
>> parse "into collections automatically". You didn't inspectIt for  
>> verifying
>> your (false) claim, didn't you.
>
> No I didn't!  The { } just looked so wrong and like C!  I'm used to  
> #()
> which of course doesn't work.
>
>  Also, have a look at the implementors of
>> #caseOf: and #caseOf:otherwise:, they are heavy users of literal  
>> blocks in
>> Collections ...
>
> I will!
>
>>
>> ...
>>> Each in this case is already a block.
>>
>> Yes. And, into the other direction, even in good core methods one  
>> often
>> finds things like
>>
>>   ^ dict at: aKey ifAbsent: [nil]
>
> I started to write this too but thought about some of the errors  
> that people
> receive about wrong form of block and didn't want to scare people.
>
>>
>> There seems to be a "natural" confusion between "object" value and  
>> block
>> "value". Not a big surprise since Java and other procedural-oriented
>> friends do not offer block values. So any demo of using blocks "as  
>> if"
>> they where any other object, as Brian has shown, is a sign for the  
>> ability
>> to master the subject 8-)
>>
>>> Only each is needed.
>>
>> Absolutely.
>>
>>> So here is a version that works.
>>>
>>> (OrderedCollection new
>>> add: [10/0];
>>> add: [2 raisedToInteger: 1/2];
>>> add: [-5 raisedTo: 1.5]; yourself
>>> ) do: [:each | each on: Exception do: [:ex | Transcript show: ex;  
>>> cr;
>>> endEntry]].
>>>
>>> endEntry is for Klaus!
>>
>> Hhm, endEntry is too expensive within any and every loop. Just put
>> Transcript endEntry after the loop. I mentioned endEntry because
>> Transcript almost always does not display the last lines (they are
>> buffered) and people get confused and believe that either their  
>> code or
>> Squeak is wrong (but both is not the case).
>>
>>> It is a very good suggestion Brian!
>>
>> Indeed, and Briant's use of literal blocks in a literal Array is  
>> perfect
>> (in the sense of: cannot be made better).
>>
>
> Thanks for your correction Klaus!  With programming always keep an  
> open
> mind, there is lots more to learn!
>
> Ron
>
>
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
>

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: error trap

Klaus D. Witzel
On Thu, 10 Aug 2006 17:27:09 +0200, Roel Wuyts wrote:

> Note: no need for the endEntry when using show: it does it already (see  
> TranscriptStream>>#show: )
>
> Use a 'manual' endEntry when you would use nextPutAll: or print: etc. on  
> the Transcript (which most people do not use anyway).

Right you are! But I'm writing on recycled web pages, those with  
notoriously small margin, therefore I tend to believe that people point to  
the methods mentioned (like #endEndtry) and curiously look for  
implementors and other good things in the same message category, the  
famous "cmd-m followed by a cmd-b and/or cmd-m" :p

/Klaus

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: error trap

Klaus D. Witzel
In reply to this post by Ron Teitelbaum
Hi Ron,

on Thu, 10 Aug 2006 17:02:11 +0200, you wrote:
>> From: Klaus D. Witzel
>> ... You didn't inspectIt for verifying
>
> No I didn't!  The { } just looked so wrong and like C!

Yes, same for me when I saw that for the first time in Squeak. Never saw  
that in Smalltalk/2.x (didn't look for it in VW).

But nowaday's I wonder how we have done it for so many decades without  
handsome {expression. 'constant'. [block]} select: [:everything |  
everything isAnObject].

/Klaus

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: error trap

stéphane ducasse-2
In reply to this post by Ron Teitelbaum
>>
>> parse "into collections automatically". You didn't inspectIt for  
>> verifying
>> your (false) claim, didn't you.
>
> No I didn't!  The { } just looked so wrong and like C!  I'm used to  
> #()
> which of course doesn't work.
>
>  Also, have a look at the implementors of
>> #caseOf: and #caseOf:otherwise:, they are heavy users of literal  
>> blocks in
>> Collections ...
>
> I will!

argh! Ugly!

>> Yes. And, into the other direction, even in good core methods one  
>> often
>> finds things like
>>
>>   ^ dict at: aKey ifAbsent: [nil]

this is much better.

I would like to see caseOf:...removed from the system

> I started to write this too but thought about some of the errors  
> that people
> receive about wrong form of block and didn't want to scare people.
>
stef
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: error trap

Klaus D. Witzel
On Fri, 11 Aug 2006 23:00:03 +0200, stéphane ducasse wrote:
Klaus wrote:
>>> Yes. And, into the other direction, even in good core methods one often
>>> finds things like
>>>
>>>   ^ dict at: aKey ifAbsent: [nil]
>
> this is much better.

Why do you call failures in understanding things like this better, Stef?  
Whoever writes such statements, has no idea about an object's value versus  
a block's value and especially no idea about when and why execution of a  
block of code can and should be delayed (not to speak about performance  
impact).

> I would like to see caseOf:...removed from the system

And replace it by what? Why would you limit the expressive power of the  
software developer, Stef?

/Klaus

> stef


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: error trap

Damien Cassou-3
In reply to this post by Klaus D. Witzel
> Yes. And, into the other direction, even in good core methods one often
> finds things like
>
>  ^ dict at: aKey ifAbsent: [nil]
>
> There seems to be a "natural" confusion between "object" value and block
> "value".

What's the problem with that ? Yes, 'nil value' answers nil but 'nil' is
not a block and #at:ifAbsent: waits for a block (the parameter is called
aBlock). It is shorter to write 'nil' directly I agree.


What is more problematic in my point of view is code like this:

AbstractLauncher>>parameterAt: parName ifAbsent: aBlock
   "Return the parameter named parName.
     Evaluate the block if parameter does not exist."
   ^self parameters
     at: parName asUppercase
     ifAbsent: [aBlock value]



It may be me (still a beginner), but it looks equivalent to

   ^self parameters
     at: parName asUppercase
     ifAbsent: aBlock


which is faster and clearer in my opinion.
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: error trap

Klaus D. Witzel
On Sun, 13 Aug 2006 18:31:23 +0200, Damien Cassou wrote:

>> Yes. And, into the other direction, even in good core methods one often  
>> finds things like
>>   ^ dict at: aKey ifAbsent: [nil]
>>  There seems to be a "natural" confusion between "object" value and  
>> block "value".
>
> What's the problem with that ?

The lack of understanding the expressive power of the software developer  
is the problem. Why always use a hammer? Because everything looks like  
nails?

> Yes, 'nil value' answers nil but 'nil' is not a block and #at:ifAbsent:  
> waits for a block (the parameter is called aBlock).

No, #at:ifAbsent: doesn't wait for an instance of BlockContext. Smalltalk  
is typeless and, if at all, only has *one* (the universal) type.

> It is shorter to write 'nil' directly I agree.

And the compiler is not forced to emit code for a BlockContext and the VM  
is not forced to create a BlockContext only for throwing it away unused  
(unused in the sense that nil == [nil] value). It is like writing (x)  
versus (0+x) or (1*x).

> What is more problematic in my point of view is code like this:
>
> AbstractLauncher>>parameterAt: parName ifAbsent: aBlock
>    "Return the parameter named parName.
>      Evaluate the block if parameter does not exist."
>    ^self parameters
>      at: parName asUppercase
>      ifAbsent: [aBlock value]
>
> It may be me (still a beginner), but it looks equivalent to
>
>    ^self parameters
>      at: parName asUppercase
>      ifAbsent: aBlock

Yes, anObject == [anObject] value.

> which is faster and clearer in my opinion.

Sure.

/Klaus

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: error trap

Klaus D. Witzel
In reply to this post by Damien Cassou-3
On Sun, 13 Aug 2006 18:31:23 +0200, Damien Cassou wrote:
> Klaus wrote:
>> Yes. And, into the other direction, even in good core methods one often  
>> finds things like
>>   ^ dict at: aKey ifAbsent: [nil]
>>  There seems to be a "natural" confusion between "object" value and  
>> block "value".

Perhaps I should add rules of thumb for when to *author* a block of code:

#1 - for a non local return like [^ nil]

#2 - for deferring a computation like [base raisedTo: bigInteger]

#3 - for parameterized "smart" logic like [:x :y | "do something with  
self, x and y"]

Anybody anything for #4 ?

Unfortunately there are, enforced by people who wrote the compiler, other  
rules (not many of them are for the thumb). For an example try a printIt on

  ^ true ifTrue: #a ifFalse: [false ifTrue: #b ifFalse: #c]

Again, a "natural" confusion between an object's value and a block's value.

/Klaus

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Re: Re: Re: error trap

Damien Cassou-3
Klaus D. Witzel wrote:

> On Sun, 13 Aug 2006 18:31:23 +0200, Damien Cassou wrote:
>> Klaus wrote:
> Perhaps I should add rules of thumb for when to *author* a block of code:
>
> #1 - for a non local return like [^ nil]
> #2 - for deferring a computation like [base raisedTo: bigInteger]
> #3 - for parameterized "smart" logic like [:x :y | "do something with
> self, x and y"]
>
> Anybody anything for #4 ?
>
> Unfortunately there are, enforced by people who wrote the compiler,
> other rules (not many of them are for the thumb). For an example try a
> printIt on
>
>  ^ true ifTrue: #a ifFalse: [false ifTrue: #b ifFalse: #c]
>
> Again, a "natural" confusion between an object's value and a block's value.

"
  <- argument of ifTrue: must be a block or variable ->
"


In VW, there is no Object>>value method. But #value is implemented in
Boolean and UndefinedObject. Is this Smalltalk-standard to have #value
on Object ?
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: error trap

Klaus D. Witzel
On Mon, 14 Aug 2006 10:17:40 +0200, Damien Cassou  
<[hidden email]> wrote:

> Klaus D. Witzel wrote:
>> For an example try a printIt on
>>   ^ true ifTrue: #a ifFalse: [false ifTrue: #b ifFalse: #c]
>>  Again, a "natural" confusion between an object's value and a block's  
>> value.
>
> "
>   <- argument of ifTrue: must be a block or variable ->
> "
>
>
> In VW, there is no Object>>value method. But #value is implemented in  
> Boolean and UndefinedObject. Is this Smalltalk-standard to have #value  
> on Object ?

Just scanned SmalltalkV2.sources and SqueakV1.sources: #value is not  
implemented by Object nor by UndefinedObject.

/Klaus

_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners