comp.lang.ada
 help / color / mirror / Atom feed
From: "Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de>
Subject: Re: Parser interface design
Date: Thu, 7 Apr 2011 22:31:17 +0200
Date: 2011-04-07T22:31:17+02:00	[thread overview]
Message-ID: <jns8ijpud7h4.1e809ji5833aa$.dlg@40tude.net> (raw)
In-Reply-To: slrnips38p.2fnq.lithiumcat@sigil.instinctive.eu

On Thu, 7 Apr 2011 19:14:33 +0000 (UTC), Natasha Kerensikova wrote:

> Hello,
> 
> On 2011-04-06, Dmitry A. Kazakov <mailbox@dmitry-kazakov.de> wrote:
>> On Wed, 6 Apr 2011 10:11:46 +0000 (UTC), Natasha Kerensikova wrote:
>>
>>> I thought the most idiomatic way of putting together a bunch of
>>> callbacks in Ada would be to use an Interface, and then rely on dynamic
>>> dispatch.
>>
>> It also can be an abstract base type with primitive operations defined
>> null. The advantage is that you can have a "null function" and non-null
>> implementations with a type, which you cannot with an interface.
> 
> That's an interesting idea, however that prevents a renderer object from
> being based on another type, like Controlled or Limited_Controlled -
> unless I base the abstract type on them.
> 
> The null function fact seems very interesting though. Is it possible to
> test externally whether a given dispatched function is null?

I meant "null" in the sense of an elementary implementation, e.g.

   function Get_Line (...) return String is
   begin
      raise End_Error;
   end String;

With interfaces you can do:

   procedure Bar (...) is null;

but cannot

   function Get_Line (...) return String is null;

and furthermore you cannot provide any implementation for Get_Line.
Interface is such a broken concept.

> I'm asking
> because in my C implementation, a NULL callback was a meant to
> communicate to the parser that the associated active character should
> no longer be considered active, thereby switching off that particular
> feature (which is very different from having a no-op callback).

Why should you test for anything? Just make the implementation do what is
required to do in order to achieve the desired effect.

>>> The approach using tagged types implementing an interface seems heavier.
>>
>> You should not try to pack everything onto one types hierarchy. The parser
>> and renderer should likely be two different hierarchies glued together
>> through a mix-in in a third object aggregating both implementation.
> 
> Actually I don't understand why there would be a second or even a third
> object in there. Would you mind expanding?

Parser should not know anything about rendering. Likewise it should know
nothing about the source. It is better to decouple such things into
independent hierarchies. Objects instantiating each hierarchy can be
aggregated or mixed-in by the user.

> In the example I proposed, the only object was the parser, which is
> tagged in order to provide dynamic dispatching. That's what would be in
> the renderer package. The parser package would be only a procedure, to
> which the client hand over the flow control, and which uses the
> callbacks from the tagged instance provided by the client. I don't see
> how to get from this to something where the parser and/or the client has
> a tagged object.

Parser is such an object encapsulating the parsing state. You certainly
would like to have it reentrant, so you need to keep that state somewhere.
The source object encapsulates the state of the source being parsed, e.g. a
file keeps its current position. The renderer object holds the rendering
context etc. An ability to keep hidden state is key advantage of an OO
design over naked procedures tossed here and there.

>>> So what would be the best approach to interface a parser and a renderer?
>>
>> The parsers I implemented used primitive operations as sematic callbacks.
> 
> That sound exactly like what I proposed, doesn't it?

Yes it does.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



  reply	other threads:[~2011-04-07 20:31 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-04-06 10:11 Parser interface design Natasha Kerensikova
2011-04-06 12:17 ` Georg Bauhaus
2011-04-07 18:56   ` Natasha Kerensikova
2011-04-08 11:49     ` Stephen Leake
2011-04-06 12:20 ` Dmitry A. Kazakov
2011-04-07 19:14   ` Natasha Kerensikova
2011-04-07 20:31     ` Dmitry A. Kazakov [this message]
2011-04-08 13:51       ` Natasha Kerensikova
2011-04-08 14:21         ` Dmitry A. Kazakov
2011-04-12 15:58           ` Natasha Kerensikova
2011-04-12 17:14             ` Dmitry A. Kazakov
2011-04-06 15:51 ` Georg Bauhaus
2011-04-07 19:44   ` Natasha Kerensikova
2011-04-07 20:52     ` Dmitry A. Kazakov
2011-04-07 22:09     ` Simon Wright
2011-04-08 14:03       ` Natasha Kerensikova
2011-04-08 19:06         ` Jeffrey Carter
2011-04-08 19:59         ` Simon Wright
2011-04-12 16:13           ` Natasha Kerensikova
2011-04-12 17:22             ` Dmitry A. Kazakov
2011-04-12 19:02               ` Simon Wright
2011-04-13  8:20                 ` Natasha Kerensikova
2011-04-13  8:37                   ` Dmitry A. Kazakov
2011-04-13 11:06                     ` Georg Bauhaus
2011-04-13 12:46                       ` Dmitry A. Kazakov
2011-04-13 22:33                   ` Randy Brukardt
2011-04-14  6:55                     ` Natasha Kerensikova
2011-04-15  0:22                       ` Randy Brukardt
2011-04-12 21:54               ` Randy Brukardt
2011-04-07 22:13     ` Georg Bauhaus
2011-04-08 15:30       ` Natasha Kerensikova
2011-04-07  0:36 ` Randy Brukardt
2011-04-08 11:16 ` Brian Drummond
2011-04-19  9:08 ` Natasha Kerensikova
2011-04-19 12:35   ` Ludovic Brenta
2011-04-20 10:44     ` Brian Drummond
2011-04-19 17:28   ` Jeffrey Carter
replies disabled

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