comp.lang.ada
 help / color / mirror / Atom feed
* Interfaces.Shift_Left
@ 2011-12-12 22:30 awdorrin
  2011-12-12 23:34 ` Interfaces.Shift_Left Simon Wright
  2011-12-13 12:00 ` Interfaces.Shift_Left Brian Drummond
  0 siblings, 2 replies; 22+ messages in thread
From: awdorrin @ 2011-12-12 22:30 UTC (permalink / raw)


Perhaps I'm just brain-dead after staring at code all day - but I'm
currently stumped and hoping someone could point me in the right
direction.

I've been trying to update old Ada code to Ada95 standards and wanted
to replace the calls to a custom C 'bit' library with the methods
available in the Interface package.

The interface package only takes unsigned values as parameters, which
I figured is fine since at a bit level sign doesn't really matter, but
looks like I was wrong, as I'm now encountering a constraint error
after a Shift_Left operation's results are casted back to an
Integer_32 type.

The code is similar to the following:

Cur_Word := (Cur_Word OR Shift_Left( Unsigned_32(Data),
Bits_To_Shift));
INT_PTR.all := Integer_32(Cur_Word);

I understand that the result from the shift_left is a negative number,
so it is being seen by Ada as a  large positive number ( > (2^31-1))
which is why I'm getting the Constraint error;

Maybe its my history with C that is confusing me, but shouldn't there
be an easy way to cast the value back to a negative Integer_32 from an
Unsigned_32?

Thanks!



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

* Re: Interfaces.Shift_Left
  2011-12-12 22:30 Interfaces.Shift_Left awdorrin
@ 2011-12-12 23:34 ` Simon Wright
  2011-12-13  1:36   ` Interfaces.Shift_Left Adam Beneschan
  2011-12-13 12:00 ` Interfaces.Shift_Left Brian Drummond
  1 sibling, 1 reply; 22+ messages in thread
From: Simon Wright @ 2011-12-12 23:34 UTC (permalink / raw)


awdorrin <awdorrin@gmail.com> writes:

> Cur_Word := (Cur_Word OR Shift_Left( Unsigned_32(Data),
> Bits_To_Shift));
> INT_PTR.all := Integer_32(Cur_Word);
>
> I understand that the result from the shift_left is a negative number,
> so it is being seen by Ada as a large positive number ( > (2^31-1))
> which is why I'm getting the Constraint error;
>
> Maybe its my history with C that is confusing me, but shouldn't there
> be an easy way to cast the value back to a negative Integer_32 from an
> Unsigned_32?

Ada doesn't have an easy way to do what you ask; one way you can do it
is by instantiating Ada.Unchecked_Conversion, which is deliberately
obvious so that reviewers know that they have to take more care than
usual.

It'd be much easier if Data was Unsigned_32 to start with, and if
instead of INT_PTR you had an Unsigned_32_Ptr.



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

* Re: Interfaces.Shift_Left
  2011-12-12 23:34 ` Interfaces.Shift_Left Simon Wright
@ 2011-12-13  1:36   ` Adam Beneschan
  0 siblings, 0 replies; 22+ messages in thread
From: Adam Beneschan @ 2011-12-13  1:36 UTC (permalink / raw)


On Dec 12, 3:34 pm, Simon Wright <si...@pushface.org> wrote:
> awdorrin <awdor...@gmail.com> writes:
> > Cur_Word := (Cur_Word OR Shift_Left( Unsigned_32(Data),
> > Bits_To_Shift));
> > INT_PTR.all := Integer_32(Cur_Word);
>
> > I understand that the result from the shift_left is a negative number,
> > so it is being seen by Ada as a large positive number ( > (2^31-1))
> > which is why I'm getting the Constraint error;
>
> > Maybe its my history with C that is confusing me, but shouldn't there
> > be an easy way to cast the value back to a negative Integer_32 from an
> > Unsigned_32?
>
> Ada doesn't have an easy way to do what you ask; one way you can do it
> is by instantiating Ada.Unchecked_Conversion, which is deliberately
> obvious so that reviewers know that they have to take more care than
> usual.

In fact, I think most C casts are, in essence, "unchecked
conversions".  In Ada, however, type conversions (specifically, value
conversions) are more strictly defined, and it's defined so that the
result of a type conversion has the same *value* as the operand, with
allowance for rounding.  So the idea of a type conversion whose
operand is a positive number and whose result is a negative number is
not how Ada does things.

                                 -- Adam



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

* Re: Interfaces.Shift_Left
  2011-12-12 22:30 Interfaces.Shift_Left awdorrin
  2011-12-12 23:34 ` Interfaces.Shift_Left Simon Wright
@ 2011-12-13 12:00 ` Brian Drummond
  2011-12-13 13:15   ` Interfaces.Shift_Left awdorrin
  1 sibling, 1 reply; 22+ messages in thread
From: Brian Drummond @ 2011-12-13 12:00 UTC (permalink / raw)


On Mon, 12 Dec 2011 14:30:51 -0800, awdorrin wrote:

> Perhaps I'm just brain-dead after staring at code all day - but I'm
> currently stumped and hoping someone could point me in the right
> direction.
> 
> I've been trying to update old Ada code to Ada95 standards and wanted to
> replace the calls to a custom C 'bit' library with the methods available
> in the Interface package.
> 
> The interface package only takes unsigned values as parameters, which I
> figured is fine since at a bit level sign doesn't really matter, but
> looks like I was wrong, as I'm now encountering a constraint error after
> a Shift_Left operation's results are casted back to an Integer_32 type.

Is there any way you could use modular types instead? They are closer to 
the semantics of C unsigned.

- Brian



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

* Re: Interfaces.Shift_Left
  2011-12-13 12:00 ` Interfaces.Shift_Left Brian Drummond
@ 2011-12-13 13:15   ` awdorrin
  2011-12-13 21:48     ` Interfaces.Shift_Left Randy Brukardt
  0 siblings, 1 reply; 22+ messages in thread
From: awdorrin @ 2011-12-13 13:15 UTC (permalink / raw)


The data being manipulated does start out as signed 32-bit integers -
its the Logical Shift operations in the Interfaces package that are
expecting Unsigned_32 types as input parameters.

After a good night's sleep - the Unchecked_Conversion seems like the
best choice here, if I want to stick with using the Interfaces package.



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

* Re: Interfaces.Shift_Left
  2011-12-13 13:15   ` Interfaces.Shift_Left awdorrin
@ 2011-12-13 21:48     ` Randy Brukardt
  2011-12-14 18:28       ` Interfaces.Shift_Left awdorrin
  0 siblings, 1 reply; 22+ messages in thread
From: Randy Brukardt @ 2011-12-13 21:48 UTC (permalink / raw)


"awdorrin" <awdorrin@gmail.com> wrote in message 
news:5f989095-5c1c-4b23-a538-d70f4718b4b1@l19g2000yqc.googlegroups.com...
> The data being manipulated does start out as signed 32-bit integers -
> its the Logical Shift operations in the Interfaces package that are
> expecting Unsigned_32 types as input parameters.

It does not make sense to "shift" numbers: "shift" is not an operation of a 
number.

It does make sense to "shift" a bunch of bits. Ada allows treating an 
unsigned number as a "bunch of bits", thus modular types support "and", 
"or", and shifting. But Ada does not allow that for signed numbers.

C programmers sometimes use shifting as a shortcut for multiplying or 
dividing by a power of 2. But this is premature optimization: any remotely 
decent compiler will do this automatically, without confusing the reader of 
the code. (Ever Ada compiler that I've examined the output of does this 
optimization.) (And this has the advantage of still getting overflow checks 
for multiplies, so there is a protection against getting the wrong answers 
by accident.)

So, if the data is *really* numeric in nature, then the first choice is to 
write the operations in terms of multiply and divide.

OTOH, if the data is not numeric, then the shifting probably is just used to 
pack data into a word. That's better done in Ada using representation 
clauses -- but in the interests of getting your program converted fast, you 
probably should leave well-enough alone and stick with the shifts. But in 
that case, the data type should be unsigned (there is no "number" involved).

Anyway, I understand if you want to use Unchecked_Conversion as a 
quick-and-dirty hack -- those are often necessary in the real world. But you 
shouldn't think of that as the final solution; there is something 
fundementally wrong with needing to shift signed values, and it would be 
best to work out what the problem is an eliminate it.

                                   Randy.





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

* Re: Interfaces.Shift_Left
  2011-12-13 21:48     ` Interfaces.Shift_Left Randy Brukardt
@ 2011-12-14 18:28       ` awdorrin
  2011-12-14 22:49         ` Interfaces.Shift_Left Randy Brukardt
  0 siblings, 1 reply; 22+ messages in thread
From: awdorrin @ 2011-12-14 18:28 UTC (permalink / raw)


I understand what you are saying and I do agree in theory.

The situation is that bit shifting is being used to retrieve data of
various bit lengths and positions from compound records.

For instance, retrieving a 6-bit signed value from a 32-bit field.

For the purposes of obtaining those 6 bits - sign is irrelevant, but
that 6 bit value is then sent back to a calling process as an 'Int32'
so I need the sign then.

Given more time and funding, I would replace this logic with something
that makes more sense, but a quick Unchecked_Conversion saves
rewriting 15,000+ lines of code. :)




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

* Re: Interfaces.Shift_Left
  2011-12-14 18:28       ` Interfaces.Shift_Left awdorrin
@ 2011-12-14 22:49         ` Randy Brukardt
  2011-12-15  9:51           ` Interfaces.Shift_Left Niklas Holsti
  0 siblings, 1 reply; 22+ messages in thread
From: Randy Brukardt @ 2011-12-14 22:49 UTC (permalink / raw)


"awdorrin" <awdorrin@gmail.com> wrote in message 
news:a76daa61-49f7-4235-af65-11973a012f35@v29g2000yqv.googlegroups.com...
>I understand what you are saying and I do agree in theory.
>
> The situation is that bit shifting is being used to retrieve data of
> various bit lengths and positions from compound records.
>
> For instance, retrieving a 6-bit signed value from a 32-bit field.

Right. This definitely should be done using record representation clauses if 
there is a choice. But of course if the code already exists, that might be 
too much.

> For the purposes of obtaining those 6 bits - sign is irrelevant, but
> that 6 bit value is then sent back to a calling process as an 'Int32'
> so I need the sign then.

Right. A record representation clause would do this correctly with no 
(visible) shifting, and it would be far less prone to errors. To take a 
quick example from my solitare solvers:

    Max_Score : constant := 1000;
    type Suits is (Diamonds, Hearts, Spades, Clubs);
    subtype Pip_Value is Natural range 1 .. 13; -- 1 = Ace, 13 = King. (I 
have names for these not shown here.)
    subtype Score_Value is Integer range -Max_Score..Max_Score;

    type Card is record
         Suit : Suits;
         Pip  : Pip_Value;
         Score : Score_Value;
    end record;
    for Card use record
         Suit at 0 range 14..15;
         Pip at 0 range 10..13;
         Score at 0 range 0..9;
    end record;
    for Card'Size use 16;

    Great_Card : constant Card := (Suit => Spades, Pip => 1, Score => 800);

Now, a reference to Great_Card.Score will give you a signed result, and the 
compiler will select the best set of shifts and masks for your target 
machine (not to mention combining them when possible). Much less 
complication, much easier to read, much less likely to make a mistake.

> Given more time and funding, I would replace this logic with something
> that makes more sense, but a quick Unchecked_Conversion saves
> rewriting 15,000+ lines of code. :)

I certainly understand, but personally I would guess that replacing the 
explicit shifting and masking with a record type would probably take me 
about the same time as writing all of the Unchecked_Conversion instances you 
would need. And there will be a lot less chance of error. YMMV, of course.

BTW, if there are really 15000 lines that would get changed by this, there 
is a really bad lack of encapsulation with this code. The interfaces between 
Ada and other languages/hardware/OSes should always be made as narrow as 
possible, and always should go through a well-encapulated interface (so it 
is easy to change one side without distrubing the other). But I realize that 
you probably know this.

                                                Randy.





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

* Re: Interfaces.Shift_Left
  2011-12-14 22:49         ` Interfaces.Shift_Left Randy Brukardt
@ 2011-12-15  9:51           ` Niklas Holsti
  2011-12-16  0:23             ` Interfaces.Shift_Left Randy Brukardt
  0 siblings, 1 reply; 22+ messages in thread
From: Niklas Holsti @ 2011-12-15  9:51 UTC (permalink / raw)


On 11-12-15 00:49 , Randy Brukardt wrote:
> "awdorrin"<awdorrin@gmail.com>  wrote in message
> news:a76daa61-49f7-4235-af65-11973a012f35@v29g2000yqv.googlegroups.com...
>> I understand what you are saying and I do agree in theory.
>>
>> The situation is that bit shifting is being used to retrieve data of
>> various bit lengths and positions from compound records.
>>
>> For instance, retrieving a 6-bit signed value from a 32-bit field.
>
> Right. This definitely should be done using record representation clauses if
> there is a choice.

I'm sorry to say that I disagree, and now always use the shift-and-mask 
method.

I used to be charmed by record representation clauses, until I wanted to 
write Ada 95 code that was portable between machines with different bit 
numbering orders.

I know that it is claimed that record representation clauses can be 
written to be portable between different bit numberings. But in my 
opinion, the schemes that do not use the Bit_Order attribute make the 
representation clauses ugly and hard to write and read, while the RM 
language that describes the Bit_Order attribute and its effects has 
surpassed my understanding whenever I've tried to read it -- I simply 
could not be sure that it would have the effect that I wanted.

I still would like to define the bit-level structure of data in a 
declarative way, rather than with field-extraction and field-insertion 
operations, but I have reluctantly concluded that the operational method 
is better for portable Ada programs, at least in my applications.

Another factor in this decision is that in my applications, the raw data 
(machine instructions for various processors) can actually have several 
different structures (instruction formats), so an approach using record 
representation clauses needs as many different record types and 
unchecked conversions from the raw data (bit-strings or words) to the 
appropriate record type. The operational approach entirely avoids these 
conversions.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Interfaces.Shift_Left
  2011-12-15  9:51           ` Interfaces.Shift_Left Niklas Holsti
@ 2011-12-16  0:23             ` Randy Brukardt
  2011-12-18 20:47               ` Interfaces.Shift_Left Niklas Holsti
  0 siblings, 1 reply; 22+ messages in thread
From: Randy Brukardt @ 2011-12-16  0:23 UTC (permalink / raw)


"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
news:9ktu5mFn31U1@mid.individual.net...
> On 11-12-15 00:49 , Randy Brukardt wrote:
>> "awdorrin"<awdorrin@gmail.com>  wrote in message
>> news:a76daa61-49f7-4235-af65-11973a012f35@v29g2000yqv.googlegroups.com...
>>> I understand what you are saying and I do agree in theory.
>>>
>>> The situation is that bit shifting is being used to retrieve data of
>>> various bit lengths and positions from compound records.
>>>
>>> For instance, retrieving a 6-bit signed value from a 32-bit field.
>>
>> Right. This definitely should be done using record representation clauses 
>> if
>> there is a choice.
>
> I'm sorry to say that I disagree, and now always use the shift-and-mask 
> method.

Might as well write in C then, this sort of code is complete, unmaintainable 
junk.

> I used to be charmed by record representation clauses, until I wanted to 
> write Ada 95 code that was portable between machines with different bit 
> numbering orders.

It's true, that's a problem. Luckily, it's not a real problem in practice 
for the vast majority of users, since pretty much all popular machines these 
days use the same bit numbering.

> I know that it is claimed that record representation clauses can be 
> written to be portable between different bit numberings. But in my 
> opinion, the schemes that do not use the Bit_Order attribute make the 
> representation clauses ugly and hard to write and read, while the RM 
> language that describes the Bit_Order attribute and its effects has 
> surpassed my understanding whenever I've tried to read it -- I simply 
> could not be sure that it would have the effect that I wanted.

It will have the right effect or be illegal. (At least that was my 
understanding.) The problem is that the non-default bit ordering makes it 
trivial to declare discontiguous (from the persepective of the default 
bit-ordering) components, and we didn't want to force compilers to support 
that sort of stuff. There is little customer demand for that sort of thing 
(most of the ones that exist are like you and gave up completely wanting 
more control than the language could possibly provide), so it didn't make 
sense to require the effort.

> I still would like to define the bit-level structure of data in a 
> declarative way, rather than with field-extraction and field-insertion 
> operations, but I have reluctantly concluded that the operational method 
> is better for portable Ada programs, at least in my applications.
>
> Another factor in this decision is that in my applications, the raw data 
> (machine instructions for various processors) can actually have several 
> different structures (instruction formats), so an approach using record 
> representation clauses needs as many different record types and unchecked 
> conversions from the raw data (bit-strings or words) to the appropriate 
> record type. The operational approach entirely avoids these conversions.

Of course, the vast majority of Unchecked_Conversions generate no code at 
all, so these conversions have no run-time impact and IMHO they're still 
more readable than a bunch of shifts or multiplies.

Anyway, I understand that everyone's mileage may vary. I doubt that many 
applications have the problem of decoding data that are both in the wrong 
bit-order and are unknown at run-time.

(Truth-in-advertising provision: most of the Janus/Ada compiler uses 
multiplies and divides to create machine instructions, because early 
versions of Janus/Ada had no support for record representation clauses or 
any other bit operations at all. We used assembler code whenever those 
operations were unavoidable -- hardly an ideal approach for portability 
reasons. Later versions (like the never-finished 68K and SPARC codegens) 
used record rep. clauses; I recall we had some issues with non-default 
bit-ordering but don't remember anymore how we solved them.)

                                          Randy.





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

* Re: Interfaces.Shift_Left
  2011-12-16  0:23             ` Interfaces.Shift_Left Randy Brukardt
@ 2011-12-18 20:47               ` Niklas Holsti
  2011-12-20  0:38                 ` Interfaces.Shift_Left Randy Brukardt
  0 siblings, 1 reply; 22+ messages in thread
From: Niklas Holsti @ 2011-12-18 20:47 UTC (permalink / raw)


On 11-12-16 02:23 , Randy Brukardt wrote:
> "Niklas Holsti"<niklas.holsti@tidorum.invalid>  wrote in message
> news:9ktu5mFn31U1@mid.individual.net...
>> On 11-12-15 00:49 , Randy Brukardt wrote:
>>> "awdorrin"<awdorrin@gmail.com>   wrote in message
>>> news:a76daa61-49f7-4235-af65-11973a012f35@v29g2000yqv.googlegroups.com...
>>>> I understand what you are saying and I do agree in theory.
>>>>
>>>> The situation is that bit shifting is being used to retrieve data of
>>>> various bit lengths and positions from compound records.
>>>>
>>>> For instance, retrieving a 6-bit signed value from a 32-bit field.
>>>
>>> Right. This definitely should be done using record representation clauses
>>> if
>>> there is a choice.
>>
>> I'm sorry to say that I disagree, and now always use the shift-and-mask
>> method.
>
> Might as well write in C then, this sort of code is complete, unmaintainable
> junk.

Ooh, harsh words. I'm trying not to take offence.

Of course I hide the implementation in an "extract field" function with 
the bit numbers as parameters. My code typically decodes machine 
instructions from the instruction set of some processor; the user manual 
of that processor is the specification for my SW; the user manual 
normally shows the format of a given instruction by a figure of the 
instruction with the fields indicated by bit numbers; there is an 
immediate correspondence between this figure and the calls of the 
"extract field" functions. Very easy to write, check, and maintain, in 
my experience.

>> I used to be charmed by record representation clauses, until I wanted to
>> write Ada 95 code that was portable between machines with different bit
>> numbering orders.
>
> It's true, that's a problem. Luckily, it's not a real problem in practice
> for the vast majority of users, since pretty much all popular machines these
> days use the same bit numbering.

"All the world is a VAX -- no, an Intel -- no, an Xxx", eh?

I do not want to write programs that have such an implementation 
dependency. I wouldn't go so far as to call such code "junk", but it 
would be as bad as assuming that Integer is 32 bits.

>> the RM
>> language that describes the Bit_Order attribute and its effects has
>> surpassed my understanding whenever I've tried to read it -- I simply
>> could not be sure that it would have the effect that I wanted.
>
> It will have the right effect or be illegal. (At least that was my
> understanding.)

I'm sure that is the intention. But as I haven't been able to understand 
the conditions under which Bit_Order works, I haven't dared to rely on 
it. Maybe I could understand Bit_Order if I tried harder, but then 
there's the other factor:

>> Another factor in this decision is that in my applications, the raw data
>> (machine instructions for various processors) can actually have several
>> different structures (instruction formats), so an approach using record
>> representation clauses needs as many different record types and unchecked
>> conversions from the raw data (bit-strings or words) to the appropriate
>> record type. The operational approach entirely avoids these conversions.
>
> Of course, the vast majority of Unchecked_Conversions generate no code at
> all, so these conversions have no run-time impact

Sure, run-time is no problem; the problem is having to write a lot of 
type declarations, plus their representation clauses. There's just much 
more text, more type names, more component names, which to me have 
little benefit. Each of these types and components would be used only 
once, in the Ada code that translates an instruction of that format into 
my internal representation.

> and IMHO they're still
> more readable than a bunch of shifts or multiplies.

I agree, if the shifts and masks would be written in-line, which I don't 
do. I write calls to my "extract field" function instead, which I find 
very readable and easy to compare to the specification.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Interfaces.Shift_Left
  2011-12-18 20:47               ` Interfaces.Shift_Left Niklas Holsti
@ 2011-12-20  0:38                 ` Randy Brukardt
  2011-12-20  2:18                   ` Interfaces.Shift_Left Shark8
                                     ` (2 more replies)
  0 siblings, 3 replies; 22+ messages in thread
From: Randy Brukardt @ 2011-12-20  0:38 UTC (permalink / raw)


"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
news:9l71m2FlhuU1@mid.individual.net...
> On 11-12-16 02:23 , Randy Brukardt wrote:
>> "Niklas Holsti"<niklas.holsti@tidorum.invalid>  wrote in message
>> news:9ktu5mFn31U1@mid.individual.net...
>>> On 11-12-15 00:49 , Randy Brukardt wrote:
...
>>>> Right. This definitely should be done using record representation 
>>>> clauses
>>>> if
>>>> there is a choice.
>>>
>>> I'm sorry to say that I disagree, and now always use the shift-and-mask
>>> method.
>>
>> Might as well write in C then, this sort of code is complete, 
>> unmaintainable
>> junk.
>
> Ooh, harsh words. I'm trying not to take offence.

Sorry, that wasn't really aimed at you. Your application (which has to 
process many foreign machine formats) is highly unusual, and I would not 
want most readers to take away the same "lesson" you learned, because it is 
wrong in general.

But I realize that given the architecture of your system, having a "dirty" 
routine doing the conversion into the internal format might very well be the 
best solution. It's rarely possible to make that sort of code "pretty" 
because it has performance impliciations or just plain messy formats in the 
foreign systems.

...
> Of course I hide the implementation in an "extract field" function with 
> the bit numbers as parameters. My code typically decodes machine 
> instructions from the instruction set of some processor; the user manual 
> of that processor is the specification for my SW; the user manual normally 
> shows the format of a given instruction by a figure of the instruction 
> with the fields indicated by bit numbers; there is an immediate 
> correspondence between this figure and the calls of the "extract field" 
> functions. Very easy to write, check, and maintain, in my experience.

I wouldn't use an "extract field" function in my own code simply because 
Janus/Ada does not do inlining of subprograms. Thus the performance hit of 
such a function would be severe (it was a factor of 3 for code generation, I 
recall.) And thus in my code, this turned into a bunch of multiplies and 
divides, along with a nice ascii version of the diagram from the processor 
manual. It surely would have been better to put the diagram directly in the 
Ada code (we didn't have record rep. clauses in the early days of Janus/Ada, 
or I surely would have done so).

The advantage, of course, is that the instruction description is only in the 
text once (as a record type declaration, which is quite readable), rather 
than twice (bit extracts in whatever form, plus some documentation of what 
they mean).

>>> I used to be charmed by record representation clauses, until I wanted to
>>> write Ada 95 code that was portable between machines with different bit
>>> numbering orders.
>>
>> It's true, that's a problem. Luckily, it's not a real problem in practice
>> for the vast majority of users, since pretty much all popular machines 
>> these
>> days use the same bit numbering.
>
> "All the world is a VAX -- no, an Intel -- no, an Xxx", eh?

Not at all. My understanding is that virtually all recent processors are 
little-endian (and all of the new processors in common use). I believe this 
is driven in part by the need of all machines to interoperate (unlike the 
little islands of the 1960s and 1970s). So I don't think we'll be seeing 
many new host machines using big-endian numbers (there are a few legacy 
systems still around, of course), especially as there is no real advantage 
of one system over the other.

In a sense, this is similar to the 1's complement - 2's complement divide. 
If you have code that only works on 2's complement machines, it really 
doesn't matter anymore, but once upon a time, that would have been a big 
deal. I think we're seeing the same sort of thing with bit numbering and 
byte ordering (BTW, these two things are linked together, it's not sensible 
to swap only one and not the other -- otherwise your integer fields get 
broken into chunks).

So it is not that big of a deal to use one system and ignore the other. 
Unless, of course, you are doing processing on/for one of those legacy 
systems (which seems to be in part your situation, again, your situation 
seems unusual to me).

> I do not want to write programs that have such an implementation 
> dependency. I wouldn't go so far as to call such code "junk", but it would 
> be as bad as assuming that Integer is 32 bits.

As I said above, I think it is more like assuming your machine is 2's 
complement. Not that big of a deal, but it matters if you need absolute 
portability.

....
>>> Another factor in this decision is that in my applications, the raw data
>>> (machine instructions for various processors) can actually have several
>>> different structures (instruction formats), so an approach using record
>>> representation clauses needs as many different record types and 
>>> unchecked
>>> conversions from the raw data (bit-strings or words) to the appropriate
>>> record type. The operational approach entirely avoids these conversions.
>>
>> Of course, the vast majority of Unchecked_Conversions generate no code at
>> all, so these conversions have no run-time impact
>
> Sure, run-time is no problem; the problem is having to write a lot of type 
> declarations, plus their representation clauses. There's just much more 
> text, more type names, more component names, which to me have little 
> benefit. Each of these types and components would be used only once, in 
> the Ada code that translates an instruction of that format into my 
> internal representation.

I view these declarations as a good stand-in for the documentation 
(comments) that I'd otherwise have to write. They're a lot more readable 
than shifts or multiplies!

>> and IMHO they're still
>> more readable than a bunch of shifts or multiplies.
>
> I agree, if the shifts and masks would be written in-line, which I don't 
> do. I write calls to my "extract field" function instead, which I find 
> very readable and easy to compare to the specification.

Obviously, your mileage varies from mine. I presume you're not documenting 
"the specification" in the code, because otherwise you would have to write 
it twice (which would make the record types a lot more attactive). I 
wouldn't allow that in my code (I'm not going to make the reader go fumble 
with books or PDFs to understand the layout!), but of course YMMV. [Your 
extract operation will define the bits involved, but not the meaning, and I 
presume how you use the result will help explain the internal meaning, but 
not the original definition.]

Anyway, let me repeat again: YMMV. Your application works for you, and 
that's fine. I just don't think that you should tell the world (most of 
whose applications are very different from yours) that record represenation 
clauses don't work. Because they're in the top 5 reasons to use Ada, and 
without them, Ada becomes just another programming language (with better 
syntax, but good luck convincing anyone of that).

                                                        Randy.





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

* Re: Interfaces.Shift_Left
  2011-12-20  0:38                 ` Interfaces.Shift_Left Randy Brukardt
@ 2011-12-20  2:18                   ` Shark8
  2011-12-20 10:08                   ` Interfaces.Shift_Left Dmitry A. Kazakov
  2011-12-20 19:38                   ` Interfaces.Shift_Left Niklas Holsti
  2 siblings, 0 replies; 22+ messages in thread
From: Shark8 @ 2011-12-20  2:18 UTC (permalink / raw)


On Dec 19, 6:38 pm, "Randy Brukardt" <ra...@rrsoftware.com> wrote:
>
> Anyway, let me repeat again: YMMV. Your application works for you, and
> that's fine. I just don't think that you should tell the world (most of
> whose applications are very different from yours) that record represenation
> clauses don't work. Because they're in the top 5 reasons to use Ada, and
> without them, Ada becomes just another programming language (with better
> syntax, but good luck convincing anyone of that).
>
>                                                         Randy.

What are the other four?



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

* Re: Interfaces.Shift_Left
  2011-12-20  0:38                 ` Interfaces.Shift_Left Randy Brukardt
  2011-12-20  2:18                   ` Interfaces.Shift_Left Shark8
@ 2011-12-20 10:08                   ` Dmitry A. Kazakov
  2011-12-20 19:38                   ` Interfaces.Shift_Left Niklas Holsti
  2 siblings, 0 replies; 22+ messages in thread
From: Dmitry A. Kazakov @ 2011-12-20 10:08 UTC (permalink / raw)


On Mon, 19 Dec 2011 18:38:53 -0600, Randy Brukardt wrote:

[It is imperative vs. declarative debate]

> Obviously, your mileage varies from mine. I presume you're not documenting 
> "the specification" in the code, because otherwise you would have to write 
> it twice (which would make the record types a lot more attactive).

It must be done anyway, because when it comes to the protocols they are
normally defined not in bits and offsets, but in some quite ugly
quasi-language.

Extraction of bits in an imperative manner as Niklas does, I do, and I bet
many people dealing with protocols do, serves documentation purpose better,
than translation from one cryptic declarative language to another (of Ada
representation clauses).

And fields is just a minor problem. The protocols have lots of other
encoding stuff, which simply cannot be expressed by any clause. E.g. chain
codes, padding, check sums etc.

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



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

* Re: Interfaces.Shift_Left
  2011-12-20  0:38                 ` Interfaces.Shift_Left Randy Brukardt
  2011-12-20  2:18                   ` Interfaces.Shift_Left Shark8
  2011-12-20 10:08                   ` Interfaces.Shift_Left Dmitry A. Kazakov
@ 2011-12-20 19:38                   ` Niklas Holsti
  2011-12-20 20:46                     ` Interfaces.Shift_Left Niklas Holsti
                                       ` (2 more replies)
  2 siblings, 3 replies; 22+ messages in thread
From: Niklas Holsti @ 2011-12-20 19:38 UTC (permalink / raw)


On 11-12-20 02:38 , Randy Brukardt wrote:
> "Niklas Holsti"<niklas.holsti@tidorum.invalid>  wrote in message
> news:9l71m2FlhuU1@mid.individual.net...
>> On 11-12-16 02:23 , Randy Brukardt wrote:
>>> "Niklas Holsti"<niklas.holsti@tidorum.invalid>   wrote in message
>>> news:9ktu5mFn31U1@mid.individual.net...
>>>> On 11-12-15 00:49 , Randy Brukardt wrote:
> ...
>>>>> Right. This definitely should be done using record representation
>>>>> clauses
>>>>> if
>>>>> there is a choice.
>>>>
>>>> I'm sorry to say that I disagree, and now always use the shift-and-mask
>>>> method.
>>>
>>> Might as well write in C then, this sort of code is complete,
>>> unmaintainable junk.
>>
>> Ooh, harsh words. I'm trying not to take offence.
>
> Sorry, that wasn't really aimed at you.

Ok.

> Your application (which has to
> process many foreign machine formats) is highly unusual, and I would not
> want most readers to take away the same "lesson" you learned, because it is
> wrong in general.

I was unclear: I did not mean to claim that one should always avoid 
record representation clauses, only to say that IMO they are not always 
the best solution. I should have written a more balanced comment.

> But I realize that given the architecture of your system, having a "dirty"
> routine doing the conversion into the internal format might very well be the
> best solution.

The "extract field" function is not very dirty; two shift operations on 
an unsigned word. And completely portable (as long as Interfaces defines 
an unsigned type of the required length).

> I wouldn't use an "extract field" function in my own code simply because
> Janus/Ada does not do inlining of subprograms. Thus the performance hit of
> such a function would be severe (it was a factor of 3 for code generation, I
> recall.)

I haven't measured it, but I don't believe that the "extract field" 
operation is an important slow-down for me, even if not inlined. The 
bottle-necks are elsewhere in my app.

An "insert field" operation has more overhead than an "extract field" 
operation. But my application only needs to unpack records with 
bit-fields, not generate them.

> (we didn't have record rep. clauses in the early days of Janus/Ada,
> or I surely would have done so).

Probably I would have used record representation clauses there, too, 
since I assume that Janus/Ada was meant to run on and for Intel 
processors, so there was little cause to fear a change in bit numbering. 
And of course you know exactly how Bit_Order works in Janus/Ada.

Even today, if I were to write an Ada program to run on a particular 
microcontroller and access the on-chip peripheral control registers, I 
would use record representation clauses to describe the structure of 
those registers. The code would probably make many accesses to each 
record component, making a procedural approach more cumbersome, and 
there would be no need for portability with regard to bit numbering, 
since this code would be tied to this microcontroller anyway.

> The advantage, of course, is that the instruction description is only in the
> text once (as a record type declaration, which is quite readable), rather
> than twice (bit extracts in whatever form, plus some documentation of what
> they mean).

I don't duplicate the record specifications (= the target processor user 
manual) in my code. The calls of the "extract field" function occur in 
contexts that give sufficient documentation, IMO. For example, a line like

    Rd => Register (Word, 15, 12),

means that the value of the internal-representation component Rd is 
taken from bits 15..12 in the input Word. (The name "Rd" is the same as 
used in the processor user manual for this field, of course. The 
Register function is a variant of "extract field" that returns the 
proper type for Rd.)

>>>> I used to be charmed by record representation clauses, until I wanted to
>>>> write Ada 95 code that was portable between machines with different bit
>>>> numbering orders.
>>>
>>> It's true, that's a problem. Luckily, it's not a real problem in practice
>>> for the vast majority of users, since pretty much all popular machines
>>> these
>>> days use the same bit numbering.
>>
>> "All the world is a VAX -- no, an Intel -- no, an Xxx", eh?
>
> Not at all. My understanding is that virtually all recent processors are
> little-endian (and all of the new processors in common use).
   ...
> In a sense, this is similar to the 1's complement - 2's complement divide.

I get your point. I don't really know, myself, how the trends are going. 
If big-endian bit-numbering is as rare as 1's complement, you have a 
good point.

> Unless, of course, you are doing processing on/for one of those legacy
> systems (which seems to be in part your situation, again, your situation
> seems unusual to me).

My Ada code was originally written for big-endian SPARC workstations and 
needed porting to little-endian Intel PCs. I believe the SPARC is still 
an actively developed architecture.

> I view these declarations as a good stand-in for the documentation
> (comments) that I'd otherwise have to write.
...
> I presume you're not documenting
> "the specification" in the code, because otherwise you would have to write
> it twice (which would make the record types a lot more attactive).

That's right, I just write comments that reference the existing 
specification doc that defines the record formats, often naming a 
specific chapter, section, or page.

> I wouldn't allow that in my code (I'm not going to make the reader go fumble
> with books or PDFs to understand the layout!), but of course YMMV.

The mileage varies, indeed: I would consider it downright dangerous to 
copy the specs (manually) into the code, since this can introduce 
errors. I don't see any need for a reader to "understand" the layout, 
since the layout has no impact on meaning. If a reader wants to check 
that the code uses the right bit numbers and the right interpretation of 
the fields, it is much better IMO to force the reader to look at the 
original specs.

> [Your extract operation will define the bits involved, but not the
> meaning, and I presume how you use the result will help explain the
> internal meaning, but not the original definition.]

That's right. Each call of an extract operation typically defines the 
value of a component of the internal representation. The meaning of this 
component is documented in the type declarations for the internal 
representation.

> Anyway, let me repeat again: YMMV. Your application works for you, and
> that's fine. I just don't think that you should tell the world (most of
> whose applications are very different from yours) that record represenation
> clauses don't work.

That was not my intent. The original question was something about 
"retrieving a 6-bit signed value from a 32-bit field"; you said that 
record representation clauses "definitely should be used" for this; I 
wanted to protest against the "definitely", with reasons. I think we 
understand each other now.

> Because they're in the top 5 reasons to use Ada,

Is that based on some survey of reasons why Ada is used? That would be 
interesting. I agree with that ranking only for some Ada applications -- 
the traditional embedded, bare-machine programs that access hardware 
registers. Programs that deal with communication protocols may also 
qualify. And even there, I would not put record representation clauses 
close to the top of the 5 top reasons.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Interfaces.Shift_Left
  2011-12-20 19:38                   ` Interfaces.Shift_Left Niklas Holsti
@ 2011-12-20 20:46                     ` Niklas Holsti
  2011-12-20 21:13                       ` Interfaces.Shift_Left Simon Wright
  2011-12-20 21:08                     ` Interfaces.Shift_Left Simon Wright
  2011-12-20 23:36                     ` Interfaces.Shift_Left Randy Brukardt
  2 siblings, 1 reply; 22+ messages in thread
From: Niklas Holsti @ 2011-12-20 20:46 UTC (permalink / raw)


Making a comment on my own post:

On 11-12-20 21:38 , Niklas Holsti wrote:
> On 11-12-20 02:38 , Randy Brukardt wrote:
>>
>> Not at all. My understanding is that virtually all recent processors are
>> little-endian (and all of the new processors in common use).
>
> My Ada code was originally written for big-endian SPARC workstations and
> needed porting to little-endian Intel PCs. I believe the SPARC is still
> an actively developed architecture.

... but I just learned that the newer SPARCs are "bi-endian" and able to 
run in either big- or little-endian mode. So little-endian is gaining, 
which may in the end make little-endian record representation clauses 
portable, in practice. Good if that happens.

-- 
Niklas Holsti
Tidorum Ltd
niklas holsti tidorum fi
       .      @       .



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

* Re: Interfaces.Shift_Left
  2011-12-20 19:38                   ` Interfaces.Shift_Left Niklas Holsti
  2011-12-20 20:46                     ` Interfaces.Shift_Left Niklas Holsti
@ 2011-12-20 21:08                     ` Simon Wright
  2011-12-20 23:26                       ` Interfaces.Shift_Left Randy Brukardt
  2011-12-20 23:36                     ` Interfaces.Shift_Left Randy Brukardt
  2 siblings, 1 reply; 22+ messages in thread
From: Simon Wright @ 2011-12-20 21:08 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> I get your point. I don't really know, myself, how the trends are
> going. If big-endian bit-numbering is as rare as 1's complement, you
> have a good point.

As you noted below, there's SPARC; and in rugged systems there are still
quite a lot of big-endian processors about (6 BE to 8 LE from GE
Intelligent Platforms, for example).



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

* Re: Interfaces.Shift_Left
  2011-12-20 20:46                     ` Interfaces.Shift_Left Niklas Holsti
@ 2011-12-20 21:13                       ` Simon Wright
  0 siblings, 0 replies; 22+ messages in thread
From: Simon Wright @ 2011-12-20 21:13 UTC (permalink / raw)


Niklas Holsti <niklas.holsti@tidorum.invalid> writes:

> Making a comment on my own post:
>
> On 11-12-20 21:38 , Niklas Holsti wrote:
>> On 11-12-20 02:38 , Randy Brukardt wrote:
>>>
>>> Not at all. My understanding is that virtually all recent processors are
>>> little-endian (and all of the new processors in common use).
>>
>> My Ada code was originally written for big-endian SPARC workstations and
>> needed porting to little-endian Intel PCs. I believe the SPARC is still
>> an actively developed architecture.
>
> ... but I just learned that the newer SPARCs are "bi-endian" and able
> to run in either big- or little-endian mode. So little-endian is
> gaining, which may in the end make little-endian record representation
> clauses portable, in practice. Good if that happens.

The same is I believe true of PowerPC and ARM. But it really depends on
the OS - and the peripherals! Dealing with a LE-designed peripheral vs a
BE processor/OS was fun.



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

* Re: Interfaces.Shift_Left
  2011-12-20 21:08                     ` Interfaces.Shift_Left Simon Wright
@ 2011-12-20 23:26                       ` Randy Brukardt
  0 siblings, 0 replies; 22+ messages in thread
From: Randy Brukardt @ 2011-12-20 23:26 UTC (permalink / raw)


"Simon Wright" <simon@pushface.org> wrote in message 
news:m24nwv7xxz.fsf@pushface.org...
> Niklas Holsti <niklas.holsti@tidorum.invalid> writes:
>
>> I get your point. I don't really know, myself, how the trends are
>> going. If big-endian bit-numbering is as rare as 1's complement, you
>> have a good point.
>
> As you noted below, there's SPARC; and in rugged systems there are still
> quite a lot of big-endian processors about (6 BE to 8 LE from GE
> Intelligent Platforms, for example).

Yes, they're about, but mostly they're older designs. (At least, that is the 
way it was explained to me; I haven't studied processors for years, early 
SPARC being the last one that I coded for.)

                                     Randy.





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

* Re: Interfaces.Shift_Left
  2011-12-20 19:38                   ` Interfaces.Shift_Left Niklas Holsti
  2011-12-20 20:46                     ` Interfaces.Shift_Left Niklas Holsti
  2011-12-20 21:08                     ` Interfaces.Shift_Left Simon Wright
@ 2011-12-20 23:36                     ` Randy Brukardt
  2011-12-21  0:44                       ` Interfaces.Shift_Left Georg Bauhaus
  2011-12-21  7:23                       ` Interfaces.Shift_Left AdaMagica
  2 siblings, 2 replies; 22+ messages in thread
From: Randy Brukardt @ 2011-12-20 23:36 UTC (permalink / raw)


"Niklas Holsti" <niklas.holsti@tidorum.invalid> wrote in message 
news:9lc6bqFfhrU1@mid.individual.net...
...
> Is that based on some survey of reasons why Ada is used? That would be 
> interesting. I agree with that ranking only for some Ada applications -- 
> the traditional embedded, bare-machine programs that access hardware 
> registers. Programs that deal with communication protocols may also 
> qualify. And even there, I would not put record representation clauses 
> close to the top of the 5 top reasons.

No, just my gut feeling. At lot of the things that make Ada unique aren't 
things that you really can sell to outsiders (that is, non-Ada users that 
might be interested in using Ada).

For instance, I find that the syntax of Ada has just the right level of 
verbosity (not so much as to be a pain, not so little as to allow one to 
write something other than what they meant to be legal). Most languages 
(especially C-based syntaxes) don't have enough. But I doubt I'm going to 
convince many others of that, at least not until they've had the experience 
of using Ada for a while.

Another truly valuable feature of Ada is the complete coverage rule for case 
statements, aggregates, and the like. The amount of time that it can save 
when adding a new kind of thing (enumeration literal, record component, 
etc.) is amazing. (As the compiler points out the places you've forgotten to 
change; errors of omission are by far the hardest to find.) But again, this 
is a tough sell until you've had the compiler find errors for you.

Most of the big picture things (like packages and generics) are available in 
other languages, and Ada's advantages with them are subtle (physical 
separation of interface and implementation; the contract model of 
generic) -- these are also not that easy to describe to potential users.

The net effect of all of these smallish things leads to a much bigger 
advantage when put together -- but there is nothing "sexy" about any of 
them. Representation clauses in general at least are easy to explain and 
almost everybody remembers times when they would have preferred that the 
compiler did the packing/unpacking of fields. So they make a good lead for 
the advantages of Ada.

                                      Randy.





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

* Re: Interfaces.Shift_Left
  2011-12-20 23:36                     ` Interfaces.Shift_Left Randy Brukardt
@ 2011-12-21  0:44                       ` Georg Bauhaus
  2011-12-21  7:23                       ` Interfaces.Shift_Left AdaMagica
  1 sibling, 0 replies; 22+ messages in thread
From: Georg Bauhaus @ 2011-12-21  0:44 UTC (permalink / raw)


On 21.12.11 00:36, Randy Brukardt wrote:

>
> Another truly valuable feature of Ada is the complete coverage rule for case
> statements, aggregates, and the like. The amount of time that it can save
> when adding a new kind of thing (enumeration literal, record component,
> etc.) is amazing. (As the compiler points out the places you've forgotten to
> change; errors of omission are by far the hardest to find.) But again, this
> is a tough sell until you've had the compiler find errors for you.

Coverage of all cases is already being sold with other, uhum, languages:
The mechanism appears to be effective, but technically and economically,
and is catering to both types of programmers: those who love to know the
sharpness of C tools and to software engineers (pragmatic style).
  "Static analysis" allows the compilers to warn about cases not
covered in switches in imperative C languages. Similarly, warnings about
argument pattern matching not being exhaustive is about the same for the
ML family of functional languages; advanced compilers will issue the
warnings when translating the definition of function by cases.
   Thus, the programmers who know what they are doing (who therefore do
not need Ada) can continue to know what they are doing *and* turn on warnings
about coverage *as* *needed*.  No bullying compiler is in the way, as is always
the case with Ada.(*)
   When no one is listening, the makers of static analysis tools might even
note that coverage rules were always present in Ada. Creating and using analysis
tools adds flexibility, though, if rules are left informal in the
respective virtual languages that the tools will establish.
So each of the vendors can define their own informal language tacked onto the
respective language.
   Everyone is happy, members of the virtual in-group of tool users share in
a gentlemen's agreement, and no language standard gets in the way of
creative business.

All of this is possible without dragging in that dated, expensive
government language. :-)

__
(*) Reminds me of a story told by Richard Riehle about a big floor
cleaning device that was really easy to push in one direction or other
but only if you learn how to operate the massive thing.  Then, a single
finger would suffice.
But why buy a floor cleaning device if brooms and rags are so much cheaper?



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

* Re: Interfaces.Shift_Left
  2011-12-20 23:36                     ` Interfaces.Shift_Left Randy Brukardt
  2011-12-21  0:44                       ` Interfaces.Shift_Left Georg Bauhaus
@ 2011-12-21  7:23                       ` AdaMagica
  1 sibling, 0 replies; 22+ messages in thread
From: AdaMagica @ 2011-12-21  7:23 UTC (permalink / raw)


On 21 Dez., 00:36, "Randy Brukardt" <ra...@rrsoftware.com> wrote:

> ... At lot of the things that make Ada unique aren't
> things that you really can sell to outsiders (that is, non-Ada users that
> might be interested in using Ada).

I think the paper
John W. McCormick\vUniversity of Northern Iowa\vSoftware Engineering
Education: On the Right Track
http://www.crosstalkonline.org/storage/issue-archives/2000/200008/200008-McCormick.pdf
has shown that the following basic Ada features were vital for the
success of Ada vs. C:

Modeling of Scalar Objects
  Strong Typing
  Range Constraints
  Enumerations
  Attributes like 'Range ...
  No need for Pointers
Parameter modes for data flow
Named Parameter Assoziation
Flexible array index ranges

But are these sexy? You have to have used them to estimate the value...



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

end of thread, other threads:[~2011-12-21  7:29 UTC | newest]

Thread overview: 22+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-12-12 22:30 Interfaces.Shift_Left awdorrin
2011-12-12 23:34 ` Interfaces.Shift_Left Simon Wright
2011-12-13  1:36   ` Interfaces.Shift_Left Adam Beneschan
2011-12-13 12:00 ` Interfaces.Shift_Left Brian Drummond
2011-12-13 13:15   ` Interfaces.Shift_Left awdorrin
2011-12-13 21:48     ` Interfaces.Shift_Left Randy Brukardt
2011-12-14 18:28       ` Interfaces.Shift_Left awdorrin
2011-12-14 22:49         ` Interfaces.Shift_Left Randy Brukardt
2011-12-15  9:51           ` Interfaces.Shift_Left Niklas Holsti
2011-12-16  0:23             ` Interfaces.Shift_Left Randy Brukardt
2011-12-18 20:47               ` Interfaces.Shift_Left Niklas Holsti
2011-12-20  0:38                 ` Interfaces.Shift_Left Randy Brukardt
2011-12-20  2:18                   ` Interfaces.Shift_Left Shark8
2011-12-20 10:08                   ` Interfaces.Shift_Left Dmitry A. Kazakov
2011-12-20 19:38                   ` Interfaces.Shift_Left Niklas Holsti
2011-12-20 20:46                     ` Interfaces.Shift_Left Niklas Holsti
2011-12-20 21:13                       ` Interfaces.Shift_Left Simon Wright
2011-12-20 21:08                     ` Interfaces.Shift_Left Simon Wright
2011-12-20 23:26                       ` Interfaces.Shift_Left Randy Brukardt
2011-12-20 23:36                     ` Interfaces.Shift_Left Randy Brukardt
2011-12-21  0:44                       ` Interfaces.Shift_Left Georg Bauhaus
2011-12-21  7:23                       ` Interfaces.Shift_Left AdaMagica

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