comp.lang.ada
 help / color / mirror / Atom feed
* Good Ada Style For Impossible Actions?
@ 2002-10-26 15:59 Dr Nancy's Sweetie
  2002-10-26 21:11 ` Jeffrey Carter
  0 siblings, 1 reply; 7+ messages in thread
From: Dr Nancy's Sweetie @ 2002-10-26 15:59 UTC (permalink / raw)



I'm working on a program which uses the ncurses packages to draw on the
screen and handle mouse events.  (It has keyboard input in the event the
user hasn't got a mouse or is using a terminal emulator which doesn't
support a mouse.)  It breaks the working area into four subwindows, only
one of which responds to mouse clicks.

In ncurses, the way to test whether a mouse click happened in a window is
to use the function "Enclosed_In_Window", which takes a window and the
Mouse_Event and returns a Boolean.  But I've moved all the window-handling
code into a separate package.  As a result, the event loop can't see the
window (which is private to the Display object), so the Enclosed_In_Window
line won't compile.

Also, the Mouse_Event has a Row & Column which refer to its actual location
on the screen, not to the logical position within the relevant window.  To
take care of this, I plan to write "Display.Translate_Mouse_Event"
function, which would return the logical position given the Mouse_Event.
But then we come to the situation of "What if the mouse is NOT in the
window?"

At this point, several alternative approaches occurred to me.  The first is
to have the function return an illegal logical location -- made difficult
because the "Location_Type" is range limited to only legal possibilities.
It could be kludged to have a "Any_Location_Type", which would include some
impossible spots, and "Real_Location_Type", which would be only legal
spots, and then cast things around, and then . . .  Well, it's starting to
sound pretty kludgy.  I recognised this from C, in which you return bogus
values for functions that can't do their jobs.  (scanf() returns an EOF,
for example, if you read past end of file.)

The Perl solution might be to use the special value "undef", which is
tested for by the defined() function -- but it seems unlikely that a
strongly-typed language like Ada is going to have an untyped undef.

Considering the parallel with reading input, I could write two functions,
a "Display.Within_Active_Window", returning a Boolean, and then put the
call to Display.Translate_Mouse_Event inside an "if" (following the example
of Ada's "End_Of_File" function, which you call before calling "Get",
instead of calling Get and seeing if it returns a special value).

Then I realised that this could also be done with an exception: I could
make up an exception, "Not_In_Active_Window", have Translate_Mouse_Event
raise that exception if the Mouse_Event wasn't in the window, and then
just have a little begin..exception..end block in the code.

But of these last two approaches, I don't have a feeling for which one is
Good Ada Style(tm).  Should exceptions only be used for serious problems?
Using it here would remove a function and chop out some lines of code, but
it's not really much of a savings and the exception block feels like it
would clutter up the event loop at least as much as the if-then.

Is there some community feeling about how to handle a case like this?  When
to use exceptions and when not to?


My own inclination is to write two functions and use an if, but I thought
it might be worthwhile to ask people with a better sense of the style.


Thank you for your kind attention.


Darren Provine ! kilroy@elvis.rowan.edu ! http://www.rowan.edu/~kilroy
"He seems to me a very foolish man, and very wretched, who will not increase
 his understanding while he is in the world, and ever wish and long to reach
 that endless life where all shall be made clear."
                    -- Alfred the Great, King of the West Saxons (849-899)



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Good Ada Style For Impossible Actions?
  2002-10-26 15:59 Good Ada Style For Impossible Actions? Dr Nancy's Sweetie
@ 2002-10-26 21:11 ` Jeffrey Carter
  2002-10-28  3:52   ` Dr Nancy's Sweetie
  0 siblings, 1 reply; 7+ messages in thread
From: Jeffrey Carter @ 2002-10-26 21:11 UTC (permalink / raw)


Dr Nancy's Sweetie wrote:
> Considering the parallel with reading input, I could write two functions,
> a "Display.Within_Active_Window", returning a Boolean, and then put the
> call to Display.Translate_Mouse_Event inside an "if" (following the example
> of Ada's "End_Of_File" function, which you call before calling "Get",
> instead of calling Get and seeing if it returns a special value).
> 
> Then I realised that this could also be done with an exception: I could
> make up an exception, "Not_In_Active_Window", have Translate_Mouse_Event
> raise that exception if the Mouse_Event wasn't in the window, and then
> just have a little begin..exception..end block in the code.
> 
> But of these last two approaches, I don't have a feeling for which one is
> Good Ada Style(tm).  Should exceptions only be used for serious problems?
> Using it here would remove a function and chop out some lines of code, but
> it's not really much of a savings and the exception block feels like it
> would clutter up the event loop at least as much as the if-then.

Exceptions should be reserved for exceptional situations. Reading past 
the end of a file is exceptional because you're expected to test to see 
if you're at the end of the file before reading. If you then read past 
the end of file anyway, something exceptional has happened.

It sounds as if you could have mouse events outside the proper window at 
any time, so such an event would not be exceptional. So having a 
function would probably be a good idea.

But if you use the function and still get a mouse event outside the 
proper window, you should also have an exception to indicate that.

-- 
Jeff Carter
"All citizens will be required to change their underwear
every half hour. Underwear will be worn on the outside,
so we can check."
Bananas




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Good Ada Style For Impossible Actions?
  2002-10-26 21:11 ` Jeffrey Carter
@ 2002-10-28  3:52   ` Dr Nancy's Sweetie
  2002-10-28 17:13     ` Jeffrey Carter
  0 siblings, 1 reply; 7+ messages in thread
From: Dr Nancy's Sweetie @ 2002-10-28  3:52 UTC (permalink / raw)


Jeffrey Carter wrote, in reply to a question about when to use exceptions
and functions for testing error conditions:
> It sounds as if you could have mouse events outside the proper window
> at any time, so such an event would not be exceptional. So having a
> function would probably be a good idea.
>
> But if you use the function and still get a mouse event outside the
> proper window, you should also have an exception to indicate that.

If the function tries to compute a logical address for an invalid
mouse position, a CONSTRAINT_ERROR will be raised because the logical
position will be outside its valid range.

Is there a good heuristic for "raise your own exception" and "don't
clutter up the exception namespace"?


Darren Provine ! kilroy@elvis.rowan.edu ! http://www.rowan.edu/~kilroy
"C++ is like jamming a helicopter inside a Miata and expecting some
 sort of improvement." -- Drew Olbrich



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Good Ada Style For Impossible Actions?
  2002-10-28  3:52   ` Dr Nancy's Sweetie
@ 2002-10-28 17:13     ` Jeffrey Carter
  2002-10-28 17:33       ` tmoran
  2002-10-28 17:52       ` Warren W. Gay VE3WWG
  0 siblings, 2 replies; 7+ messages in thread
From: Jeffrey Carter @ 2002-10-28 17:13 UTC (permalink / raw)


Dr Nancy's Sweetie wrote:
> Jeffrey Carter wrote, in reply to a question about when to use exceptions
> and functions for testing error conditions:
> 
>>It sounds as if you could have mouse events outside the proper window
>>at any time, so such an event would not be exceptional. So having a
>>function would probably be a good idea.
>>
>>But if you use the function and still get a mouse event outside the
>>proper window, you should also have an exception to indicate that.
> 
> 
> If the function tries to compute a logical address for an invalid
> mouse position, a CONSTRAINT_ERROR will be raised because the logical
> position will be outside its valid range.
> 
> Is there a good heuristic for "raise your own exception" and "don't
> clutter up the exception namespace"?

The function returns Boolean: True if the mouse pointer is in the active 
window; False otherwise. So it should catch the exception and return False.

The other subprogram returns the mouse position within the active 
window, and should only be called if the function mentioned above 
returns True. But of course people will ignore that rule, and in any 
case it may be possible for the mouse pointer to move between the 2 
calls. If the mouse pointer is outside the active window when this 
subprogram is called, then it should raise a specific exception to 
indicate this. Constraint_Error is not very informative in this context.

-- 
Jeff Carter
"It's all right, Taggart. Just a man and a horse being hung out there."
Blazing Saddles




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Good Ada Style For Impossible Actions?
  2002-10-28 17:13     ` Jeffrey Carter
@ 2002-10-28 17:33       ` tmoran
  2002-10-29  1:35         ` Dr Nancy's Sweetie
  2002-10-28 17:52       ` Warren W. Gay VE3WWG
  1 sibling, 1 reply; 7+ messages in thread
From: tmoran @ 2002-10-28 17:33 UTC (permalink / raw)


A mouse outside a particular screen area is not an impossible action.
What should your particular program that is asking for mouse position do
in that case?  Is this an error - the program shouldn't be asking about
position in those circumstances?  Is it OK, and the legitimate space of
mouse positions for that program consists of the set of points inside the
rectangle, plus the single "outside the rectangle" 'point'?  Perhaps the
program should simply go dormant, ie the Ask_Position function shouldn't
return, until the mouse moves into its window area?



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Good Ada Style For Impossible Actions?
  2002-10-28 17:13     ` Jeffrey Carter
  2002-10-28 17:33       ` tmoran
@ 2002-10-28 17:52       ` Warren W. Gay VE3WWG
  1 sibling, 0 replies; 7+ messages in thread
From: Warren W. Gay VE3WWG @ 2002-10-28 17:52 UTC (permalink / raw)


Jeffrey Carter wrote:
> Dr Nancy's Sweetie wrote:
> 
>> Jeffrey Carter wrote, in reply to a question about when to use exceptions
>> and functions for testing error conditions:
>>
>>> It sounds as if you could have mouse events outside the proper window
>>> at any time, so such an event would not be exceptional. So having a
>>> function would probably be a good idea.
>>>
>>> But if you use the function and still get a mouse event outside the
>>> proper window, you should also have an exception to indicate that.
>>
>> If the function tries to compute a logical address for an invalid
>> mouse position, a CONSTRAINT_ERROR will be raised because the logical
>> position will be outside its valid range.
>>
>> Is there a good heuristic for "raise your own exception" and "don't
>> clutter up the exception namespace"?
> 
> The function returns Boolean: True if the mouse pointer is in the active 
> window; False otherwise. So it should catch the exception and return False.
> 
> The other subprogram returns the mouse position within the active 
> window, and should only be called if the function mentioned above 
> returns True. But of course people will ignore that rule, and in any 
> case it may be possible for the mouse pointer to move between the 2 
> calls. If the mouse pointer is outside the active window when this 
> subprogram is called, then it should raise a specific exception to 
> indicate this. Constraint_Error is not very informative in this context.

I'd suggest that your function (or procedure) return
a discriminated record instead:

type Window_Status_Kind is ( Not_In_Window, In_Window );

type Return_Type(Kind : Window_Status_Kind) is
    record
       case Kind in
          when Not_In_Window =>
             null; -- no other information available
          when In_Window =>
             Y :      Line_Type;    -- Translated window Y coordinate
             X :      Column_Type;  -- Translated window X coordinate
       end case;
    end record;

The nice thing about this approach is that if your code attempts to
access Y or X from the returned value when it is inappropriate to do
so, the code will fail immediately, at the source of error.  Returning
the Y,X separately from a Boolean flag (say), leaves you open to
abusing Y,X when they are not valid.

I agree that an exception is probably overkill for something that is
likely to occur with reasonable frequency.

Warren.
-- 
Warren W. Gay VE3WWG
http://home.cogeco.ca/~ve3wwg




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Good Ada Style For Impossible Actions?
  2002-10-28 17:33       ` tmoran
@ 2002-10-29  1:35         ` Dr Nancy's Sweetie
  0 siblings, 0 replies; 7+ messages in thread
From: Dr Nancy's Sweetie @ 2002-10-29  1:35 UTC (permalink / raw)


Discussing a style question I had involving a program I've been
fiddling with, "tmoran@acm.org" wrote:
> A mouse outside a particular screen area is not an impossible action.

No, but translating the physical position into a logical position is,
if the mouse is outside a certain area.


In any case, I've been thinking about this, and I decided that the
problem was one of incorrect object boundaries.  That is, I had worked
out a "display" object, to handle drawing on the screen, but left all
the keyboard/mouse handling in the main body of the code.

I have since decided that I what I want is to move input management into
the same module with the display, and create an "interface" object.  The
main body of the code will look something this:

   while not Finished loop
      Selection = Interface.Get_Action;

      case Selection.Action is
         when Register_Move =>
            New_Spot := Selection.Spot;
            -- do stuff
         when Exit_Game =>
            Finished := True;
         -- and so on
      end case;
   end loop;

I thought of this because it occurred that a GUI made with GtkAda might
be interesting, but such a thing could never be added into the program
as it was.  This way, I can write the main body of the code so that it
works with an object called "Interface", and I can write a simple text
interface now, and (if I want) add in a fancier one later without having
to change any of the logic.

At least, I think I can.  Having a single variable which points to
different kinds of objects at different times feels like it ought to be
possible, but I haven't read that section of the book yet.

(I did read about protected classes, so I have a working clock.)


Darren Provine ! kilroy@elvis.rowan.edu ! http://www.rowan.edu/~kilroy
"Had George III been a Scheme programmer, he might have responded to
 Patrick Henry by freeing him and then killing him." -- Michael Eisenberg



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2002-10-29  1:35 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-10-26 15:59 Good Ada Style For Impossible Actions? Dr Nancy's Sweetie
2002-10-26 21:11 ` Jeffrey Carter
2002-10-28  3:52   ` Dr Nancy's Sweetie
2002-10-28 17:13     ` Jeffrey Carter
2002-10-28 17:33       ` tmoran
2002-10-29  1:35         ` Dr Nancy's Sweetie
2002-10-28 17:52       ` Warren W. Gay VE3WWG

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox