FacebookTwitter
Hatrack River Forum   
my profile login | search | faq | forum home

  next oldest topic   next newest topic
» Hatrack River Forum » Active Forums » Books, Films, Food and Culture » Cousin's Aunt's Daughter's Brother Russell's Introduction to Types

   
Author Topic: Cousin's Aunt's Daughter's Brother Russell's Introduction to Types
fugu13
Member
Member # 2859

 - posted      Profile for fugu13   Email fugu13         Edit/Delete Post 
(all code below is pseudocode)

<edit>and Russell is my name IRL</edit>

I've done a similar series to Hobbes, though most of you haven't been present for it, they were in chat. I have been inspired to move them onto Hatrack [Smile] .

Types are a very powerful concept in programming. Very early programming involved manipulating memory (that is, bits of 1's and 0's) directly. One needed to keep track of what a particular group of memory "meant" -- was it a word, or a number, or a picture of an apple? -- it could be used for just about anything, but usually if one used it for something other than its intended use, the result was gibberish -- a picture of an apple doesn't have any useful meaning as a word.

Very early types solved this problem by requiring one to specify types in the program one was writing. So one might say
code:
Integer xx = 5
Integer yy = 10
Integer zz = xx + yy

In the cases one wanted to convert between the types, one had to make it explicit, something like this:
code:
FloatingPointNumber mm = <FloatingPointNumber> zz

with zz "converted" to a floating point number from its previous integer type. Now, no conversion actually happened in these early languages. This was just a way for the compiler[1] to keep track of what types were being used, and alert the programmer to when he used some bits as one type when they were labeled as another. This was incredibly useful, because that usually indicates a programming error -- remember, the bits representing one thing are often gibberish when interpreted as another type of bits.

This is called compile-time type checking -- all the type checking is done when the program is compiled. Some programming languages later added a feature called run-time type checking. In this, the first few bits of any "thing" represent what type that thing is. So when a program is run, if someone ever tries to convert the data to an incompatible "type" (there are several situations where this could happen even with compile-time type checking), the program complains and fails. In a program that only uses compile time type checking, the result will often be gibberish (or worse, actually), but the programmer won't know where in the program the gibberish resulted from, and will have to painstakingly track it down by hand. With run time type checking point of failure is much easier to determine.

Now, so far I've just treated types as being there. Now I will answer the question, where do types come from?

There are two principle kinds of types: built-in types, and user-defined types. Built-in types are those types that "come with" a programming language, and are generally considered "more fundamental" (though this is largely due to which programming languages have become popular). They often include integers, and floating point numbers, and strings, and files, along with a few others.

The most common way for the user to define types is the object oriented way, and its rather silly in a number of ways, so I'm going to skip it for now and start with the sensible way.

The sensible way is direct definition. For instance, here is a definition for the Color type:

code:
Type Color is Red or Green or Blue \
or Orange or Fuschia or Mauve or Orange or Purple or Pink

And so on until all colors one might choose to use are included (if one wishes to add a color as an option, just add it to the type definition). This makes sense -- the type of Red is Color. In fact, if one wanted to expand the collection of colors without changing the definition itself (maybe its in someone else's file), one could inherit the type, like this:

code:
Type MyColor from Color is Lime or Lavender

And then both Lime and Lavender would be of type MyColor, which is a subtype of Color, so both would be of type Color as well, meaning one could use them anywhere a Color could be used (for instance, in a function like Paint(Thing xx, Color yy), which if called like Paint(MyHighSchool, Lime) paints MyHighSchool the Color Lime).

And if the type Color had certain behaviors, one could make those explicit as well:

code:
Type Color is Red or Green does Compare

Which might mean you can ask the relationship between colors (perhaps along the darkness/lightness contiuum) (this function would have to be defined elsewhere).

The reason for doing this instead of just putting the types in the function definition for the Compare function is, there may be another function that doesn't name a very specific type, it may name a behavior. For instance Sort(List of Things that do Compare) would sort a list of any things that understand how to Compare. If you didn't say that a Color could be Compared, the type checking mechanism wouldn't either.

Now, on to the silly way for users to define types, the object oriented way. In this way, user defined types are actually composites of built-in types and other user-defined types. For instance, one might create the Color type like so:

code:
type Color {
string Name
}

This is of course, oversimplified, but the basics are there. Now as to why this is silly -- what on earth does being a color have to do with having a name that's a string, and why am I able to name a color Bob? There are no inherent restrictions on the type, only ones that are checked programmatically, which just adds more bookkeeping, like we needed for the most primitive notion of types, which allows many errors.

So for instance, our object oriented Color type might end up being more like
code:
type Color {
string Name

function Color(string xx) {
if xx == "orange" or xx == "peach" or xx == "red" {
Name = xx
}
else {
throw WrongColorNameError
}
}
}

(the function with the same name as the type is called to "create" an object having the type)

Now that's silly. And it gets worse if we try to inherit from Color and want to maintain that type checking:
code:
type MyColor from Color {
function MyColor(string xx) {
if xx == "purple" {
Name = xx
}
else {
parent.Color(xx)
}
}
}

We don't need to define Name because it is inherited from Color, and parent calls a function from the parent type. And this is just one of the simplest examples, in more complex examples the solutions are not so "elegant" (and the elegance of this solution is limited at best).

Now, object oriented thinking is not all silly. There are things which are best described in terms of the properties they have, rather than any intrinsic relationship (as the first means of user defined typing is done). For instance, a form on a website has many fields, which each have contents. Object oriented design is very useful for describing such situations. In fact, GUIs (Graphical User Interfaces), such as your computer displays on the screen, were an original impetus towards object oriented design.

Well, that's it for types for now. The above pretty much encompasses the basics, as well as touching on a few more complex issues involving typing. I am always available to answer questions, either on Hatrack or on AIM (well, except when I'm not. In which case I'll get back to you).

[1] a compiler converts a program as a human writes it into a form a machine can interpret.

[ May 19, 2004, 01:47 PM: Message edited by: fugu13 ]

Posts: 15770 | Registered: Dec 2001  |  IP: Logged | Report this post to a Moderator
aspectre
Member
Member # 2222

 - posted      Profile for aspectre           Edit/Delete Post 
Is there a purpose behind creating a thread that can only be read by scrolling side to side?
Posts: 8501 | Registered: Jul 2001  |  IP: Logged | Report this post to a Moderator
fugu13
Member
Member # 2859

 - posted      Profile for fugu13   Email fugu13         Edit/Delete Post 
Odd, it doesn't create any scrolling problems in Safari or in Firefox, even if I shrink my screen a fair amount. I'll change what I think is the most likely cause, and tell you to get a better browser or use a larger resolution, or both [Razz] .
Posts: 15770 | Registered: Dec 2001  |  IP: Logged | Report this post to a Moderator
St. Yogi
Member
Member # 5974

 - posted      Profile for St. Yogi   Email St. Yogi         Edit/Delete Post 
I don't have a problem and I'm using IE. It's probably the Resolution.
Posts: 739 | Registered: Dec 2003  |  IP: Logged | Report this post to a Moderator
ak
Member
Member # 90

 - posted      Profile for ak   Email ak         Edit/Delete Post 
If you will lose Pink off the end of that long code string, I think that will improve readability. --- Edit: oh I see you fixed it. [Smile]

I have a question. Is there a functional difference between a type and a structure? In C I rarely if ever used a user-defined type, but instead defined all my data (records and so on) as structures (or arrays of structures). In object oriented code is it more common to make everything a type?

The only sort of thing for which I might think of using a user-defined type is, for instance, if I needed a bunch of quadruple long integers for some reason, or something odd like that. Then I might stick four long integers together, and define functions like addQuad, subtractQuad, multiplyQuad, divideQuad that handled the stuck-together longs as one big integer. That would suggest a new type to my mind.

Is that an old way of thinking? I've done little to no object oriented programming.

[ May 19, 2004, 02:05 PM: Message edited by: ak ]

Posts: 2843 | Registered: A Long Time Ago!  |  IP: Logged | Report this post to a Moderator
saxon75
Member
Member # 4589

 - posted      Profile for saxon75           Edit/Delete Post 
In VHDL it's very common to use enumerated types for state machine design.
Posts: 4534 | Registered: Jan 2003  |  IP: Logged | Report this post to a Moderator
Bokonon
Member
Member # 480

 - posted      Profile for Bokonon           Edit/Delete Post 
ML stinks.

[Razz]

-Bok

Posts: 7021 | Registered: Nov 1999  |  IP: Logged | Report this post to a Moderator
Bokonon
Member
Member # 480

 - posted      Profile for Bokonon           Edit/Delete Post 
ak, OOP classes (or "Types") are essentially data structures plus goodies. The goodies are a cleaner way of associating functions to them (since objects not only ARE, they also DO), as well as allowing restrictions on what can access certain parts, and which ways the access is allowed. This is useful for code reuse, so that if the original prgrammer changes how a list of items is stored (from, say, an array, to a doubly-linked list), as long as the "public"ly accessable portions don't change, it makes no difference to the end-user.

-Bok

EDIT:

In C, a struct for a circle might be

[In psuedocode]
STRUCT circle
{
int x;
int y;
int r;
}

function getArea(circle)
function getCircumference(circle)

Note, in the above functions, to be codesafe, you need to ensure that what is being passed in is a circle struct as you have defined it. Also, what happens if someone uses your area function to try and compute the area of a rectangle?

In OOP, the Circle structure "owns" those utility functions so the structure would look more like:

STRUCT circle
{
int x, y, r;
function getArea()
function getCircumference()
}

The above minimizes the confusion of what area is being computed. You could now have code that says:

Circle a;
...
a.getArea();

It's more readable this way.

[ May 19, 2004, 02:21 PM: Message edited by: Bokonon ]

Posts: 7021 | Registered: Nov 1999  |  IP: Logged | Report this post to a Moderator
fugu13
Member
Member # 2859

 - posted      Profile for fugu13   Email fugu13         Edit/Delete Post 
<edit>this is a response to ak</edit>

Umm, that's a very old way of thinking.

And I was actually making up a keyword for my pseudocode to avoid introducing extraneous terms; the C++ keyword is class, which is a C struct with much better type checking and functions.

User defined types are exceptionally useful (particularly Higher Order Types, which I didn't discuss yet). It is safe to say that the modern operating system would not exist without strong user defined types.

<edit>yes, Bok touches on some of the particular uses of OOP in modern programming -- it would be hideous to have to rewrite an entire operating system because the implementation of a data structure changed.</edit>

[ May 19, 2004, 02:20 PM: Message edited by: fugu13 ]

Posts: 15770 | Registered: Dec 2001  |  IP: Logged | Report this post to a Moderator
ak
Member
Member # 90

 - posted      Profile for ak   Email ak         Edit/Delete Post 
Okay, thanks, that makes more sense.

I'm not surprised if I'm guilty of very old thinking. I haven't worked as a programmer in 15 years (sheesh!), though I dabble in this and that for my various engineering projects. [Smile]

Class was the (key)word I was looking for, yes. I think they use that for lots of different OOP languages, don't they? At least I'm pretty sure that's what they are called in two different C++ implementations I've seen (MS and Borland) and MS Visual Basic.

This is very interesting to me. I'd love to hear more. Especially the pseudocode snippets to illustrate everything being described are quite useful. If you are most familiar with some particular implementation, it would not upset me if you used specific code from it, as well, if it's easier. For me, having things be nailed down and rigorous makes them easier for me to get a handle on. It narrows down the possible interpretations.

Posts: 2843 | Registered: A Long Time Ago!  |  IP: Logged | Report this post to a Moderator
Richard Berg
Member
Member # 133

 - posted      Profile for Richard Berg   Email Richard Berg         Edit/Delete Post 
quote:
This is very interesting to me. I'd love to hear more.
I usually chastise people for cross-forum linking, but your curiousity just begs for this thread (warning: don't click when busy).

To answer your original question: a "structure" is a C term for a certain kind of type that's simply constructed from other primitives. It's similar to what database people will call a "record," or some functional languages a "tuple" (a Cartesian product, in this case one of other types). We might define a C struct with pseudosyntax:
code:
struct        :: [structtype] -> memory layout
structtype = Int | Bool | Float | structtype

Obviously these beasts are extremely useful in every kind of programming language, but they do not express everything that a computer scientist normally means by "type." The latter is really any mapping from ideas to bits that occurs in our brains and/or compilers.

C/C++'s typedef keyword really has nothing to do with the language's typesystem aside from attempting to make ugly things prettier. It's just an alias.

(edit) to note, since it's not obvious upon rereading, that when I put stuff in brackets I'm loosely borrowing Haskell notation meaning "a list of these things"

[ May 19, 2004, 03:08 PM: Message edited by: Richard Berg ]

Posts: 1839 | Registered: May 1999  |  IP: Logged | Report this post to a Moderator
   

   Close Topic   Feature Topic   Move Topic   Delete Topic next oldest topic   next newest topic
 - Printer-friendly view of this topic
Hop To:


Contact Us | Hatrack River Home Page

Copyright © 2008 Hatrack River Enterprises Inc. All rights reserved.
Reproduction in whole or in part without permission is prohibited.


Powered by Infopop Corporation
UBB.classic™ 6.7.2