Variant types

S

Stefan Haflidason

My languages lecturer is a fan of a feature called 'variant' in a model
language he defined. The variant declaration is used to specify that a
variable may be of one or another type.

When he stated that no languages we are taught have this functionality,
I asked him whether using an abstract class which is subclassed for
each variant type would be enough. He said that this would work, but is
a form of encoding the declaration and as such is not as good as such a
declaration provided as part of the language.

I had a go at implementing 'variant' in Ruby. I'm going to show it to
him tomorrow and see what he thinks. Comments welcome.

Variant takes the name of the property, and one or more types. I
haven't seen him use this for more than two types however.

Can anyone see a way to do away with the instance variables? I could
have made them methods, but this does not seem to offer additional
encapsulation.

Code:

class Class

def variant(name, *classes)
instance_variable_set("@#{name}_value", nil)
instance_variable_set("@#{name}_classes", classes)

classes = instance_variable_get("@#{name}_classes")

define_method("#{name}=") do |value|
if classes.include? value.class
instance_variable_set("@#{name}_value", value)
else
raise "TypeException for '#{value}'. May be one of
[#{classes.join(', ')}]"
end
end

define_method(name) do
instance_variable_get("@#{name}_value")
end
end
end

class ListItem

def initialize(value)
self.value = value
end

attr_accessor :value

variant :next, ListItem, NilClass
end

item = ListItem.new('1')

item.next = ListItem.new('2')

item.next.next = ListItem.new('3')

# Try assigning a value which would not make sense
# in the context of a list.
begin
item.next.next = 2.2
rescue => ex
puts ex
end

while item != nil
puts item.value
item = item.next
end

# Output:
# TypeException for '2.2'. May be one of [ListItem, NilClass]
# 1
# 2
# 3

Stefan.
 
J

Jim Weirich

Stefan said:
My languages lecturer is a fan of a feature called 'variant' in a model
language he defined. The variant declaration is used to specify that a
variable may be of one or another type

If I understand correctly, it sounds very much like a static lanugage
concept, with little applicability to Ruby. The problem with
implementing it is Ruby is not to open up variables to more than one
type (that happens automatically), but to artificially restrict the
variable to the explicitly listed types.
When he stated that no languages we are taught have this functionality,

Perhaps the key phrase is "we are taught", because as described,
variants sound much like a union in C. If I recall correctly, even
Pascal has variant records that did much the same thing. Of course, I
may be misunderstanding yor description.
 
S

Stefan Haflidason

Jim said:
If I understand correctly, it sounds very much like a static lanugage
concept, with little applicability to Ruby. The problem with
implementing it is Ruby is not to open up variables to more than one
type (that happens automatically), but to artificially restrict the
variable to the explicitly listed types.

Can't a little restriction be healthy? In the lecture last week I could
have, instead of using abstract classes in Java, used Ruby's dynamic
typing to show that the property could already be set to be of any type.
But is that freedom a weakness?

If this restriction was used in a large software system, and another
developer mis-used a list type I had defined, or some other library,
then the TypeException would be raised. Without the restriction, the
other developer would be able to set 'next' to be a Fixnum, for example.
Then, when I call next on the Fixnum I'd get its successor, and not a
ListItem. I would need to call kind_of? to check that next is returning
a ListItem and not something else.

If you wanted to be confident that the software was implemented as it is
specified, would this (variant typing) not be preferable to calling
kind_of? many times?
Perhaps the key phrase is "we are taught", because as described,
variants sound much like a union in C. If I recall correctly, even
Pascal has variant records that did much the same thing. Of course, I
may be misunderstanding yor description.

We are, unfortunately or necessarily, only taught a few languages. I
don't agree with the choices, but it's not a problem as I teach myself
what I can.

I currently do ~90% of my programming in Ruby. I'm currently studying
(outwith my course) Ruby, Common Lisp and Haskell.

What I don't have is an answer to the question, "How does the freedom of
Ruby's typing system affect large-scale software development?". I enjoy
programming in Ruby and have involved it in my final year project and
every-day tasks. The freedom does make me a little nervous though, as
unless I have misunderstood the ethos behind it, it seems to imply that
those who use it must be proficient.

Given the ease with which Ruby can be picked up, there are sure to be
many people in the near future who put Ruby on their CV who have at best
a simplistic understanding of its workings/use.

I do not consider this to be a fault of Ruby; far from it. I do however
forsee in my own future a discussion with a future manager where I
suggest Ruby and will be required to exemplify Ruby's suitability for a
large project.

Without restrictions, and without the notion of contracts, what
foundations could my answer be based on?

Stefan.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,998
Messages
2,570,242
Members
46,834
Latest member
vina0631

Latest Threads

Top