1. An elegant, EUPHORIA solution

One of the complaints from people who want structures in Euphoria is the
ugly way we're forced to write our type-check routines. For example, a
structure like this in pseudocode...

 --structure my_structure
 --   integer NUMBER
 --   string NAME
 --   user_defined_type WHO_KNOWS_WHAT
 --end structure

..must be type-defined like this...

constant NUMBER = 1, NAME = 2, WHO_KNOWS_WHAT = 3

type my_structure(sequence x)
   if length(x) != 3 then
      return 0
   elsif not integer(x[NUMBER]) then
      return 0
   elsif not string(x[NAME]) then
      return 0
   elsif not user_defined_type(x[WHO_KNOWS_WHAT]) then
      return 0
   end if
   return 1
end type

..and if we want to type-check a sequence of these values, we always have
to write a "for" loop each time:

type list_of_my_structure(sequence x)
   for z = 1 to length(x) do
      if not my_structure(x[z]) then
         return 0
      end if
   end for
   return 1
end type

As you can see, this is hardly an "elegant" way of doing things. The problem
with the constants is more of a namespace issue, though -- the PRIMARY
objection I'm focusing on is the inelegant, *ugly* code we're forced to
write to type-check everything.

To solve this, I propose the following library:

 -- struct.e
 -- written by Gabriel Boehme
 -- free for anybody and everybody to use

global function type_structure(sequence types, sequence data)
 -- this function verifies that each element of a sequence is of the correct
type

   if length(types) != length(data) then
      -- data is the wrong length for this structure
      return 0
   else
      for z = 1 to length(data) do
         if not call_func(types[z], {data[z]}) then
            -- the called type-check function failed
            return 0
         end if
      end for
   end if

   -- everything fits!
   return 1
end function

global function type_all(integer id, sequence x)
 -- this function verifies that every element of a sequence is of the same
type

   for z = 1 to length(x) do
      if not call_func(id, {x[z]}) then
         -- type-check failed
         return 0
      end if
   end for

   -- they're all right!
   return 1
end function

 -- end of struct.e

Now, all we have to do now is define our "structure" like this:

constant MY_STRUCTURE =
   {routine_id("integer"),
    routine_id("string"),
    routine_id("user_defined_type")}

type my_structure(sequence x)
   return type_structure(MY_STRUCTURE, x)
end type

constant NUMBER = 1, NAME = 2, WHO_KNOWS_WHAT = 3

You see? Euphoria is more than capable of handling these things in an
"elegant" way. Yes, we still have to define constants for sequence index
values, and yes, this *is* a pain, but we have now eliminated the need for
big, ugly type-check functions.

This also applies to sequences of "structures", too:

constant LIST_OF_MY_STRUCTURE = routine_id("my_structure")

type list_of_my_structure(sequence x)
   return type_all(LIST_OF_MY_STRUCTURE, x)
end type

Of course, having to define all these extra constants goes back once again
to the namespace issue. But never mind that for now, look at how much more
elegant this is than the type of code I had to write at the beginning of
this post!

And we don't even have to introduce any new structure syntax to do it.

Gabriel Boehme

P.S. I got the inspiration for this idea from Michael Sabal, so he deserves
a share of the credit. Many thanks, Michael!

new topic     » topic index » view message » categorize

2. Re: An elegant, EUPHORIA solution

Ya know...I think you've got it!  <G>  Well, a fairly good solution,
anyway.

>constant MY_STRUCTURE =
>   {routine_id("integer"),
>    routine_id("string"),
>    routine_id("user_defined_type")}

    However, that bit won't work.  I did have a version of your type_all()
function called setOf(), that does the same thing.  When creating it, I found
out that you can't call routine_id() on the built-in types.  First you have to
wrap them.

type blah_integer( object v )
   return( integer( v ) )
end type
global constant INTEGER = routine_id( "blah_integer" )

Now you can say something like:
>constant MY_STRUCTURE =
>   {INTEGER,
etc, etc

     The type_structure() routine, however, is brilliant in it's simplicity.
(which is probably why I never thought of it... :)

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

3. Re: An elegant, EUPHORIA solution

>You see? Euphoria is more than capable of handling these things in an
>"elegant" way. Yes, we still have to define constants for sequence index
>values, and yes, this *is* a pain, but we have now eliminated the need for
>big, ugly type-check functions.

Yes, you could even do this using 100% pure Euphoria:

include oop.e

new_class (EMPTY_CLASS) -- base upon empty class
constant
    SUIT = new_attribute (routine_id ("string_9"), repeat (' ', 9))
    VALUE = new_attribute (routine_id ("integer"), 0)

class my_class my_class = store_class ()

And this library I wrote, was available months ago.
Yet, I want structures implemented. What does this say you ?

>And we don't even have to introduce any new structure syntax to do it.

Well, no.
Issues with the above:
    - constants name can conflict
    - my_class is a sequence of one element longer, than what its
representing. (the last element is used to store the different routine-id's
of each type, for run-time type checking)
    - speed
    - you're forced to either work with it as an class or as a structure.
Conversion does not happen automatically. If I pass a normal sequence to a
place where a 'class' is suppose to be passed to, it will be an 'invalid'
class, and a type-check error will occur. I can thus not use sequences as
structures, and structures as a sequence. I could add some conversion
routine, but then I would need to keep track which structures are structures
and which are sequences. This means I need to use a handle. WHen I use a
handle, rather than the object itself to store the value in, the value isnt
freed when appropiate, and you'll need a call a procedure to 'free' the
variable at the end of, for example, a routine declaration. And even then,
you would still be forced to use a routine to convert the values.
    - The syntax is not euphorish.


So, I was already aware of that its 'almost' possible with Euphoria. Just
not good enough.
Also, I havent seen any one use my library. Not even from the win32 front,
so i'm assuming the routine based syntax is really hated. And without the
automatic conversion you either write everthing using structure or not using
them. They can't be mixed.

Ralf Nieuwenhuijsen

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

Search



Quick Links

User menu

Not signed in.

Misc Menu