Reputation: 2612
Give an ugly example:
data Bighead = Big
little = 1
f1 = little :: Int
f2 = Big :: BigHead
In my opinion:
f1
and f2
all point to some data. the only different of (little
and Big
) is
little has a piece of code to do evaluation. but Big doesn't.
They all have a rewritable body, little can be transformed from a collection of data to a result, and Big is just don't do the last step --- it always holds this data forms (but recursively they can be evaluated).
But in syntax form, they are almost the same: can be applied, can be evaluated.
One big deal may be that functions can't alter its applied params, but data can do.
Is this the only reason that Haskell treats data and function's names differently?
Call for analysis :-)
edit: some more pads
data A = B Int
type of B
:
B :: Int -> A
b :: Int -> A
b = B
Upvotes: 22
Views: 5488
Reputation: 29
In addition to disambiguating parsing etc., already mentioned, there's also readability (and parsing) for humans reading the program. Some supporting quotes:
Programs must be written for people to read, and only incidentally for machines to execute.
--- Abelman and Sussman, Structure and Interpretation of Computer Programs
Any fool can write code that a computer can understand. Good programmers write code that humans can understand.
--- Martin Fowler
Upvotes: 2
Reputation: 138007
From the Haskell 98 Language we see the core distinction in identifier tokens in Haskell:
varid -> (small {small | large | digit | ' })<reservedid>
conid -> large {small | large | digit | ' }
That is, the language fundamentally distinguish variable names ("varid") from constructor names ("conid"), at all levels of the language (both value and type variables and constructors). So clearly, Haskell distinguishes identifiers into two main namespaces (well, there are others, if you count modules and classes), but two primary ones, those that begin with a lower-case letter (variable identifiers) and those that begin with an upper-case letter (constructor identifiers).
So, given that we do distinguish constructors from variables, the question is "why?".
Reading types
One plausible argument is that it makes it very easy to spot parameters in types (e.g. polymorphic types).
Pattern matching
Secondly, and more importantly, we have uniform syntax for data construction and deconstruction (pattern matching). Whenever you see an upper case identifier in a pattern,
case x of
Foo y z -> ...
You know that Foo
is a data structure being taken apart and its components named. Correspondingly, whenever you see an upper case identifier in an expression,
g (f (Foo 1 2)
you know that f
is receiving a newly built Foo
data type with two arguments.
So, since constructors (both type and value) are so important in the language, this simple restriction to upper case identifiers makes it much easier for a human to see what is going on in a piece of code. In some ways upper case letters make up for the lack of other syntactic noise in the language, as an aid to the reader.
Namespaces
There are six kinds of names in Haskell : those for variables and constructors denote values; those for type variables, type constructors, and type classes refer to entities related to the type system; and module names refer to modules. There are two constraints on naming:
Names for variables and type variables are identifiers beginning with lowercase letters or underscore; the other four kinds of names are identifiers beginning with uppercase letters. An identifier must not be used as the name of a type constructor and a class in the same scope. These are the only constraints; for example, Int may simultaneously be the name of a module, class, and constructor within a single scope.
Haskell B
In Haskell B, constructors and variables could use either case.
Upvotes: 32
Reputation: 370465
Constructor names need to be syntactically different from variable/function names to differentiate between variables and constructors in pattern matches. Example:
f (Foo bar) Baz bay = bar + bay
Here Haskell knows that Foo
and Baz
are constructors it should match against and bar
and bay
are variables it should introduce because of the way they are capitalized.
Upvotes: 12