Haskell programming language: Difference between revisions
imported>Walter Rorie-Baety (Started the Introduction; working on what/how to continue the article) |
imported>Walter Rorie-Baety (Fleshing out the characteristics as first given.) |
||
Line 1: | Line 1: | ||
The '''Haskell programming language''' is a general-purpose, purely functional programming language, with lax ("non-strict") semantics and strong, static typing, named for logician Haskell B. Curry. Haskell is best known for three things: 1) adhering almost religiously to the principle of ''referential transparency'', the concept that replacing a function call with the results of the call should not otherwise change the behavior of the program; 2) a semi-official tongue-in-cheek rite-of-passage of writing tutorials in the chosen mechanism Haskell uses to deal with non-determinism, optional results, and especially I/O: ''monads''; 3) a fondness for using names of concepts taken from abstract mathematics, such as the previously mentioned monads. The third point is especially interesting, since Haskell enthusiasts consequently garner criticism for both sides of the practical/abstract divide; "professional" programmers hate the use of short cryptic-looking names for things more usually described with a multi-syllabic class name ending in "-able", while abstract mathematicians are equally quick to point of that Haskell's names for things don't exactly line up with the high-powered math concepts that gave the inspiration. Haskell brings a non-typical whitespace-sensitive layout structure and equational style of function definition, which tends to make its programs look more like math papers that computers understand, than your typical "line noise" look of C or Perl. However, Haskell's lack of distinction between variables and functions, and especially between functions that are or aren't recursive, allows for understandable and surprisingly efficient high-level coding. Haskell also makes heavy use of ''higher-order functions'': functions that take other functions are arguments, and give functions as results. Haskell (the language) is rooted in the observations of Haskell (the mathematician) Curry and his disciples, that "a proof is a program; the formula it proves is a type for the program". | The '''Haskell programming language''' is a general-purpose, purely functional programming language, with lax ("non-strict") semantics and strong, static typing, named for logician Haskell B. Curry. Haskell is best known for three things: 1) adhering almost religiously to the principle of ''referential transparency'', the concept that replacing a function call with the results of the call should not otherwise change the behavior of the program; 2) a semi-official tongue-in-cheek rite-of-passage of writing tutorials in the chosen mechanism Haskell uses to deal with non-determinism, optional results, and especially I/O: ''monads''; 3) a fondness for using names of concepts taken from abstract mathematics, such as the previously mentioned monads. The third point is especially interesting, since Haskell enthusiasts consequently garner criticism for both sides of the practical/abstract divide; "professional" programmers hate the use of short cryptic-looking names for things more usually described with a multi-syllabic class name ending in "-able", while abstract mathematicians are equally quick to point of that Haskell's names for things don't exactly line up with the high-powered math concepts that gave the inspiration. Haskell brings a non-typical whitespace-sensitive layout structure and equational style of function definition, which tends to make its programs look more like math papers that computers understand, than your typical "line noise" look of C or Perl. However, Haskell's lack of distinction between variables and functions, and especially between functions that are or aren't recursive, allows for understandable and surprisingly efficient high-level coding. Haskell also makes heavy use of ''higher-order functions'': functions that take other functions are arguments, and give functions as results. Haskell (the language) is rooted in the observations of Haskell (the mathematician) Curry and his disciples, that "a proof is a program; the formula it proves is a type for the program". | ||
General-purpose | |||
Unlike more special-purpose functional languages, like the many XML-processing ones (e.g. XSLT, XPath, XQuery), or the database-manipulating SQL, Haskell is general-purpose, as easy to use to access and manipulate databases and XML as it is to write (darcs) a distributed version control system, (Xmonad) a window manager or (snap) a web framework. These tasks are even made more manageable, due to Haskell's ''purity''. | |||
Purity | |||
Haskell, contrary to fast-and-loose descriptions, does not disallow you from code that performs "impure" actions, like accessing a database, file/screen input/output, or random number generation. It does something else highly unusual and easy to get used to: it makes you note in your code that you're doing it. It also gives a tightly-integrated means by which you can still write pure code, and have it work with the impure parts with no problems, and little extra effort. | |||
Functional Programming | |||
Haskell takes the idea of programming with functions and runs with it. Haskell's syntax is especially biased to blur the distinction between a function that takes arguments and gives results, and values. In Haskell, functions are just a special type of value. Also, thanks to its Hindley-Milner type inference engine, much of the boilerplate needed to indicate a function's argument types and result types is automatically figured out from the types needed by other functions before and after it in the processing chain. Programming in Haskell is more like knitting a sweater than forging chain links. | |||
Lax Semantics | |||
The main means by which Haskell is able to do this "figure out the types I want by how I use them with other functions" exploits another of Haskell's unusual characteristics, lax semantics. What this means is that values in Haskell are usually assigned by "call-by-need"; if your function is given a value that it never uses, and never passes on to be used in another function, then that value is never evaluated. It could (normally) cause your computer to crash and spew forth a couple of pages of diagnostics of the internal "call stack" of your program, or just a simple NullPointerException...except, since it isn't used, it'll never be accessed, so it never causes a problem. This allows special function behavior (short-circuiting logical operators) to be standard procedure for the programmer. If you've ever wished you could pass a data structure to a procedure, and have it be tested for being empty from the inside, go ahead. If your algorithm needs a sequence of items, but you need to use a generator to simulate the concept of an infinite sequence, forget about it! Haskell's lax semantics lets you quickly describe your sequence as a list, take as many values from it as you need, and chuck the rest. | |||
Strong Static Typing | |||
If you've ever had to test a value to be sure it could be "coerced" to be a number, then had to test it again just before you used it as a number, then stop! You're trying to construct a static typing system in a language that doesn't have one. Now, there are some things one cannot check in a program until it's actually running on your system. However, if a part of your program expects a value/object/attribute to be in a certain form, the best way to get it to happen is to tell the computer to track it for you. This is what static typing is about; getting the computer to keep track of the details of "what kind of value is this supposed to be?" Haskell does it, and does it in a way that lets you know what's going on, and why. Some people prefer the easy-going style of automatic coercion of numbers to strings, and back again. Others like to be able to do sneaky tricks like have a function give a different result based on what type the answer is. That's very tough to get right in a language that does automatic coercion, but it's just another programming technique for Haskell. |
Revision as of 21:12, 25 January 2011
The Haskell programming language is a general-purpose, purely functional programming language, with lax ("non-strict") semantics and strong, static typing, named for logician Haskell B. Curry. Haskell is best known for three things: 1) adhering almost religiously to the principle of referential transparency, the concept that replacing a function call with the results of the call should not otherwise change the behavior of the program; 2) a semi-official tongue-in-cheek rite-of-passage of writing tutorials in the chosen mechanism Haskell uses to deal with non-determinism, optional results, and especially I/O: monads; 3) a fondness for using names of concepts taken from abstract mathematics, such as the previously mentioned monads. The third point is especially interesting, since Haskell enthusiasts consequently garner criticism for both sides of the practical/abstract divide; "professional" programmers hate the use of short cryptic-looking names for things more usually described with a multi-syllabic class name ending in "-able", while abstract mathematicians are equally quick to point of that Haskell's names for things don't exactly line up with the high-powered math concepts that gave the inspiration. Haskell brings a non-typical whitespace-sensitive layout structure and equational style of function definition, which tends to make its programs look more like math papers that computers understand, than your typical "line noise" look of C or Perl. However, Haskell's lack of distinction between variables and functions, and especially between functions that are or aren't recursive, allows for understandable and surprisingly efficient high-level coding. Haskell also makes heavy use of higher-order functions: functions that take other functions are arguments, and give functions as results. Haskell (the language) is rooted in the observations of Haskell (the mathematician) Curry and his disciples, that "a proof is a program; the formula it proves is a type for the program".
General-purpose Unlike more special-purpose functional languages, like the many XML-processing ones (e.g. XSLT, XPath, XQuery), or the database-manipulating SQL, Haskell is general-purpose, as easy to use to access and manipulate databases and XML as it is to write (darcs) a distributed version control system, (Xmonad) a window manager or (snap) a web framework. These tasks are even made more manageable, due to Haskell's purity.
Purity Haskell, contrary to fast-and-loose descriptions, does not disallow you from code that performs "impure" actions, like accessing a database, file/screen input/output, or random number generation. It does something else highly unusual and easy to get used to: it makes you note in your code that you're doing it. It also gives a tightly-integrated means by which you can still write pure code, and have it work with the impure parts with no problems, and little extra effort.
Functional Programming Haskell takes the idea of programming with functions and runs with it. Haskell's syntax is especially biased to blur the distinction between a function that takes arguments and gives results, and values. In Haskell, functions are just a special type of value. Also, thanks to its Hindley-Milner type inference engine, much of the boilerplate needed to indicate a function's argument types and result types is automatically figured out from the types needed by other functions before and after it in the processing chain. Programming in Haskell is more like knitting a sweater than forging chain links.
Lax Semantics The main means by which Haskell is able to do this "figure out the types I want by how I use them with other functions" exploits another of Haskell's unusual characteristics, lax semantics. What this means is that values in Haskell are usually assigned by "call-by-need"; if your function is given a value that it never uses, and never passes on to be used in another function, then that value is never evaluated. It could (normally) cause your computer to crash and spew forth a couple of pages of diagnostics of the internal "call stack" of your program, or just a simple NullPointerException...except, since it isn't used, it'll never be accessed, so it never causes a problem. This allows special function behavior (short-circuiting logical operators) to be standard procedure for the programmer. If you've ever wished you could pass a data structure to a procedure, and have it be tested for being empty from the inside, go ahead. If your algorithm needs a sequence of items, but you need to use a generator to simulate the concept of an infinite sequence, forget about it! Haskell's lax semantics lets you quickly describe your sequence as a list, take as many values from it as you need, and chuck the rest.
Strong Static Typing If you've ever had to test a value to be sure it could be "coerced" to be a number, then had to test it again just before you used it as a number, then stop! You're trying to construct a static typing system in a language that doesn't have one. Now, there are some things one cannot check in a program until it's actually running on your system. However, if a part of your program expects a value/object/attribute to be in a certain form, the best way to get it to happen is to tell the computer to track it for you. This is what static typing is about; getting the computer to keep track of the details of "what kind of value is this supposed to be?" Haskell does it, and does it in a way that lets you know what's going on, and why. Some people prefer the easy-going style of automatic coercion of numbers to strings, and back again. Others like to be able to do sneaky tricks like have a function give a different result based on what type the answer is. That's very tough to get right in a language that does automatic coercion, but it's just another programming technique for Haskell.