Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

We have all seen integer, floating point, string, and the occasional decimal type. What are some of the most strange or unique or useful types you have encountered, useful or not?

share|improve this question

closed as not constructive by Mark Trapp Jan 13 '12 at 20:32

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.If this question can be reworded to fit the rules in the help center, please edit the question.

    
Hi user10008, welcome to Programmers.SE! Have you checked out our FAQ? Which of the six subjective guidelines do you think your question meets? – user8 Jan 25 '11 at 0:04
3  
Would anyone like to write the entry for Lisp? – Mark C Jan 25 '11 at 1:59
    
I thought it might have been a dupe, but only because my answer would have been a dupe, so I'll post a link and maybe you'll find some good answers: programmers.stackexchange.com/questions/724/… – Peter Turner Jan 25 '11 at 18:58
    
@Mark: I tried, but types are probably one of the least interesting things about Lisp. – Larry Coleman Jan 25 '11 at 21:36
    
@LarryC I thought this was the perfect question for Lisp because of the all-pervasive use of lists ! The lists form the syntax tree and this allows you to write functions that do amazing things to your code, I gather. I'm learning Racket (previously PLT Scheme) now. Lisp is the only programming language I have been truly motivated and interested to learn. – Mark C Jan 26 '11 at 4:45

24 Answers 24

I'll be short:

Maybe a

in Haskell.

With this simple construct, the language solves the issue of crashes or NullPointerException, it neatly sidesteps the "One Million Mistake" of Tony Hoare :)

Frankly, an optional presence checked at compile-time ? It's dreamlike...

share|improve this answer
    
Or Option as it's called in many other programming languages. – Jonas Sep 27 '11 at 6:54
    
@Jonas: I must admit I don't like the Option name. Why not Optional! It may be because I am no native speaker, but Option does not convey the "optional" meaning to me. – Matthieu M. Sep 27 '11 at 7:01
    
The Maybe name is cute: "What do you have?" "Maybe an Int". However, the really neat bit is that it is both a functor and a monad which, in plain speak, means you get null-propagation for free. You never need to put null checks inside functions or in the middle of your code; you only ever need to check it at the very end of your code, if at all. – Tikhon Jelvis Jan 14 '12 at 0:56
    
There's a Maybe monad for Ruby: lostechies.com/derickbailey/2010/10/10/the-maybe-monad-in-ruby – Jason Lewis Jan 14 '12 at 1:03

I am perennially fond of void *. It's probably a symptom of something deeply flawed in me.

share|improve this answer
2  
Yes. I'm afraid that's exactly what it is. :) Oh, +1 for "interesting" rather than "unique". Objective-C obviously has void * and Pascal/Delphi have Pointer. – Frank Shearar Jan 25 '11 at 9:03
    
haha more of a non type, but you can't argue that it is not powerful – user10008 Jan 25 '11 at 17:27
14  
I just love the inherent pessimism it expresses: 'Can you see that thing over there?' 'Yes, what is it?', 'No idea.' – biziclop Jan 25 '11 at 19:11
    
I always thought it was funny that you can't declare a void but you can take the address of it. Seems to me that with struct s { int A; void B; int C ; } that the address of B should be the address of the crack between A and C. But no, not allowed. – Andy Canfield Sep 27 '11 at 9:43
    
That's why in pascal "pointer" is used to denote a generic pointer, and not confuse with "procedure". – umlcat Sep 27 '11 at 15:42

Lua has a built-in table that is most impressive. It has a built-in hashtable and a vector, and with the use of metatables can be the fundamental base for object-oriented programming in a procedural language.

Each index of a table can receive any of the basic language structures (number, boolean, string, function -yes, functions are types on lua -, and tables).

share|improve this answer
    
Note how Javascript is built in a very similar way, and Python is built on the very same foundation, as probably is Ruby. – 9000 Jan 25 '11 at 0:31
    
I think this is also possible in Perl and PHP, yes? – FrustratedWithFormsDesigner Jan 25 '11 at 5:43
    
There is a difference between the tables in lua and the hash containers in other languages. There is a subtle implementation difference in the way lua distributes hash values that makes its tables work in ways that are almost magical. I mostly program in python, and on occasion find that I'm using assumptions that don't hold, based on my expectations of the way tables work in lua. A specific example of this magic is that integers hash to themselves + 1. This means that integer keys are packed densly, and that +0.0 and -0.0 have the same hash (they are equal) – SingleNegationElimination Jan 25 '11 at 6:10

I'm surprised nobody has mentioned Monads or Algebraic Datatypes yet.

share|improve this answer
    
May be show us examples :) – nawfal Oct 1 '15 at 19:17

Lisp has two interesting types: t and nil. What's interesting about them is that everything is a t and nothing is a nil.

share|improve this answer
    
Are you serious? I did not know that. – Mark C Jan 26 '11 at 4:47

SNOBOL: pattern (essentially a LL(1) parser tree, if I remember it correctly).

share|improve this answer

Fortran has common blocks; it's one of the least common data types in modern languages, or, rather an unusual way to efficiently share data.

Fortran 95 has interval types and built-in interval arithmetics.

The list would not be complete without monadic types found in Haskell. To understand them you need a bit of effort.

share|improve this answer
    
Ah, UniData/UniVerse DBs have common blocks in their internal language (UniBasic) too. – Dan McGrath Jan 25 '11 at 0:39
    
Is a common block a block of code that is used by different parts of the program? – Mark C Jan 26 '11 at 4:52
1  
@MarkC IIRC its basically global data, but each function that accesses has to explicitly say it is going to at the top – jk. Sep 27 '11 at 8:32

Delphi has sets (see also), which I don't believe are implemented the same way in other languages.

This makes storing multi-variable attributes in databases a breeze :D

share|improve this answer

I suppose it's really only strange coming from programming on a classical architecture, but certainly one of the hardest types for me to wrap my head around at first was the quantum register, which shows up in QCL.

share|improve this answer

PL/SQL lets you declare variables of type my_table.some_column%type... I find that pretty damn useful.

And C# lets you declare objects as nullable or not, though I'm not sure that counts as a type.

share|improve this answer
4  
But cursor%rowtype is even funnier: it's a dynamically-formed record type that reflects which columns the cursor's query returns. – 9000 Jan 25 '11 at 0:36
    
.NET "Nullable" is actually a (generic) type in itself. – Konamiman Sep 27 '11 at 7:20

I had a soft spot in my heart for Euphoria's data types when I was younger

It is structured as thus:

Object
-> Atom
-> Sequence
  • Atom = A single numeric value
  • Sequence = A sequence of Objects

    -- examples of atoms:
    
    0
    98.6
    -1e6
    
    -- examples of sequences:
    
    {2, 3, 5, 7, 11, 13, 17, 19}
    {1, 2, {3, 3, 3}, 4, {5, {6}}}
    {{"jon", "smith"}, 52389, 97.25}
    {}                        -- the 0-element sequence
    

    See: The Ref Manual

Note: "jon" is actually a short hand way of writing the sequence of ASCII values. For example "ABCDEFG" is the same as {65, 66, 67, 68, 69, 70, 71}

share|improve this answer
7  
This feels LISP-like... – FrustratedWithFormsDesigner Jan 25 '11 at 5:43
    
The actual data types are the only bit. – Dan McGrath Jan 25 '11 at 7:13
1  
@FrustratedWithForms Same, I thought, "Hey, he said, 'Atom'! This looks like (a) Lisp but with unnecessary dividers. :P – Mark C Jan 26 '11 at 4:54

Felix has anonymous sum types. The type is written like:

typedef il = int + long;

as it would be in theory. The values are ugly:

case 0 of il (1)
case 1 of il (2L)

except perhaps for a unit sum such as 3 = 1 + 1 + 1

case 0 of 3
case 1 of 3 

which unfortunately uses zero origin counting for "C compatibility". Anonymous sums are necessary for structurally typed algebraic types, for example:

(1 + T * li) as li

is a (singly linked) list of T. All other languages I know of required nominally typed sums, where both the type itself and the constructors must be given names.

The shorthand 3 used above is cute, the following is in the library:

typedef void = 0;
typedef unit = 1;
typedef bool = 2;

and this notation:

 T ^ 3

is an array of static length 3 .. the 3 is not an integer but a sum of 3 units. What a pity + is not associative :)

share|improve this answer

q/kdb+ has tables built-in. Since it's a programming language and column-oriented database in one, there's no need for LINQ or ORMs.

For example, can create a table like this (assignment is distinquished by : rather than = as in most languages):

people:([]name:`Joe`Amy`Sarah; age:17 15 18; GPA:3.5 3.8 3.33)

Now I can look at my table:

q)show people
name  age GPA 
--------------
Joe   17  3.5 
Amy   15  3.8 
Sarah 18  3.33

And I can query it:

q)select from people where GPA>3.4
name age GPA
------------
Joe  17  3.5
Amy  15  3.8
share|improve this answer

I found union's in C++ to be 'quirky' when I first heard about them. I still haven't hit a scenario where they're the obvious choice to implement.

share|improve this answer
3  
Unions came from C. One good example is the zval struct in php. – Martin Wickman Jan 25 '11 at 7:12
2  
I've used them in a Z80 emulator, to easily access the 16 bit registers as whole registers (HL, BC) and as 8-bit registers (H, L, B and C). This reflects how they're used in Z80 asm. Also in "variants", a class that can hold a value of different types (for example int/float) - not sure why I didn't use subclasses, but it made sense at the time :) – ggambett Jan 25 '11 at 11:50
    
@ggambett: I have done exactly the same for my Z80 programs! Only that I have also added a bitfield to access individual flags in the F register. – Konamiman Sep 27 '11 at 7:21

I'm still trying to wrap my head around what a multi-parameter function becomes in F# and other functional languages. Basically int f(Foo, Bar) becomes func f(Foo)

That is the two parameter function that takes a Foo, and a Bar and returns an int is really a one parameter function that takes a Foo and returns a one parameter function that takes a bar and returns an int. But somehow you can call it with two parameters if you want. I wrote a post about it here

share|improve this answer
8  
Rather, a function f(Foo, Bar) is the same as function f(Foo) that returns another function f'(Bar) which returns the value what f(Foo, Bar) would return. That is, if you fix the 'Foo' argument, but not 'Bar', you have a function that does not depend on 'Foo' but still depends on the 'Bar' argument. This is typical for functional languages; it's called 'currying'. – 9000 Jan 25 '11 at 0:40

Regular Expressions:

They are extremely powerful yet compact objects.
Languages that have them built in have great ability to manipulate text (lets not hear the word parse they are not that good).

share|improve this answer
2  
It is entirely possible to parse many simple grammars with regexes. For instance, it's relatively trivial to parse an ini file with a minimum of logic on top of a set of regexes. The mistake a lot of people make is trying to parse very complex grammars with it (ie. XML/HTML). – Matthew Scharley Jan 25 '11 at 5:33
    
@MatthewSch NEW! How to parse HTML with regex! – Mark C Jan 26 '11 at 4:50
    
@Mark C: The top is answer is (with a record breaking 4320 up votes). You can't – Loki Astari Jan 26 '11 at 5:37
    
Yes, that was for humor. It sprang to mind when I read Matthew's comment. – Mark C Jan 26 '11 at 5:56

A handful of languages in the functional family have a class of types known as Unity. The distinguishing feature of Unity types are that they contain no information, they are zero bit types. A unity type (in some variations) is also its only value, or (in most others) has only one value (that is not itself a type).

These are useful, though, because they are distinguished types. Since you can't implicitly convert from one unity type to another, you can put static type checking to work in a very efficient, and expressive way.

Unity is also the way most such languages describe Enums, by allowing a new type to be any of a defined set of other types, or to describe maybe types, values that may be either a value of a typical type (say, an integer), or have a value that represents no-value.

Some languages that don't employ the richness of user defined unity types still have unity in them, in some form or another. For instance, Python has at least three unity types, NoneType, NotImplementedType, and EllipsisType. It's interesting that the first two both mean something like "No value", but the third is used in complex values (specifically, slice expressions) to represent interesting special cases.

Other interesting examples of unity include NULL in sql and undefined in javascript, but not void in C or C++. void fails. Even though it describes a value of no information, but no actual value can be of type void.

share|improve this answer
    
I think you mean "unit type". – Jason Baker Jan 25 '11 at 9:25

Ruby's symbol type is a bit unusual. It's essentially a string implementing the singleton pattern. Or something. So far, I've found the best uses for symbols are in tracking states and passing function names.

share|improve this answer
    
Also as keys to a map for O(1) key comparison. – Jeremy Heiler Jan 25 '11 at 19:11
    
Well, it's not really that unusual. Ruby inherited it from Smalltalk, which inherited it from Lisp. Scala also has it, I think. In fact, almost every language implementation (compiler or interpreter) has a symbol table internally, Lisp, Smalltalk and Ruby just expose it to the programmer. – Jörg W Mittag Apr 13 '11 at 23:46

COBOL. Essentially only two basic data types, strings and numbers, but you have to specify exactly how they're laid out in memory, e.g. PIC S9(5)V99 COMP-3.

share|improve this answer
    
I can beat that. BCPL has one data type - word; see en.wikipedia.org/wiki/BCPL – Stephen C Jan 25 '11 at 5:20
    
There are different types of numbers (COMP, COMP-1, COMP-2, COMP-3). – David Thornley Jan 25 '11 at 18:47
    
That sounds awful. Can you elaborate on what those details mean? – Mark C Jan 26 '11 at 4:51
    
S = signed, 9(5) = 5 digits, V = implicit decimal point, 99 = 2 more digits, COMP-3 = BCD + sign nybble. – dan04 Jan 26 '11 at 5:28

Clipper had 'Code Blocks', which were similar to anonymous methods. They could be passed around and evaluated as needed, usually as a form of a callback. You'd often use them for things like performing calculations on the fly when presenting tables of data.

share|improve this answer

VHDL has physical types. A literal of such type includes both a value and a unit. You can define subunits as well. For instance, a predefined physical type is time:

type time is range <machine dependant> to <machine dependant> 
units
  fs;
  ps = 1000 fs;
  ns = 1000 ps;
  us = 1000 ns;
  Ms = 1000 us;
  sec = 1000 ms;
  min = 60 sec;
  hr = 60 min;
end units;

Together with operator overloading, you can define very interesting things.

share|improve this answer

Clojure is interesting because it has a meta-concept of "abstractions" that pervade the language. Examples:

  • Collections
  • Sequences (lazy and non-lazy)
  • Higher Order Functions
  • Multimethods
  • Protocols
  • Managed references
  • Macros
  • various others.....

To some extent, the abstractions take the "single responsibility principle" to the extreme. It's up to you to compose them to get the functionality that you want, but you can be extremely flexible about how you glue them together.

For example, if you want a class-based OOP system with inheritance, you could build one out of these core abstractions relatively quickly.

In practice, the abstractions themselves are designed in a way that multiple implementations are possible, e.g. through specific interfaces like clojure.lang.ISeq for sequences or clojure.lang.IFn for higher order functions.

There's an interesting video about this topic: The Art of Abstraction

share|improve this answer

If you want a language with a unique type then head for BCPL. This language only has one data type, the word, being a fixed number of bits for the language implementation.

share|improve this answer

Googles Go has a "Channel" type which is quite unique.

share|improve this answer
1  
Channels aren't unique. Many languages have them. Felix had them 10 years before Google existed :) Ocaml had them 10 years before Felix existed. – Yttrill Jan 13 '12 at 20:13
    
And there was at least one other language which had channels before Ocaml existed. Still one of the least available types in programming languages. – Brainlag Jan 14 '12 at 11:43

Not the answer you're looking for? Browse other questions tagged or ask your own question.