1. object(x) rethink

The Euphoria docs tell me that object(x) always returns True.  That makes it a
bit useless. Especially since if x is NOT an object it crashes Euphoria!

Would it not be better if object(x) returned True if x was an object and False
if x either was not an object (i.e. something else like a function) or, and
this is what I would like, if x had not yet been assigned a value so, even
though
it might have been declared, it is valueless.

This should be very easy to implement - just return False rather than crashing!

It would be useful for modules which can then detect a first call and initiate
variables, without needing an explicit initialisation call or putting the
assignments in where the variables are declared.

So what do you worthy pundits think?

new topic     » topic index » view message » categorize

2. Re: object(x) rethink

Andy Drummond wrote:
> 
> The Euphoria docs tell me that object(x) always returns True.  That makes it
> a
> bit useless. Especially since if x is NOT an object it crashes Euphoria!
> 
> Would it not be better if object(x) returned True if x was an object and False
> if x either was not an object (i.e. something else like a function) or, and
> this is what I would like, if x had not yet been assigned a value so, even
> though
> it might have been declared, it is valueless.
> 
> This should be very easy to implement - just return False rather than
> crashing!
> 
> It would be useful for modules which can then detect a first call and initiate
> variables, without needing an explicit initialisation call or putting the
> assignments in where the variables are declared.
> 
> So what do you worthy pundits think?

Hi Andy,

I think that object(x) must be true if x was *declared*
as object, and now it is true for any declaration of x,
which is unexpected behaviour.
New behaviour (true if declared) may be more useful than
old one, which is just dummy and only can confuse people.

Regards,
Igor Kachan
kinz at peterlink.ru

new topic     » goto parent     » topic index » view message » categorize

3. Re: object(x) rethink

object useless????

----------------------------------------------------------------------
A variable must be declared as an object in order to determine what
type it is.

  object x
  
  if sequence(x) then
    puts(1, "variable is a sequence")
  end if
  
  if integer(x)
    puts(1, "variable is an integer")
  end if
  
----------------------------------------------  
  doeumentation for gets() from library.doc
----------------------------------------------
  

Example 1:

              sequence buffer
              object line
              integer fn
              
              -- read a text file into a sequence
              fn = open("myfile.txt", "r")
              if fn = -1 then
                  puts(1, "Couldn't open myfile.txt\n")
                  abort(1)
              end if
              
              buffer = {}
              while 1 do
                  line = gets(fn)
                  if atom(line) then
                      exit   -- -1 is returned at end of file
                  end if
                  buffer = append(buffer, line)
              end while

new topic     » goto parent     » topic index » view message » categorize

4. Re: object(x) rethink

Bill Reed wrote:
 
> 
> object useless????
> 
> ----------------------------------------------------------------------
> A variable must be declared as an object in order to determine what
> type it is.
> 
>   object x
>   
>   if sequence(x) then
>     puts(1, "variable is a sequence")
>   end if
>   
>   if integer(x)
>     puts(1, "variable is an integer")
>   end if
>   
> ----------------------------------------------  
>   doeumentation for gets() from library.doc
> ----------------------------------------------
>   
> 
> Example 1:
> 
>               sequence buffer
>               object line
>               integer fn
>               
>               -- read a text file into a sequence
>               fn = open("myfile.txt", "r")
>               if fn = -1 then
>                   puts(1, "Couldn't open myfile.txt\n")
>                   abort(1)
>               end if
>               
>               buffer = {}
>               while 1 do
>                   line = gets(fn)
>                   if atom(line) then
>                       exit   -- -1 is returned at end of file
>                   end if
>                   buffer = append(buffer, line)
>               end while

Hi Bill,

Try please:
integer i   i= 1
atom a      a= 2
sequence s  s={3}
object x    x={4,{5}}

if object(i) then ? i end if
if object(a) then ? a end if
if object(s) then ? s end if
if object(x) then ? x end if


Is *object()*, not *object*, useful?

This *object()* is just a dummy function now.
It stands just for some 'symmetry' with integer(),
atom() and sequence() functions.

Do you see now?

Regards,
Igor Kachan
kinz at peterlink.ru

new topic     » goto parent     » topic index » view message » categorize

5. Re: object(x) rethink

Igor Kachan wrote:
> 
> Bill Reed wrote:
>  
> > 
> > object useless????
> > 
> > ----------------------------------------------------------------------
> > A variable must be declared as an object in order to determine what
> > type it is.
> > 
> >   object x
> >   
> >   if sequence(x) then
> >     puts(1, "variable is a sequence")
> >   end if
> >   
> >   if integer(x)
> >     puts(1, "variable is an integer")
> >   end if
> >   
> > ----------------------------------------------  
> >   doeumentation for gets() from library.doc
> > ----------------------------------------------
> >   
> > 
> > Example 1:
> > 
> >               sequence buffer
> >               object line
> >               integer fn
> >               
> >               -- read a text file into a sequence
> >               fn = open("myfile.txt", "r")
> >               if fn = -1 then
> >                   puts(1, "Couldn't open myfile.txt\n")
> >                   abort(1)
> >               end if
> >               
> >               buffer = {}
> >               while 1 do
> >                   line = gets(fn)
> >                   if atom(line) then
> >                       exit   -- -1 is returned at end of file
> >                   end if
> >                   buffer = append(buffer, line)
> >               end while
> 
> Hi Bill,
> 
> Try please:
> }}}
<eucode>
> integer i   i= 1
> atom a      a= 2
> sequence s  s={3}
> object x    x={4,{5}}
> 
> if object(i) then ? i end if
> if object(a) then ? a end if
> if object(s) then ? s end if
> if object(x) then ? x end if
> </eucode>
{{{

> 
> Is *object()*, not *object*, useful?
> 
> This *object()* is just a dummy function now.
> It stands just for some 'symmetry' with integer(),
> atom() and sequence() functions.
> 
> Do you see now?
> 
> Regards,
> Igor Kachan
> kinz at peterlink.ru


Sure, integer, atom, and sequences are *objects*, 
but not all objects are sequences, and 
not all objects are atoms and 
not all objects are integers.

I don't check for "if object(x)" or "if not object(x)"

If I declare an object as a sequence, and one time it becomes an an integer,
I get a "type_check failure".  I can assign anything to an object, but I
can't assign an integer to a sequence.

  object x

  x = "abc"      -- ok
  x = -1         -- ok

But:

  sequence x
  
  x = "abc"       -- ok
  x = -1          -- type_check error, x is -1

To fix:

  object o
  sequence s
  integer i
  atom a

  o = "abc"
  o = -1
  o = 5.3

  if sequence(o) then
    s = o
  elsif integer(o) then
    i = o
  elsif atom(o) then
    a = o
  end if


Bill

new topic     » goto parent     » topic index » view message » categorize

6. Re: object(x) rethink

Bill Reed wrote:
 
[snip]

> Sure, integer, atom, and sequences are *objects*, 
> but not all objects are sequences, and 
> not all objects are atoms and 
> not all objects are integers.

Yes, but we are talking just about types of
variables here.
integer i   -- it can be the integer value only
atom a      -- it can be integer and floating
sequence s  -- its elements can be any type, including object type
object x    -- it can be any type at all


> I don't check for "if object(x)" or "if not object(x)"

Ok, but why not to check if variable is type of "object"
or it is not?
 
> If I declare an object as a sequence, and one time it becomes an an integer,
> I get a "type_check failure".  I can assign anything to an object, but I
> can't assign an integer to a sequence.

There is some confusion in "declare an object as a sequence".
Let us say "declare a variable as object" or 
"declare a variable as sequence" etc.

Then, you *can* assign an integer to a sequence using
indexing or slicing.

Try please:
sequence s
integer i i=5
s = {1,2,3,4,{5,5,5,5},6,7}
? s
s[5] = i
? s -- sequence {5,5,5,5} is integer 5 now

 
> }}}
<eucode>
> 
>   object x
> 
>   x = "abc"      -- ok
>   x = -1         -- ok
> 
> But:
> 
>   sequence x
>   
>   x = "abc"       -- ok
>   x = -1          -- type_check error, x is -1
> 
> To fix:
> 
>   object o
>   sequence s
>   integer i
>   atom a
> 
>   o = "abc"
>   o = -1
>   o = 5.3
> 
>   if sequence(o) then
>     s = o
>   elsif integer(o) then
>     i = o
>   elsif atom(o) then
>     a = o
>   end if
> </eucode>
{{{


Ok, but why not to have object(o) is true only
if variable o was declared as object?

Regards,
Igor Kachan
kinz at peterlink.ru

new topic     » goto parent     » topic index » view message » categorize

7. Re: object(x) rethink

Bill Reed wrote:
> 
> Igor Kachan wrote:
> > 
> > Bill Reed wrote:
> >  
> > > 
> > > object useless????
> > > 
> > > ----------------------------------------------------------------------
> > > A variable must be declared as an object in order to determine what
> > > type it is.
> > > 
> > >   object x
> > >   
> > >   if sequence(x) then
> > >     puts(1, "variable is a sequence")
> > >   end if
> > >   
> > >   if integer(x)
> > >     puts(1, "variable is an integer")
> > >   end if
> > >   
> > > ----------------------------------------------  
> > >   doeumentation for gets() from library.doc
> > > ----------------------------------------------
> > >   
> > > 
> > > Example 1:
> > > 
> > >               sequence buffer
> > >               object line
> > >               integer fn
> > >               
> > >               -- read a text file into a sequence
> > >               fn = open("myfile.txt", "r")
> > >               if fn = -1 then
> > >                   puts(1, "Couldn't open myfile.txt\n")
> > >                   abort(1)
> > >               end if
> > >               
> > >               buffer = {}
> > >               while 1 do
> > >                   line = gets(fn)
> > >                   if atom(line) then
> > >                       exit   -- -1 is returned at end of file
> > >                   end if
> > >                   buffer = append(buffer, line)
> > >               end while
> > 
> > Hi Bill,
> > 
> > Try please:
> > }}}
<eucode>
> > integer i   i= 1
> > atom a      a= 2
> > sequence s  s={3}
> > object x    x={4,{5}}
> > 
> > if object(i) then ? i end if
> > if object(a) then ? a end if
> > if object(s) then ? s end if
> > if object(x) then ? x end if
> > </eucode>
{{{

> > 
> > Is *object()*, not *object*, useful?
> > 
> > This *object()* is just a dummy function now.
> > It stands just for some 'symmetry' with integer(),
> > atom() and sequence() functions.
> > 
> > Do you see now?
> > 
> > Regards,
> > Igor Kachan
> > kinz at peterlink.ru
> 
> 
> Sure, integer, atom, and sequences are *objects*, 
> but not all objects are sequences, and 
> not all objects are atoms and 
> not all objects are integers.
> 
> I don't check for "if object(x)" or "if not object(x)"
> 
> If I declare an object as a sequence, and one time it becomes an an integer,
> I get a "type_check failure".  I can assign anything to an object, but I
> can't assign an integer to a sequence.
> 
> }}}
<eucode>
> 
>   object x
> 
>   x = "abc"      -- ok
>   x = -1         -- ok
> 
> But:
> 
>   sequence x
>   
>   x = "abc"       -- ok
>   x = -1          -- type_check error, x is -1
> 
> To fix:
> 
>   object o
>   sequence s
>   integer i
>   atom a
> 
>   o = "abc"
>   o = -1
>   o = 5.3
> 
>   if sequence(o) then
>     s = o
>   elsif integer(o) then
>     i = o
>   elsif atom(o) then
>     a = o
>   end if
> </eucode>
{{{

> 
> Bill

Hi, Bill.
You are missing the point.
Declaring a variable as an object is very useful, no doubt. I routinely use
"object x" the way you explained.
Andy's proposal is that, as object(x) always yields true or crashes,
 it should be changed to somewhat more useful. I agree with him.
Best regards.

new topic     » goto parent     » topic index » view message » categorize

8. Re: object(x) rethink

I think you completely miss the point with generic type.
There is no point testing if a variable is of type 'object' as all variables
hold an object.
The object data type is there as a generic container and as is, it is very
usefull.
It is right to say that it is useless to write something like:

if object(x) then...

But for the coherance of the language this must be a valid declaration and must
behave like any other datatype validation.
There is nothing to change in the language here. All language that use generic
type behave the same way.
In OOP for exemple there is alway a generic class from which all other classes
are derived and if you test any class to know if it is of that generic the answer
will allways be TRUE, like in euphoria.
This coherent in syntax and in semantic.


regards,
Jacques Deschênes
 

Ricardo Forno wrote:
> 
> Bill Reed wrote:
> > 
> > Igor Kachan wrote:
> > > 
> > > Bill Reed wrote:
> > >  
> > > > 
> > > > object useless????
> > > > 
> > > > ----------------------------------------------------------------------
> > > > A variable must be declared as an object in order to determine what
> > > > type it is.
> > > > 
> > > >   object x
> > > >   
> > > >   if sequence(x) then
> > > >     puts(1, "variable is a sequence")
> > > >   end if
> > > >   
> > > >   if integer(x)
> > > >     puts(1, "variable is an integer")
> > > >   end if
> > > >   
> > > > ----------------------------------------------  
> > > >   doeumentation for gets() from library.doc
> > > > ----------------------------------------------
> > > >   
> > > > 
> > > > Example 1:
> > > > 
> > > >               sequence buffer
> > > >               object line
> > > >               integer fn
> > > >               
> > > >               -- read a text file into a sequence
> > > >               fn = open("myfile.txt", "r")
> > > >               if fn = -1 then
> > > >                   puts(1, "Couldn't open myfile.txt\n")
> > > >                   abort(1)
> > > >               end if
> > > >               
> > > >               buffer = {}
> > > >               while 1 do
> > > >                   line = gets(fn)
> > > >                   if atom(line) then
> > > >                       exit   -- -1 is returned at end of file
> > > >                   end if
> > > >                   buffer = append(buffer, line)
> > > >               end while
> > > 
> > > Hi Bill,
> > > 
> > > Try please:
> > > }}}
<eucode>
> > > integer i   i= 1
> > > atom a      a= 2
> > > sequence s  s={3}
> > > object x    x={4,{5}}
> > > 
> > > if object(i) then ? i end if
> > > if object(a) then ? a end if
> > > if object(s) then ? s end if
> > > if object(x) then ? x end if
> > > </eucode>
{{{

> > > 
> > > Is *object()*, not *object*, useful?
> > > 
> > > This *object()* is just a dummy function now.
> > > It stands just for some 'symmetry' with integer(),
> > > atom() and sequence() functions.
> > > 
> > > Do you see now?
> > > 
> > > Regards,
> > > Igor Kachan
> > > kinz at peterlink.ru
> > 
> > 
> > Sure, integer, atom, and sequences are *objects*, 
> > but not all objects are sequences, and 
> > not all objects are atoms and 
> > not all objects are integers.
> > 
> > I don't check for "if object(x)" or "if not object(x)"
> > 
> > If I declare an object as a sequence, and one time it becomes an an integer,
> > I get a "type_check failure".  I can assign anything to an object, but I
> > can't assign an integer to a sequence.
> > 
> > }}}
<eucode>
> > 
> >   object x
> > 
> >   x = "abc"      -- ok
> >   x = -1         -- ok
> > 
> > But:
> > 
> >   sequence x
> >   
> >   x = "abc"       -- ok
> >   x = -1          -- type_check error, x is -1
> > 
> > To fix:
> > 
> >   object o
> >   sequence s
> >   integer i
> >   atom a
> > 
> >   o = "abc"
> >   o = -1
> >   o = 5.3
> > 
> >   if sequence(o) then
> >     s = o
> >   elsif integer(o) then
> >     i = o
> >   elsif atom(o) then
> >     a = o
> >   end if
> > </eucode>
{{{

> > 
> > Bill
> 
> Hi, Bill.
> You are missing the point.
> Declaring a variable as an object is very useful, no doubt. I routinely use
> "object x" the way you explained.
> Andy's proposal is that, as object(x) always yields true or crashes,
>  it should be changed to somewhat more useful. I agree with him.
> Best regards.

new topic     » goto parent     » topic index » view message » categorize

9. Re: object(x) rethink

jacques deschênes wrote:
> 
> But for the coherance of the language this must be a valid declaration and
> must
> behave like any other datatype validation.
> There is nothing to change in the language here. All language that use generic
> type behave the same way.

I think, if I've understood Andy correctly, he is simply proposing that
object(x) returns true in all cases except when x has not been assigned a value,
in which case it returns false.

I agree with this as x is not truly an object until it has a value, until then
it is only a notion.

Perl has this concept with if defined(x), and even undef(x) to make x be
"unassigned".

The question as to whether to change the behaviour of the object type test comes
down to (IMHO) whether it is easy to do, whether a significant amount of code
relies on the current behaviour... oh and of course someone to actually
change/test/document the code :)

Gary

new topic     » goto parent     » topic index » view message » categorize

10. Re: object(x) rethink

jacques deschênes wrote:
> 
> I think you completely miss the point with generic type.
> There is no point testing if a variable is of type 'object' as all variables
> hold an object.
> The object data type is there as a generic container and as is, it is very
> usefull.
> It is right to say that it is useless to write something like:
> 
> if object(x) then...
> 
> But for the coherance of the language this must be a valid declaration and
> must
> behave like any other datatype validation.
> There is nothing to change in the language here. All language that use generic
> type behave the same way.
> In OOP for exemple there is alway a generic class from which all other classes
> are derived and if you test any class to know if it is of that generic the
> answer
> will allways be TRUE, like in euphoria.
> This coherent in syntax and in semantic.
> 
> 
> regards,
> Jacques Deschênes
>  

I remember discussing whether "object(x)" should return a false value for
uninitialized variables. It seems reasonable to me, and I was going to reply
yesterday.

However I remember that Rob had an objection and it took a little forum
searching to remember why. Basically it is that whether an object has been
initialized or not is kind of a "meta" concept.

I dunno. I can see it both ways. But changing the behavior would make it
inconsistent with integer(x) and sequence(x) unless those, too, returned false
for uninitialized variables.

And since procedures are different from variables in Euphoria, I don't know if
"object(func_name)" makes much sense, especially since you can use or wrap
routine_id().


--
A complex system that works is invariably found to have evolved from a simple
system that works.
--John Gall's 15th law of Systemantics.

"Premature optimization is the root of all evil in programming."
--C.A.R. Hoare

j.

new topic     » goto parent     » topic index » view message » categorize

11. Re: object(x) rethink

jacques deschênes wrote:
 
> I think you completely miss the point with generic type.
> There is no point testing if a variable is of type 'object' as all variables
> hold an object.
> The object data type is there as a generic container and as is, it is very
> usefull.
> It is right to say that it is useless to write something like:
> 
> if object(x) then...
> 
> But for the coherance of the language this must be a valid declaration and
> must
> behave like any other datatype validation.
> There is nothing to change in the language here. All language that use generic
> type behave the same way.
> In OOP for exemple there is alway a generic class from which all other classes
> are derived and if you test any class to know if it is of that generic the
> answer
> will allways be TRUE, like in euphoria.
> This coherent in syntax and in semantic.

Ok, I've prepared some code, to be more concrete and clear.
Try it please:
type old_object(object x)
   return object(x)
end type   

global type object(old_object x)
    if integer(x) then return 1
      elsif atom(x) then return 2
    elsif sequence(x) then return 3
      else return 4 -- reserved for variables, declared with type 'object'
    end if
end type

sequence s
    s={1,1}
   ? object(s) -- true, 3
integer i
    i=1
   ? object(i) -- true, 1
atom a
     a=2.5
   ? object(a) -- true, 2
object x
     x = {}
   ? object(x) -- true, 3 or 2 or 1 now
               -- but must be 4, I think


The "object" word is ambiguous in EU, I think.
It is some piece of data in common sence, so to say,
and it is some very specific type of variable.
This new type in above code seems to have both
meanings, I think.
But that old one - it is just useless, yes,
you are right.

Regards,
Igor Kachan
kinz at peterlink.ru

new topic     » goto parent     » topic index » view message » categorize

12. Re: object(x) rethink

Andy Drummond wrote:
> 
> The Euphoria docs tell me that object(x) always returns True.  That makes
> it a bit useless. Especially since if x is NOT an object it crashes
> Euphoria! 
> Would it not be better if object(x) returned True if x was an object and
> False if x either was not an object (i.e. something else like a function)
> or, and this is what I would like, if x had not yet been assigned a value
> so, even though it might have been declared, it is valueless.

Well just to get over the pedantic issue first, object() does not return True or
False; it returns 1 or 0. Euphoria has no boolean datatype.

But yes, object() does seem quite useless in its current form. But what do we
want it to do? So far we seem to have a few options:

(A) Leave it alone. 
(B) Return 1 if the symbol has been explictly declared as 'object', regardless
of what type of data it is currently carrying, otherwise return 0.
(C) Return 1 if the symbol has been assigned a value, othewise return 0.
(D) Return a value that represents the declaration type of the symbol. eg. 1 for
objects, 2 for sequences, 3 for integers, 4 for atoms, 5 for user-types, 6 for
procedures, 7 for functions, ...
(E) Same as (D) but related to the current data content of the symbol, rather
than the original symbol declaration.
(F) Same as (D)/(E) but also return the negative value if the symbol has not
been assigned yet.

My feeling is it should be left alone. Instead of changing it, we need some new
built-in functions to tell us things about the symbols.

It should be left alone because the Euphoria datatype system is built upon a
hierarchy of datatypes...

atoms are also objects
integers are also atoms and thus also objects
sequence are also objects

The current integer(), atom() and sequence() functions give us information about
the current data contained by the symbol, so therefore object() should do the
same. This is particularly useful when dealing with sequence elements, which are
always 'declared' as objects.

However, we could do with functions like assigned() and declaration(). 

The assigned() function would return 1 if the symbol has a value, and 0 if it
doesn't. This information is useful so we can tell if we need to initialize the
symbol or not.

I was thinking that a declaration() function would return a value indicating
what the symbol was declared as, but I can't think of anything useful to do with
that information. With the possible exception being that a function that took a
routine_id could be able to tell you things about the routine, such is it a
function or procedure, what is name and namespace is, what is parameter signature
is, etc ...

I also think the interpreter should raise an exception (that is, crash) when the
symbol used as a parameter has not been declared at all.

-- 
Derek Parnell
Melbourne, Australia
Skype name: derek.j.parnell

new topic     » goto parent     » topic index » view message » categorize

13. Re: object(x) rethink

Derek Parnell wrote:
> 
> Andy Drummond wrote:
> > 
> > The Euphoria docs tell me that object(x) always returns True.  That makes
> > it a bit useless. Especially since if x is NOT an object it crashes
> > Euphoria! 
> > Would it not be better if object(x) returned True if x was an object and
> > False if x either was not an object (i.e. something else like a function)
> > or, and this is what I would like, if x had not yet been assigned a value
> > so, even though it might have been declared, it is valueless.
> 
> Well just to get over the pedantic issue first, object() does not return True
> or False; it returns 1 or 0. Euphoria has no boolean datatype.
> 
> But yes, object() does seem quite useless in its current form. But what do we
> want it to do? So far we seem to have a few options:
> 
> (A) Leave it alone. 
> (B) Return 1 if the symbol has been explictly declared as 'object', regardless
> of what type of data it is currently carrying, otherwise return 0.
> (C) Return 1 if the symbol has been assigned a value, othewise return 0.
> (D) Return a value that represents the declaration type of the symbol. eg. 1
> for objects, 2 for sequences, 3 for integers, 4 for atoms, 5 for user-types,
> 6 for procedures, 7 for functions, ...
> (E) Same as (D) but related to the current data content of the symbol, rather
> than the original symbol declaration.
> (F) Same as (D)/(E) but also return the negative value if the symbol has not
> been assigned yet.
> 
> My feeling is it should be left alone. Instead of changing it, we need some
> new built-in functions to tell us things about the symbols. 
> 
> It should be left alone because the Euphoria datatype system is built upon a
> hierarchy of datatypes...
> 
> atoms are also objects
> integers are also atoms and thus also objects
> sequence are also objects
> 
> The current integer(), atom() and sequence() functions give us information
> about
> the current data contained by the symbol, so therefore object() should do the
> same. This is particularly useful when dealing with sequence elements, which
> are always 'declared' as objects.
> 
> However, we could do with functions like assigned() and declaration(). 
> 
> The assigned() function would return 1 if the symbol has a value, and 0 if it
> doesn't. This information is useful so we can tell if we need to initialize
> the symbol or not.
> 
> I was thinking that a declaration() function would return a value indicating
> what the symbol was declared as, but I can't think of anything useful to do
> with that information. With the possible exception being that a function that
> took a routine_id could be able to tell you things about the routine, such is
> it a function or procedure, what is name and namespace is, what is parameter
> signature is, etc ...
> 
> I also think the interpreter should raise an exception (that is, crash) when
> the symbol used as a parameter has not been declared at all. 
> 
> -- 
> Derek Parnell
> Melbourne, Australia
> Skype name: derek.j.parnell

Derek is right, I think, in his analysis.  The reason I suggested changing the
operation of the object() operator is that it has no significant use currently
(unless someone is being particularly devious).  It should be simpler to change
the operation of a presently-unused operator to something usable, than to add a
new operator.  I agree that, in general, it is *not* wise to change the function
of an existing operator, but in this case I would think it sensible.  There are
a whole range of potential language enhancements one could do along these lines
but doing that would create a plethora of problems and irate programmers too.
The object(x) change is, IMHO, a minimal enhancement with zero compatibility
issues involved - while giving us (me, anyway!) a very useful functionality
gain.

The question of crashing if you use object(unused_name) is interesting. In the
current school of thought it ought to return False - "No, it's not an object".
But I agree it ought to cause an exception if used that way.  Oh, maybe I ought
to not use False but zero, if you wish to be pedantic;)

I wonder if Rob would care to give us his opinion - after all, he conceived the
whole language structure and it is to him that I am so very grateful. Rob?

new topic     » goto parent     » topic index » view message » categorize

14. Re: object(x) rethink

Jason wrote:

>I dunno. I can see it both ways. But changing the behavior would make it
>inconsistent
>with integer(x) and sequence(x) unless those, too, returned false for
>uninitialized
>variables.

right

>And since procedures are different from variables in Euphoria, I don't know
>if "object(func_name)" makes much sense, especially since you can use or wrap
>routine_id().

right again

Derek wrote:

>The assigned() function would return 1 if the symbol has a value, and 0 if it
>doesn't. This information is useful so we can tell if we need to initialize
>the symbol or not.

You already know if you have an uninitialized variable as it generate a runtime
error when you try to use it.
I'm not convince of the usefullness of assigned().

>...With the possible exception being that a function that
>took a routine_id could be able to tell you things about the routine, such is
>it a function or procedure, what is name and namespace is, what is parameter
>signature is, etc ...

to be pedandic ;) in c# and other languages it's called "reflection".


Jacques

new topic     » goto parent     » topic index » view message » categorize

15. Re: object(x) rethink

jacques deschênes wrote:
> 
> 
> Jason wrote:
> 
> >I dunno. I can see it both ways. But changing the behavior would make it
> >inconsistent
> >with integer(x) and sequence(x) unless those, too, returned false for
> >uninitialized
> >variables.
> 
> right
> 
> >And since procedures are different from variables in Euphoria, I don't know
> >if "object(func_name)" makes much sense, especially since you can use or wrap
> >routine_id().
> 
> right again
> 

On those points, I also agree.

> Derek wrote:
> 
> >The assigned() function would return 1 if the symbol has a value, and 0 if it
> >doesn't. This information is useful so we can tell if we need to initialize
> >the symbol or not.
> 
> You already know if you have an uninitialized variable as it generate a
> runtime
> error when you try to use it.
> I'm not convince of the usefullness of assigned().
> 

This is exactly why something like assigned() would be useful.

When several tasks might enter a race condition, you need this sort of mechanism
so as o avoid the race. Crashing without recovery is probably the simplest, but
it is a very annoying feature of Eu I have complained about, namely lack of
ability to detect an error, correct it and resume execution in a supposedly
stabilised state. I say "supposedly" because Eu doesn't have Design by Contract
builtins. The latter would have my yes vote.

In the meantime, it seems to me just as useful to be able to check whether a var
has a value or whether a sequence index is out of bounds. You can check the
latter without crashing, and hus avoid a crash, but not the former. This is
illogical.

> >...With the possible exception being that a function that
> >took a routine_id could be able to tell you things about the routine, such is
> >it a function or procedure, what is name and namespace is, what is parameter
> >signature is, etc ...
> 
> to be pedandic ;) in c# and other languages it's called "reflection".
> 

My idea of the whole thing is to have a meta(identifier,meta_type) function,
which takes a name and a meta property id (I don't care using "TYPE", META_TYPE
or any other flavor). The return value would be a sequence, empty if property not
available or symbol doesn't exist, and {value} otherwise. I don't mind a
{status,value} pair instead. Examples of meta property ids might include:
TYPE - which type was this identifier declared with;
ARGS - list of argument types for a routine. Simple vars return {};
DEFINED - does this identifier exist;
ASSIGNED - was the symbol ever given a value? For routines, the meaning might
be: was the routine ever called?
READONLY - is this a variable that can be assigned?
SCOPE - is identifier private, local or global, or a keyword, ...?

I cannot see how that info could be gathered using an include file - unless it
is another copy of the parser and maintains duplicate info. This would be the
only way to do it currently, and wouldn't be terribly efficient, and wouldn't
work for all the examples above - specifically the ASSIGNED part.

For some of the above, a set_meta(identifier,property_id,new_value) routine
would make sense and make some areas of coding safer.

> 
> Jacques

CChris

new topic     » goto parent     » topic index » view message » categorize

16. Re: object(x) rethink

All types in Euphoria, whether they are
built-in, like integer(), or user_defined,
can be used to either declare a variable,
or test if a value belongs to that type.
e.g.
atom a
    sequence s
    my_special_type month

    if atom(9.9) then ...
    if sequence(x) then ...
    if my_special_type(11) then ...


So, just for completeness, if you can
declare something as:
    object y
it seems reasonable that you should
be able to say:
    if object(z) then ...
even if that is rather pointless.

As for detecting uninitialized variables,
this would be trivial to implement in the
interpreter as it is currently implemented.

It would be harder to implement in the translator,
since the translator currently does no run-time 
checking at all for uninitialized variables.
You would have to initialize variables to the
magic "NOVALUE", something that is currently not done.
This might waste a bit of time, in the case of
private variables that would have to be set to NOVALUE
each time a routine was called. (In some cases I 
currently set certain variables to 0 to achieve 
an optimization later on.)

All future implementations of Euphoria,
interpreted, compiled, etc. would
have to support this, even if it proved to
be inconvenient for the implementor.

Currently Euphoria can often detect *at compile-time*
that a variable is never assigned a value.

I'd like to see some good examples of where
this would be useful. It seems to me you
could have code that detected that a variable
was not initialized, but then what would you
typically do? Probably either issue an error
message "Variable not initialized!", or quietly
set the variable to some default value.

If the program was composed entirely of your own
code, it would be silly to add *error-checking* code 
to test if a particular variable is initialized. 
It would be easier just to initialize it.
If you wanted to test that it "hasn't really
been set to a meaningful value yet", e.g. a file handle,
in almost all cases you can just set it to some special 
value that indicates that fact, like -1, or whatever.

If you wrote a library used by others, they might
fail to initialize one of your global variables, maybe because they
made a silly mistake, or just didn't realize it was
required. So in that case you could either issue an error message
telling them they made a mistake, or quietly set the 
variable to some default value. Your message might be
slightly more meaningful to them, than a generic
Euphoria-issued message, but probably not much.
You could also initialize the variable yourself to some
special value that means "not really initialized properly yet"
and issue the same kind of message.

I don't think this is a good idea,
but I would not oppose it if a majority
wanted it, and someone were willing to
implement it.

Regards,
   Rob Craig
   Rapid Deployment Software
   http://www.RapidEuphoria.com

new topic     » goto parent     » topic index » view message » categorize

17. Re: object(x) rethink

Robert Craig wrote:
> 
> All types in Euphoria, whether they are
> built-in, like integer(), or user_defined,
> can be used to either declare a variable,
> or test if a value belongs to that type.
> e.g.
> }}}
<eucode>
>     atom a
>     sequence s
>     my_special_type month
> 
>     if atom(9.9) then ...
>     if sequence(x) then ...
>     if my_special_type(11) then ...
> </eucode>
{{{

> 
> So, just for completeness, if you can
> declare something as:
>     object y
> it seems reasonable that you should
> be able to say:
>     if object(z) then ...
> even if that is rather pointless.
> 
> As for detecting uninitialized variables,
> this would be trivial to implement in the
> interpreter as it is currently implemented.

Which is why I thought a logical response rather
than a program abort would be simple to implement.
> 
> It would be harder to implement in the translator,
> since the translator currently does no run-time 
> checking at all for uninitialized variables.
> You would have to initialize variables to the
> magic "NOVALUE", something that is currently not done.
> This might waste a bit of time, in the case of
> private variables that would have to be set to NOVALUE
> each time a routine was called. (In some cases I 
> currently set certain variables to 0 to achieve 
> an optimization later on.)

I had not appreciated that a translated and compiled program
would not detect uninitialised variables. That does affect things.
> 
> All future implementations of Euphoria,
> interpreted, compiled, etc. would
> have to support this, even if it proved to
> be inconvenient for the implementor.

Yes - but if trivial, OK
> 
> Currently Euphoria can often detect *at compile-time*
> that a variable is never assigned a value.
> 
> I'd like to see some good examples of where
> this would be useful. It seems to me you
> could have code that detected that a variable
> was not initialized, but then what would you
> typically do? Probably either issue an error
> message "Variable not initialized!", or quietly
> set the variable to some default value.
> 
> If the program was composed entirely of your own
> code, it would be silly to add *error-checking* code 
> to test if a particular variable is initialized. 
> It would be easier just to initialize it.
> If you wanted to test that it "hasn't really
> been set to a meaningful value yet", e.g. a file handle,
> in almost all cases you can just set it to some special 
> value that indicates that fact, like -1, or whatever.
> 
> If you wrote a library used by others, they might
> fail to initialize one of your global variables, maybe because they
> made a silly mistake, or just didn't realize it was
> required. So in that case you could either issue an error message
> telling them they made a mistake, or quietly set the 
> variable to some default value. Your message might be
> slightly more meaningful to them, than a generic
> Euphoria-issued message, but probably not much.
> You could also initialize the variable yourself to some
> special value that means "not really initialized properly yet"
> and issue the same kind of message.
> 
> I don't think this is a good idea,
> but I would not oppose it if a majority
> wanted it, and someone were willing to
> implement it.
> 
> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    <a href="http://www.RapidEuphoria.com">http://www.RapidEuphoria.com</a>

Reading your comments above, I understand where you are coming from.
I agree that having object() is consistent with atom(), integer(), and
sequence(), but it is rather a waste of effort if all it can do is cause
an abort to occur.  While atom(x) would return false if x was not an atom,
it seemed reasonable that if object() exists then it ought to do something
useful - so object(x) returning false - 0 - if x was not an object (and an
uninitialised variable is not an object) is a rational response.

I won't press this one. I merely rest my case. I have no idea how Euphoria
as a language will develop in the future, but in the hope that there will be
advances I thought this would be a valuable change. To have  function which 
can only return a single value and changes nothing is pedantically pointless.

Andy

new topic     » goto parent     » topic index » view message » categorize

18. Re: object(x) rethink

Robert Craig wrote:
 
> All types in Euphoria, whether they are
> built-in, like integer(), or user_defined,
> can be used to either declare a variable,
> or test if a value belongs to that type.
> e.g.
> }}}
<eucode>
>     atom a
>     sequence s
>     my_special_type month
> 
>     if atom(9.9) then ...
>     if sequence(x) then ...
>     if my_special_type(11) then ...
> </eucode>
{{{

> 
> So, just for completeness, if you can
> declare something as:
>     object y
> it seems reasonable that you should
> be able to say:
>     if object(z) then ...
> even if that is rather pointless.

Ok, thanks Rob, now I can more precisely express
my additional thoughts about this subject.

Really, sequence(s), atom(a) and integer(i) types
test not only if a *value* belongs to that type, but
also automatically test if a *variable* was declared
with that type.

We can say:
 
   if sequence(s) then -- tests the type of a variable
                       -- on declaration (via value, maybe) 

and

   if sequence(s[i]) then -- tests the value of an element (object)

Same about atom() and integer().

But the object() type doesn't test for *declaration*,
and "tests", so to say, just for *value*, which
(any one) is an object on definition -- all data in
Euphoria are objects, and there is *nothing* to test
at all.

So the obiect() type only lacks (in comparison with
sequence(), atom() and integer() ones) the ability to
test for *declaration* as any *value* is an object
without any testing, just on convention.

Just my $.02, I can live with it as it is and am
ready to leave it alone, but it may be some subject
for some confusion anyway, I think.

[snip]

Regards,
Igor Kachan
kinz at peterlink.ru

new topic     » goto parent     » topic index » view message » categorize

19. Re: object(x) rethink

Robert Craig wrote:
> 
> All types in Euphoria, whether they are
> built-in, like integer(), or user_defined,
> can be used to either declare a variable,
> or test if a value belongs to that type.
> e.g.
> }}}
<eucode>
>     atom a
>     sequence s
>     my_special_type month
> 
>     if atom(9.9) then ...
>     if sequence(x) then ...
>     if my_special_type(11) then ...
> </eucode>
{{{

> 
> So, just for completeness, if you can
> declare something as:
>     object y
> it seems reasonable that you should
> be able to say:
>     if object(z) then ...
> even if that is rather pointless.
> 
> As for detecting uninitialized variables,
> this would be trivial to implement in the
> interpreter as it is currently implemented.
> 
> It would be harder to implement in the translator,
> since the translator currently does no run-time 
> checking at all for uninitialized variables.
> You would have to initialize variables to the
> magic "NOVALUE", something that is currently not done.
> This might waste a bit of time, in the case of
> private variables that would have to be set to NOVALUE
> each time a routine was called. (In some cases I 
> currently set certain variables to 0 to achieve 
> an optimization later on.)
> 
> All future implementations of Euphoria,
> interpreted, compiled, etc. would
> have to support this, even if it proved to
> be inconvenient for the implementor.
> 
> Currently Euphoria can often detect *at compile-time*
> that a variable is never assigned a value.
> 
> I'd like to see some good examples of where
> this would be useful. It seems to me you
> could have code that detected that a variable
> was not initialized, but then what would you
> typically do? Probably either issue an error
> message "Variable not initialized!", or quietly
> set the variable to some default value.
> 
> If the program was composed entirely of your own
> code, it would be silly to add *error-checking* code 
> to test if a particular variable is initialized. 
> It would be easier just to initialize it.
> If you wanted to test that it "hasn't really
> been set to a meaningful value yet", e.g. a file handle,
> in almost all cases you can just set it to some special 
> value that indicates that fact, like -1, or whatever.
> 

This is correct, but certainlly doesn't apply to all Eu code.

> If you wrote a library used by others, they might
> fail to initialize one of your global variables, maybe because they
> made a silly mistake, or just didn't realize it was
> required. So in that case you could either issue an error message
> telling them they made a mistake, or quietly set the 
> variable to some default value. 

How to detect this condition without crashing? This is the whole point.

> Your message might be
> slightly more meaningful to them, than a generic
> Euphoria-issued message, but probably not much.
> You could also initialize the variable yourself to some
> special value that means "not really initialized properly yet"
> and issue the same kind of message.
> 

The practice of using special values to mark routine error status, not properly
initialised yet variables and other equivalent situations is a source of
countless bugs, because a value is hardly ever special enough.

This is why I, and some other, have pushed for a nil builtin "type". Returning
nil or testing a var for nil are convenient phrases, but the idea is that nil is
not a value, and hardly a type. It's a condition which can conveniently be
assessed as if it were a value or type. And if nil is a type, it can have no
legal value. Such a non type would have to be builtin, and the type system cannot
be simply adjustd as it stands now.

As I mentioned in an earlier post, you can work around a bad sequence index by
checking it prior, but not around an unitialised variable. If Eu programs can use
code plugins some day, they will certainly need this.

CChris

> I don't think this is a good idea,
> but I would not oppose it if a majority
> wanted it, and someone were willing to
> implement it.
> 
> Regards,
>    Rob Craig
>    Rapid Deployment Software
>    <a href="http://www.RapidEuphoria.com">http://www.RapidEuphoria.com</a>

new topic     » goto parent     » topic index » view message » categorize

20. Re: object(x) rethink

There is absolutely no need to change the behavior of object().
And for having a routine that does what is being proposed 
dummy data can do that same thing.

CChris wrote:
> 
> The practice of using special values to mark routine error status, not
> properly
> initialised yet variables and other equivalent situations is a source of
> countless
> bugs, because a value is hardly ever special enough. 
> 

LOL.  "Not special enough"?  You should be able to assign it to something 
legal that will work as a starting case anyway.  If I got an uninitialized
variable in my code I hope the compiler or interpreter will tell me
before test execution.  I don't want to test for that while its executing.


Shawn

new topic     » goto parent     » topic index » view message » categorize

21. Re: object(x) rethink

Shawn Pringle wrote:
> 
> There is absolutely no need to change the behavior of object().
> And for having a routine that does what is being proposed 
> dummy data can do that same thing.
> 
> CChris wrote:
> > 
> > The practice of using special values to mark routine error status, not
> > properly
> > initialised yet variables and other equivalent situations is a source of
> > countless
> > bugs, because a value is hardly ever special enough. 
> > 
> 
> LOL.  "Not special enough"?  You should be able to assign it to something 
> legal that will work as a starting case anyway.  If I got an uninitialized
> variable in my code I hope the compiler or interpreter will tell me
> before test execution.  I don't want to test for that while its executing.
> 
> 
> Shawn

You really don't?
There are tasks to be performed by a routine only the first time it is called;
frequently, it involves setting some variables, possibly asking something to user
or OS. When doing so would be a problem, either bothering the user, making costly
checks or otherwise, it would be simpler to test for an unassigned value and make
a decision on that base.
Currently, one has to initialise a dedicated flag and test whether it is set,
and if not set then set it and perform whatever. That's one extra unneeded
variable, and an extra cause of bugs when upgrading the code because it might be
set in different places, and there might be a number of flags. You may say it
hardly matters in a "hello world" sized program; I'll grant you that. Now back to
talking about useful programs.

So yes, I wish I could test for assignment at run time without a run time error.
Note that regularly reading an uninitialised var should keep crashing somehow.
Perhaps hadn't you got this specific point.

CChris

new topic     » goto parent     » topic index » view message » categorize

Search



Quick Links

User menu

Not signed in.

Misc Menu