Perl data types

firstly product types, as I see it the only way of doing this is to use
Class::Struct. This will allow the use of multiple variables to be
identified as a single value.

secondly, does this make a hash a product type, because the keys are
referenced by scalars, and these point to variables, which i guess could be
anything but allows a simple structure.

thirdly, does perl support sum types, as far as I can tell, since perl is
not a typed language as such it is imposible to tell the differnce between
the types, for example a case statement is impossible. The could obviously
be overcome using the a regex to an extent to tell whether a scalar is a
number or a string, but apart from that it is not really possible.

Advertisements

"David Holmes" <> writes:
> firstly product types, as I see it the only way of doing this is to use
> Class::Struct. This will allow the use of multiple variables to be
> identified as a single value.

What is a "product type"? I've not heard this terminology before.
> secondly, does this make a hash a product type, because the keys are
> referenced by scalars, and these point to variables, which i guess could be
> anything but allows a simple structure.

Not knowing what a product type is, I can't help.
> thirdly, does perl support sum types

What is a 'sum type'?
> as far as I can tell, since perl is not a typed language as such it
> is imposible to tell the differnce between the types, for example a
> case statement is impossible.

Case statements are possible, they're just not built into the
language. See perlfaq7, "How do I create a switch or case statement?".

And perl is typed, albeit loosely.
> The could obviously be overcome using the a regex to an extent to
> tell whether a scalar is a number or a string, but apart from that
> it is not really possible.

You don't (generally) care if it's a number or a string. If you use
it like a string, it's a string. If you use it like a number, it's a
number.

$foo = '4';

$bar = $foo + 3; # $bar is now 7

print "bar is [$bar]" if $bar eq '7';

-=Eric
--
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
-- Blair Houghton.

Advertisements

[snip]
>>as far as I can tell, since perl is not a typed language as such it
>>is imposible to tell the differnce between the types, for example a
>>case statement is impossible.
>
>
> Case statements are possible, they're just not built into the
> language. See perlfaq7, "How do I create a switch or case statement?".
>
> And perl is typed, albeit loosely.

Just to add my two cents, Damian Conway has made a module named
Attribute::Types which adds strong typing (at run time, not compile
time) to Perl 5:

The definition of a product type is a type that collects together a number
of data items in a single value. This is why I think that it is a struct. I
know that a product type would be a strinct in c, and in java it would just
be a case of specifying multiple variables, to a class.

Basically I dont know what languages you know but take java for example,
which of course would be similar for c++. If you have an object called Test
that has two string variables, you can deal with the Test object as an
individual item, but can get access to the individual elements.

Similar in a way to a perl hash, you can deal with the hash as a whole
thing, whilst being able to get access to the keys and values, as if they
are two variables of the hash object.

As for sum types, they are subtly different. Values of a sum type are
tagged. This can take several forms but again in the example of a java.
Incase you cant tell this is the language I use most. If you have a base
class that extends a superclass1 and a superclass2. You can initialise a
variable as the base class, and then say:

As I said the values of a sum type are tagged, so I guess in perl since
there are few primative types, it would be like taking a variable,
initialising it to some value and asking:

if this is a scalar { do something }
else if it is a hash { foreach hash { do something }}
else if it is an array.....

Hope that at least makes some sense.

Regards

Dave

"Eric Schwartz" <> wrote in message
news:...
> "David Holmes" <> writes:
> > firstly product types, as I see it the only way of doing this is to use
> > Class::Struct. This will allow the use of multiple variables to be
> > identified as a single value.
>
> What is a "product type"? I've not heard this terminology before.
>
> > secondly, does this make a hash a product type, because the keys are
> > referenced by scalars, and these point to variables, which i guess could
be
> > anything but allows a simple structure.
>
> Not knowing what a product type is, I can't help.
>
> > thirdly, does perl support sum types
>
> What is a 'sum type'?
>
> > as far as I can tell, since perl is not a typed language as such it
> > is imposible to tell the differnce between the types, for example a
> > case statement is impossible.
>
> Case statements are possible, they're just not built into the
> language. See perlfaq7, "How do I create a switch or case statement?".
>
> And perl is typed, albeit loosely.
>
> > The could obviously be overcome using the a regex to an extent to
> > tell whether a scalar is a number or a string, but apart from that
> > it is not really possible.
>
> You don't (generally) care if it's a number or a string. If you use
> it like a string, it's a string. If you use it like a number, it's a
> number.
>
> $foo = '4';
>
> $bar = $foo + 3; # $bar is now 7
>
> print "bar is [$bar]" if $bar eq '7';
>
> -=Eric
> --
> Come to think of it, there are already a million monkeys on a million
> typewriters, and Usenet is NOTHING like Shakespeare.
> -- Blair Houghton.

I take it you are coming from a Pascal/ML-ish background? From what
little I know of such languages, Perl works quite differently. You do
not need to worry about types in the same way.
> firstly product types, as I see it the only way of doing this is to use
> Class::Struct. This will allow the use of multiple variables to be
> identified as a single value.
>
> secondly, does this make a hash a product type, because the keys are
> referenced by scalars, and these point to variables, which i guess could be
> anything but allows a simple structure.

I take it a 'product type' is something like a C struct, where you
define that a Foo, foo, consists of a Bar, foo.bar, and a baz,
foo.baz?

Class::Struct is indeed one way of doing this, although for simple
situations it is overkill. The standard Perl way is, as you say, with
a hash:

my %foo = (bar => "something", baz => "something else");

or with an anonymous hash:

my $foo = { bar => "something", baz => "something else");

my $x = { y => $foo, z => "Z" };

You can build up complex data structures like this on the fly, without
needing to declare the types beforehand.
> thirdly, does perl support sum types, as far as I can tell, since perl is
> not a typed language as such it is imposible to tell the differnce between
> the types, for example a case statement is impossible. The could obviously
> be overcome using the a regex to an extent to tell whether a scalar is a
> number or a string, but apart from that it is not really possible.

Again, I take it a 'product type' is like a C union, where a Foo is
either a Bar or a Baz but not both, and you can switch on the runtime
type? This is not really something you need in Perl: as the data
structures are all flexible, you just switch on the values instead.

Having never got my head round one of the 'type-oriented' languages, I
don't really know what you'd use them for to tell you how to do that
in Perl. If you can give me an example of a situation where you'd want
to use one, I'll think how I'd code it.

Ben

--
I've seen things you people wouldn't believe: attack ships on fire off the
shoulder of Orion; I've watched C-beams glitter in the darkness near the
Tannhauser Gate. All these moments will be lost, in time, like tears in rain.
Time to die. |-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-|

"David Holmes" <> wrote:
> As for sum types, they are subtly different. Values of a sum type are
> tagged. This can take several forms but again in the example of a java.
> Incase you cant tell this is the language I use most. If you have a base
> class that extends a superclass1 and a superclass2.

Surely you mean 'you have a base class that is extended by a subclass1
and a subclass2'? You're talking normal single inheritance, rather
than a class which has two base classes (or implements two interfaces,
or whatever mess Java's made of multiple inheritance)?
> You can initialise a variable as the base class, and then say:
> if (instanceOf(superclass1)) { do something }
> else if (instanceOf(superclass2)) { do something else }

IMHO, Perl's OO is *really* well done. It supports all the concepts if
you need them, but doesn't force them down your throat the way Java
and C++ do. Of course, if you're a fan of Java you're likely to
disagree...

Ben

--
Like all men in Babylon I have been a proconsul; like all, a slave ... During
one lunar year, I have been declared invisible; I shrieked and was not heard,
I stole my bread and was not decapitated.
~ ~ Jorge Luis Borges, 'The Babylon Lottery'

"David Holmes" <> writes:
> The definition of a product type is a type that collects together a number
> of data items in a single value. This is why I think that it is a struct.

As Ben Morrow pointed out, you'd use a hash for this in Perl, as a
rule.
> As for sum types, they are subtly different. Values of a sum type are
> tagged. This can take several forms but again in the example of a java.
> Incase you cant tell this is the language I use most. If you have a base
> class that extends a superclass1 and a superclass2. You can initialise a
> variable as the base class, and then say:
>
> if (instanceOf(superclass1)) { do something }
> else if (instanceOf(superclass2)) { do something else }

But that's crappy OO programming. You should do

object.method()

instead, and let inheritance take care of what gets done, no?
> As I said the values of a sum type are tagged,

How are they tagged? I don't see anything like that in your example.
> so I guess in perl since there are few primative types, it would be
> like taking a variable, initialising it to some value and asking:
>
> if this is a scalar { do something }
> else if it is a hash { foreach hash { do something }}
> else if it is an array.....

But in Perl, you already know what type it is, by the sigil in front
of the variable:

$var is a scalar
@var is an array
%var is a hash

So what would be the point?
> Hope that at least makes some sense.

Sorry, not really. I don't see what you'd want to use a sum type for.

And please don't top-post, it's rude, and it's against the Posting
Guidelines which are posted regularly to this group.

-=Eric
--
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is NOTHING like Shakespeare.
-- Blair Houghton.

Eric Schwartz wrote:
> What is a "product type"? I've not heard this terminology before.

It's a type whose elements are the mathematical product (sometimes called
cross product) of two sets.
For example, the cross product of string and number could be used to create
data elements, which contain a name and the associated income.
A familar product type would be e.g. the "RECORD" type in Pascal or Modula.
>> secondly, does this make a hash a product type, because the keys are
>> referenced by scalars,

Corrrection: the keys are are actual scalars
>> and these point to variables, which i guess
>> could be anything but allows a simple structure.

Well, I wouldn't call it "point to", but essentially you are right.
And yes, hashes could be considered to be a form of a product type.
>> thirdly, does perl support sum types
>
> What is a 'sum type'?

A sum type is the mathematical sum of its constituents, e.g. the enumeration
of elements in a Pascal SET type.
>> as far as I can tell, since perl is not a typed language as such it
>> is imposible to tell the differnce between the types,

You are mistaken, Perl is a strictly typed language. However, the types are
not what you would normally consider types. The Perl data types are scalar,
array, and hash. You just need to get used to that notion of type.

Also sprach Eric Schwartz:
> "David Holmes" <> writes:
>> As for sum types, they are subtly different. Values of a sum type are
>> tagged. This can take several forms but again in the example of a java.
>> Incase you cant tell this is the language I use most. If you have a base
>> class that extends a superclass1 and a superclass2. You can initialise a
>> variable as the base class, and then say:
>>
>> if (instanceOf(superclass1)) { do something }
>> else if (instanceOf(superclass2)) { do something else }
>
> But that's crappy OO programming. You should do
>
> object.method()
>
> instead, and let inheritance take care of what gets done, no?

No, not in Java. Due to broken-by-design method dispatch, you will
constantly be checking the type and then do a typecast. If you have a
class "Foo" with a method "bar" and you stuff 10 Foo objects into

Object array[10];

you can't just say 'array[0].bar'. Instead you have to write

((Foo)array[0]).bar();

This gets worse if 'array' contains Foo and Bar objects and both have a
"bar" method. Then this becomes:

: >> As for sum types, they are subtly different. Values of a sum type are
: >> tagged. This can take several forms but again in the example of a java.
: >> Incase you cant tell this is the language I use most. If you have a base
: >> class that extends a superclass1 and a superclass2. You can initialise a
: >> variable as the base class, and then say:
: >>
: >> if (instanceOf(superclass1)) { do something }
: >> else if (instanceOf(superclass2)) { do something else }
: >
: > But that's crappy OO programming. You should do
: >
: > object.method()
: >
: > instead, and let inheritance take care of what gets done, no?

: No, not in Java. Due to broken-by-design method dispatch, you will
: constantly be checking the type and then do a typecast. If you have a
: class "Foo" with a method "bar" and you stuff 10 Foo objects into

: Object array[10];

If they are Foo objects, then why pretend they are just generic Objects?
Why not stuff them into

Foo array[10];

Then you can write

array[0].bar();

just like you wish.

: you can't just say 'array[0].bar'. Instead you have to write

: ((Foo)array[0]).bar();

: This gets worse if 'array' contains Foo and Bar objects and both have a
: "bar" method. Then this becomes:

If Foo and Bar are derived from the same class which provides "bar()", or
if they both implement an interface that has bar, then, as above, you can
select a type for the array that is more specific than Object (and more
appropriate), and then the above is not needed.

: Thus, it is often required in Java to do the type checking by hand.

I wonder why UNIVERSAL.pm provides isa() and can()? Perhaps it's because
you have to do these same kind of checks in perl on occasion?

: Therefore I never quite understood how SUN can claim that Java has
: polymorphism at all.

Also sprach Malcolm Dew-Jones:
> Tassilo v. Parseval () wrote:
>: Also sprach Eric Schwartz:
>
>: > "David Holmes" <> writes:
>
>: >> As for sum types, they are subtly different. Values of a sum type are
>: >> tagged. This can take several forms but again in the example of a java.
>: >> Incase you cant tell this is the language I use most. If you have a base
>: >> class that extends a superclass1 and a superclass2. You can initialise a
>: >> variable as the base class, and then say:
>: >>
>: >> if (instanceOf(superclass1)) { do something }
>: >> else if (instanceOf(superclass2)) { do something else }
>: >
>: > But that's crappy OO programming. You should do
>: >
>: > object.method()
>: >
>: > instead, and let inheritance take care of what gets done, no?
>
>: No, not in Java. Due to broken-by-design method dispatch, you will
>: constantly be checking the type and then do a typecast. If you have a
>: class "Foo" with a method "bar" and you stuff 10 Foo objects into
>
>: Object array[10];
>
> If they are Foo objects, then why pretend they are just generic Objects?
> Why not stuff them into
>
> Foo array[10];
>
> Then you can write
>
> array[0].bar();
>
> just like you wish.

Too bad that you sometimes have no choice. Just look at some of the
classes in the Java API (like 'Collection' or so). They all cast their
objects down to the most generic class 'Object'.

Java simply is lacking things like C++ templates. Note that C++ would
become pretty unprogrammable if you didn't have them for the sake of
genericity and polymorphism.
>: you can't just say 'array[0].bar'. Instead you have to write
>
>: ((Foo)array[0]).bar();
>
>: This gets worse if 'array' contains Foo and Bar objects and both have a
>: "bar" method. Then this becomes:
>
>: if (array[0] instanceof Foo) {
>: ((Foo)array[0]).bar();
>: } else {
>: ((Bar)array[0]).bar();
>: }
>
> If Foo and Bar are derived from the same class which provides "bar()", or
> if they both implement an interface that has bar, then, as above, you can
> select a type for the array that is more specific than Object (and more
> appropriate), and then the above is not needed.

Say, that each of these classes is instantiatable. So I'd naturally
choose

Class1 array[10];

How exactly would that avoid typecasts? Sure, I can probably have each
of these three implement an interface and change the type of the array
to that of the common interface. However, do I want that? Certainly not.
It means I, the programmer, have to accept such a red-herring in order
to make polymorphism work as expected and convenient.
>: Thus, it is often required in Java to do the type checking by hand.
>
> I wonder why UNIVERSAL.pm provides isa() and can()? Perhaps it's because
> you have to do these same kind of checks in perl on occasion?

Yes, occasionally. But this happens at runtime. In Java the thing wont
even compile. Also, please count the occurances of can() and isa() in
Perl code and compare the number to 'instanceof' and typecasts in Java
programs.

Often enough I had to program in Java and each time I got sick of these
(deliberate, I may add) limitations of this language. This will turn any
medium-sized program into something bloated with many auxiliary
interfaces and classes that wouldn't be there if Java chose a more
reasonable approach.
>: Therefore I never quite understood how SUN can claim that Java has
>: polymorphism at all.
>
> Perhaps because it does?

Tassilo v. Parseval wrote:
> No, not in Java. Due to broken-by-design method dispatch, you will
> constantly be checking the type and then do a typecast. If you have a
> class "Foo" with a method "bar" and you stuff 10 Foo objects into
>
> Object array[10];
>
> you can't just say 'array[0].bar'.

Assuming that you are an adult, you declared it:
Foo array[10];
and then you can say:
array[0].bar();
> Instead you have to write
>
> ((Foo)array[0]).bar();
>
> This gets worse if 'array' contains Foo and Bar objects and both have a
> "bar" method. Then this becomes:
>
> if (array[0] instanceof Foo) {
> ((Foo)array[0]).bar();
> } else {
> ((Bar)array[0]).bar();
> }
>
> Thus, it is often required in Java to do the type checking by hand.
> Therefore I never quite understood how SUN can claim that Java has
> polymorphism at all.

No, assuming that you are an adult, you declared
interface BarInterface {
void bar();
}
and you declared both classes Foo and Bar as:
implements BarInterface
and you declared the array as:
BarInterface array[10];
and then you can say:
array[0].bar();

--
John W. Kennedy
"But now is a new thing which is very old--
that the rich make themselves richer and not poorer,
which is the true Gospel, for the poor's sake."
-- Charles Williams. "Judgement at Chelmsford"

Tassilo v. Parseval wrote:
> Too bad that you sometimes have no choice. Just look at some of the
> classes in the Java API (like 'Collection' or so). They all cast their
> objects down to the most generic class 'Object'.

Which is why Java 1.5 includes generic types, so that you can declare a
collection as:
Collection<Foo> fooset;
> Take this hierarchy:
>
> Class1;
> Class2 extends Class1;
> Class3 extends Class2; // and possibly overrides Class1.method()
>
> Say, that each of these classes is instantiatable. So I'd naturally
> choose
>
> Class1 array[10];
>
> How exactly would that avoid typecasts? Sure, I can probably have each
> of these three implement an interface and change the type of the array
> to that of the common interface. However, do I want that? Certainly not.
> It means I, the programmer, have to accept such a red-herring in order
> to make polymorphism work as expected and convenient.

Poor baby!

If you're too big a coward to tell your lies about Java in Java
newsgroups, then keep the Hell off the subject of Java in other groups.

--
John W. Kennedy
"But now is a new thing which is very old--
that the rich make themselves richer and not poorer,
which is the true Gospel, for the poor's sake."
-- Charles Williams. "Judgement at Chelmsford"

Also sprach John W. Kennedy:
> Tassilo v. Parseval wrote:
>> Too bad that you sometimes have no choice. Just look at some of the
>> classes in the Java API (like 'Collection' or so). They all cast their
>> objects down to the most generic class 'Object'.
>
> Which is why Java 1.5 includes generic types, so that you can declare a
> collection as:
> Collection<Foo> fooset;

I am aware of that. Java 1.5 is still beta and so I don't see any reason
why I should withdraw my statement.
>> Take this hierarchy:
>>
>> Class1;
>> Class2 extends Class1;
>> Class3 extends Class2; // and possibly overrides Class1.method()
>>
>> Say, that each of these classes is instantiatable. So I'd naturally
>> choose
>>
>> Class1 array[10];
>>
>> How exactly would that avoid typecasts? Sure, I can probably have each
>> of these three implement an interface and change the type of the array
>> to that of the common interface. However, do I want that? Certainly not.
>> It means I, the programmer, have to accept such a red-herring in order
>> to make polymorphism work as expected and convenient.
>
> Poor baby!
>
> If you're too big a coward to tell your lies about Java in Java
> newsgroups, then keep the Hell off the subject of Java in other groups.

I am not subscribed to any Java newsgroup, so I couldn't see the
discussion evolving from that. I am afraid you have to antagonize me
here in this group (or if you prefer: by mail. I'd be delighted).

Apart from that, everything I wrote in the above paragraph is the truth
for non-beta Javas. Or else show me how to do it without interfaces (I
said that you can use them and that I consider them a red-herring).

"Tassilo v. Parseval" <> wrote in message news:<bvu525$1hl$-Aachen.DE>...
> Also sprach Malcolm Dew-Jones:
> >: > object.method()
> >: >
> >: > instead, and let inheritance take care of what gets done, no?
>
> >: No, not in Java. Due to broken-by-design method dispatch, you will
> >: constantly be checking the type and then do a typecast. If you have a
> >: class "Foo" with a method "bar" and you stuff 10 Foo objects into
>
> >: Object array[10];
> >
> > If they are Foo objects, then why pretend they are just generic Objects?
> > Why not stuff them into
> Too bad that you sometimes have no choice. Just look at some of the
> classes in the Java API (like 'Collection' or so). They all cast their
> objects down to the most generic class 'Object'.

I think you are misunderstanding Java.

The entire reason that your have to lug around vtables is so that
polymorphism will work as you expect. Otherwise, polymorphism is only
one-way any your life is most unpleasant.

If that didn't print "World", we'd be in pretty sad shape (well, those
who use Java would be, I'm not one of those -- I had to go search
language references just to remember how to declare main ;-)
> Java simply is lacking things like C++ templates. Note that C++ would
> become pretty unprogrammable if you didn't have them for the sake of
> genericity and polymorphism.

C++ does not use templates for what you describe above. C++ uses the
same vtable management (in general, though specifics of implementation
differ) as Java. Templates allow CODE to be polymorphic right along
with the objects that the code works on.
> Yes, occasionally. But this happens at runtime. In Java the thing wont
> even compile. Also, please count the occurances of can() and isa() in
> Perl code and compare the number to 'instanceof' and typecasts in Java
> programs.

The reason you use can() or isa() in Perl is (I would assume) much the
same reason that you would use the equivalents in Java: to know if an
object that you have been handed is capable of performing some task.

Now, in Java you have the option of using type-checking to tell you
that up-front if you have designed your class structure correctly. In
Perl, you have to do it manually, because Perl's types are too dynamic
to impose such restrictions (I think Perl 6 aims to allow such
restrictions, though).
> Often enough I had to program in Java and each time I got sick of these
> (deliberate, I may add) limitations of this language.

I think you got stuck with some bad documentation or poorly written
libraries.

Share This Page

Welcome to The Coding Forums!

Welcome to the Coding Forums, the place to chat about anything related to programming and coding languages.

Please join our friendly community by clicking the button below - it only takes a few seconds and is totally free. You'll be able to ask questions about coding or chat with the community and help others.
Sign up now!