An elegant, EUPHORIA solution

new topic     » topic index » view thread      » older message » newer message

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 thread      » older message » newer message

Search



Quick Links

User menu

Not signed in.

Misc Menu