February 04, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a3gmau$1m6r$1@digitaldaemon.com...
> "Walter" <walter@digitalmars.com> wrote in message news:a3gh39$1k44$1@digitaldaemon.com...
>
> > "Pavel Minayev" <evilone@omen.ru> wrote in message news:a3gft8$1jhm$1@digitaldaemon.com...
> > > It would be even better if variants
> > > were COM-compliant - one more step to complete COM support.
> >
> > Why not just use the COM variant struct?
>
> Because you can't just assign a number or a string to it, nor you can do arithmetics with them, or pass them to functions expecting strict types etc.

You can using the union members.



February 04, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a3lkv0$spm$1@digitaldaemon.com...
> "D" <s_nudds@hotmail.com> wrote in message news:a3lef2$no9$1@digitaldaemon.com...
>
> > Varints are an error waiting to happen.  Code reliability must trump
silly
> > convenience features.
>
> Don't like 'em - don't use 'em.
> Also, variants are still better that printf() anarchy.

I actually like printf's anarchy <g>. I pretty much use printf only for debugging anyway, and don't worry about the occaisional mistake.

> And what about multi-type arrays?

An array of union's. At least with a union you can restrict the variety of possible types.


February 04, 2002
Pavel Minayev wrote:

> Don't like 'em - don't use 'em.
> Also, variants are still better that printf() anarchy.

D could support typesafe printf (or any varags function).  I had an idea for it (the compiler expands varags calls into recursive ones), but it added some noticable runtime overhead and compiler complexity.

The example you gave makes me feel extremely uncomfortable.  Maybe I've just been in C too long, but I *really* want to know the type that is returned to me (even if I know it's a union)...otherwise, I start to break out in hives.

--
The Villagers are Online! villagersonline.com

.[ (the fox.(quick,brown)) jumped.over(the dog.lazy) ]
.[ (a version.of(English).(precise.more)) is(possible) ]
?[ you want.to(help(develop(it))) ]


February 04, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a3lp87$v31$3@digitaldaemon.com...

> > Because you can't just assign a number or a string to it, nor you can do arithmetics with them, or pass them to functions expecting strict types etc.
>
> You can using the union members.

Yep, right. Variants just make life easier. =)


February 04, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a3lp87$v31$4@digitaldaemon.com...

> I actually like printf's anarchy <g>. I pretty much use printf only for debugging anyway, and don't worry about the occaisional mistake.

Sorta funny... an access violation in your debug code of you make an error occasionally =)

> > And what about multi-type arrays?
>
> An array of union's. At least with a union you can restrict the variety of possible types.

Variant would exactly that - an {int,void*,char[],extended} union, only with
the "type" field and overloaded operators. Also, how'd you call the
sample print() function I suggested with unions, easily?



February 04, 2002
"Russ Lewis" <spamhole-2001-07-16@deming-os.org> wrote in message news:3C5ED021.85DE2B4A@deming-os.org...

> The example you gave makes me feel extremely uncomfortable.  Maybe I've
just
> been in C too long, but I *really* want to know the type that is returned
to me
> (even if I know it's a union)...otherwise, I start to break out in hives.

For languages with variants, there is usually some way to find the type of the variant. In Delphi it's VarType, AFAIK, returning vtString, vtInteger, vtFloat... etc. So you can always control it.

BTW it's funny that there is a "variant" for C++ - boost::any (http://www.boost.org/libs/any/index.html). Here's what the author says about it: "There are times when a generic (in the sense of general as opposed to template-based programming) type is needed: variables that are truly variable, accommodating values of many other more specific types rather than C++'s normal strict and static types...". Not much I can add to it. If I could see something like this: "Discriminated types that contain values of different types but do not attempt conversion between them, i.e. 5 is held strictly as an int and is not implicitly convertible either to "5" or to 5.0. Their indifference to interpretation but awareness of type effectively makes them safe, generic containers of single values, with no scope for surprises from ambiguous conversions...", I'd be really happy.


February 04, 2002
"Walter" <walter@digitalmars.com> wrote in message news:a3lp86$v31$2@digitaldaemon.com...

> Define a way to convert each type to a string. A string is what you want anyway for console I/O.

So, what's this way?

> > > unanswerable issues like what do you do when you add a float and a
> string?
> >     throw TypeMismatch;
>
> Unfortunately, that's not how COM works.

Forget about COM, then. Make your own, safer and better variant. It'd still be very useful.

> Then it really isn't that useful. Arggh.

We still have typesafe varargs and variant arrays. It worths it, IMO.

> You name which union member is the one you're initializing too.

You mean, something like that?

    print([{i:666}, {f:123}, {s:"Hello, world!"}]);

Still not very well, but acceptable. At least it's better
than printf().

Also, when will we get array constants?


February 05, 2002
> "D" <s_nudds@hotmail.com> wrote in message
> > Varints are an error waiting to happen.  Code reliability must trump
silly
> > convenience features.

Pavel Minayev <evilone@omen.ru> wrote in message news:a3lkv0$spm$1@digitaldaemon.com...
> Don't like 'em - don't use 'em.
> Also, variants are still better that printf() anarchy.

Can I sue you when your program crashes?



February 05, 2002
"Pavel Minayev" <evilone@omen.ru> wrote in message news:a3mr4l$1hrf$1@digitaldaemon.com...
> Also, when will we get array constants?

When I spend less time reading this newsgroup and more time working <g>.


February 05, 2002
Pavel Minayev <evilone@omen.ru> wrote in message news:a3lkv0$spm$1@digitaldaemon.com...
> Also, variants are still better that printf() anarchy.

Only if you rid the language of the printf statment.

What you are really saying is that varints simplify the passing of multiple variables of indeterminate type to a function.

They do. To the extent that youi don't have to worry about variable type as long as all your variables are the same size.  You still have the issue of passing multiple variables though.

The better solution of course, is to abandon the C method of passing muliple variables to a function and create something more rational.

I would define a protocol whereby the called variable argument function
would be provided with the argument count and a single pointer to a
structure holding the data that was passed.  The format of that structure
would be...
with the untyped ptr being passed so that varcount is at addres p-2.  In the
following example all ints wouild be passed as the size int64, but that
requirement isn't necessary.

struct
  int 16 varcount
  int 16 vartype,  variable
   ...
end struct

Here is how I would build a string with such a function.

In some language header somewhere...

----------------------------
enum vartype
         int1    = 0x000010000
         int2  = 0x000010001
         int4  = 0x000010010
         int8  = 0x000010011
         sint1   = 0x000011000
         sint2 = 0x000011001
         sint4 = 0x000011010
         sint8 = 0x000011011
         float   =  0x000110000
         dfloat  = 0x000110001
         efloat  = 0x000110010
         ptr     =  0x001000000
         dptr    = 0x001000001
         bool    =  0x010000000
         const   =  0x010000001
         char  =   0x100000000
         wchar = 0x100000001
         string =   0x100000100
         integer = sint1
         signed = sint1 xor sint1
end enum
-----------------------


/-----------------------------------------------
/ Print function using variable number of args
/ Call with variable number of args any type, signed/unsigned int, ptr,
string
/ Returns success or fail if invalid variable passed
/
/ Call syntax
/        print a,b,c...
/
/ Uses library functions convet int/signed int to string for all int sizes
/
/ Compiler must ensure arg count < 65536


define op int2 .is const =  ((int2 & vartype.const) <> 0)

define fail = false
define success = true

bool print(int2 count, void *p)  VariableArguments
int2  vartype
string outstring

outstring = ""

   do while (count > 0)
      vartype =  *p; p += sizeof(vartype)

      SelectCase vartype
           case  vartype .is integer
               if (vartype is signed) then
                  SelectCase vartype
                     case sint1
                         outstring += cvint1str((int1) *p))
                     case sint2
                         outstring += cviint2str((int2) *p))
                     case sint4
                         outstring += cvint4str((int4) *p))
                     case sint8
                         outstring += cvint8str((int8) *p))
                  EndSelect
               else
                  SelectCase vartype
                     case int8
                         outstring += cvsint1str((int1) *p))
                     case int16
                         outstring += cvsint2str((int2) *p))
                     case int32
                         outstring += cvsint4str((int4) *p))
                     case int64
                         outstring += cvsint8str((int8) *p))
                  EndSelect
               endif

           case  vartype .is ptr
                 outstring += cvint8str((int8) *p))
           case  vartype .is string
                 outstring += (string)*p
           case else
                return fail
         EndSelect

        p +=  sizeof(p)
        count--
   loop

   ConStrOut demostring
   return success

end print


Now lets say you just wanted to compute the average of a bunch of numbers passed as int2 arguments....


/---------------------------------------------------------------------------
----
/ Average - Computes average of a variable number of args passed as params
/ Call with bool error = fail if arg error
/                                   success otherwise
/                       variable number of int2 args
/ Returns average as an int4
/
/ Call syntax
/        average error,a,b,c...
/
/ Compiler must ensure arg count < 65536

int4 average (bool *error, int2 icount, void *p)  VariableArguments
int2  vartype
int2  count = icount
int4 rtnval = 0

   *error = true
   if icount = 0 then return -1

   do while (count > 0)
       vartype =  *p; p += sizeof(vartype)
       if !(vartype is int2) then return -1
       rtnval += (int2) *p
       p +=  sizeof(p)
/      p + = sizeof(int2)                                  / If you elect to
have the structure packed.
       count--
   loop

  *error = false
   return rtnval/icount

end average


To make the call to the variable argument function, the following
instructions would be issued.
The compiler knows how many params there are = (n).  For a 64 bit CPU...

     mpush <pn,type pn>
     mpush <pn-1,type pn-1>
     mpush <pn-2,typepn-2>
     ...
     mpush <p1,typep1>
     mpush <count,sp,count>            ; perhaps mpush <count,sp-2,count>
     call ftn
     add sp,10*n+12




Pavel Minayev <evilone@omen.ru> wrote in message news:a3lkv0$spm$1@digitaldaemon.com...
> And what about multi-type arrays?

Since you don't have varints, youi don't have varint arrays.  Quite obvious. Why do you pretend that you need them?