They arise from logic, which is the basis of functional programming (some might also say category theory, but they arise there, too.;)) They are very simple and useful for regular everyday programs, and it's odd that they don't exist ALL in mainstream languages.
Product comes from the logical proposition "A and B". It consists of a value of type A, and a value of type B together, ie, a pair. Languages often call the elements of product types "tuples," and usually they are generalized to length-n tuples. This is really convenient when you just want a function to return two or more values.
Sums are more conspicuously missing from popular languages, even though they are a direct dualization of products. They come from the proposition "A or B", so a value of type "A + B" is *either* a value of type A, *or* a value of type B. This is very useful as well. To construct a value of sum type, you say whether you have an A or B:
if x has type A
Left x has type A + (anything) Right x has type (anything) + A
and if y has type A + B
then
case y of
Left l =>... e1...
| Right r =>... e2...
Within e1, we know that l has type A, and within e2, we know that r has type B (although only one branch will be run). This is superior to "if (y.tag == T_LEFT)" because there we don't automatically learn anything about the type of the body of y (supposing it is a C union, or something). Well, C and C++ and Java don't have very good type systems...
Of course you can do these things with classes in an OO language, but in general having to use a heavyweight item to do a simple thing is just a pain. (Especially sums -- it seems the standard way to do this is by a series of 'instanceof' tests followed by casts, ugh.)
I think you're way off base. Static typing helps you catch a large fraction of bugs (these fraction of these bugs being proportional to the quality of your type system) before you ever run your program, which is a very real win. Testing is particularly bad at catching problems in unanticipated inputs or situations, so I don't believe testing can replace static typing as a bug-finding mechanism. (Although testing is of course still important, since it provides another avenue to find bugs.) Tracking down the cause of a type error is always easier than tracking down the cause of a runtime error.
Static typing doesn't come at a huge cost in language complexity. C++ is complex and broken, yes, but there are many much simpler languages (like SML, O'Caml, Haskell) that are statically typed and very elegant. Being a user of SML, I can attest to the fact that its static typing helps catch loads of bugs early--to the point where if your program compiles, it is probably right (indeed, many of the undergraduates at our school, even if they hate typed functional programming, believe this by the end of their first semester with it--I have TA'd these classes and watched programmers learn many times!)
The future (and indeed, where most language design research is done today) is in more powerful type systems that let us express our ideas even more cleanly, reducing run-time bugs even more.
(Again, C++ and Java are definitely not exemplars of this ideal.)
The world does not need more C-alike languages, especially if they don't even add in higher order functions and sum/product types. What are they thinking?!
The size of LCDs is nice, but I prefer them for their pure digital interface, lack of scanning, lower power consumption, and overall crisper pixels. This tech will be good for televisions, but I don't think the LCD will fall to thin CRTS. Now, OLEDs...
I'm talking about, if you're given a language where = means equality, then it is not ambiguous. (For example: I think ML does this quite well. As a bonus, the code wouldn't even *compile* if you tried to do an assignment in a conditional. This is even better than catching the bug at run-time by causing the loop to "fail", as you get in lisp.)
It is not ambiguous in C either, just confusing because they misuse the symbol. Again, I like functional languages too, so I am not trying to defend C. C has bad syntax, among other problems. I think you are trying to put words into my mouth instead of reading what I'm actually arguing.
Lisp's structured expressions promote better understanding of algebra by dispensing with C's confusing order of operations. In short, infix sucks.
I'm afraid I don't see the content of your argument here. What is it about lisp's structured expressions that promotes a better understanding of algebra? Why does infix suck? C is not the only implementation of infix operators, so citing it as a broken language does not advance your point, unless you can argue that these are intrinsic issues with infix.
To reiterate my argument: Using = to mean equality is better because it has precedent in mathematics, meaning that people who look at it have a (correct) preconception of what it means. Using suggestive notation helps make the meaning of programs more transparent, which means that they are easier to read and write.
It is not ambiguous when given the language. Many languages other than C/C++ don't screw this up, and use the equal sign in infix for equality, just like mathematics. You haven't provided an argument for why the lisp expression is preferable to that.
I thought the question was of economy. (I disagree that we should stick that 'if' in there, since the lisp expression computes a truth value, just as the C operator == or the ML operator = does. For the same meaning, the expression 'a = b' is certainly shorter than the lisp one.)
If we're talking about making sense of a program, then of course the question is not just a matter of counting characters. But I still disagree--every language has basic syntactic notions that you must understand before being able to read the program, and lisp is certainly no special case here. If you truly don't know lisp, I expect that prefix notation, knowing that ? is part of the symbol name and not some other syntax, and the parentheses denoting function application are all non-obvious. At least an infix equal sign has precedent in elementary school mathematics (among other places).
I absolutely do not intend to defend C's choice to use = to mean assignment, which I think is misleading on top of being unprecedented.
Well, ha ha, but most people I know who use powerful type systems don't actually use type debuggers. Once you get comfortable with that way of structuring your programs, type errors are almost always very shallow.
I do agree with the authors that "natural" problem-specific languages are useful for people who are not normally programmers (those people will increase in number dramatically, soon), but I disagree that this is an appropriate condition for the design of general-purpose languages. The reason is that there already *is* a "natural" model of computation (ie, logic), and I believe that's something that we as humans should be striving to learn and understand, not, as these authors seem to imply, replace with a more "human" notion of natural. (Disclaimer: I do not claim that any existing languages, much less so popular imperative languages like C and Java, succeed in embodying this principle yet.)
Slashdot of all places should be immune to this kind of argument. Don't you guys pride yourselves on picking technology (even underground technology) based on its merits, not its popularity or corporate backing?
Oh, I would recommed the STL if you are in a hurry. I don't know why functional is better, personally it just gave me a headache in school.
Among the many reasons that functional languages are superior for this kind of task is algebraic data types and pattern matching. Since C++ and Java don't even have sum types, the only way to simulate this is with a load of objects and "instanceof" stuff. For example, here's a simple calculator interpreter in ML:
datatype exp =
Int of int
| Plus of exp * exp
| Times of exp * exp
(* if, then, else *)
| Ifzero of exp * exp * exp
(* evaluates an expression, returning an int *) fun eval (Int i) = i
| eval (Plus (e1, e2)) = eval e1 + eval e2
| eval (Times (e1, e2)) = eval e1 + eval e2
| eval (Ifzero (b, t, f)) = if eval b = 0
then eval t
else eval f
That's it! These sorts of recursive passes over syntax trees is exactly what goes on for the bulk of a compiler or interpreter. Just think about what a mess this would be with the STL.
Perl might not be the best starting point if you want to learn something about desining a programming language. If you're thinking of using that, I'd say you're better off starting from scratch.
Functional languages, especially those with pattern matching primitives (like ML or Haskell), are really good at this kind of program -- in fact, writing compilers and interpreters is really their shining point. I highly recommend using one of these languages rather than C. Lots of undergraduate computer science classes (like 15-212 and 15-312 at my university) write interpreters in functional languages as part of the curriculum. You could try to find some course notes... I speak from experience when I say that this beats the hell out of mucking around in C or C++, not really knowing what you're doing.;)
Even saying you have experience with procedural, functional, and OO languages doesn't even begin to cover all of the possibilities. As a programming languages researcher, I see new several new programming languages (or at minimum, pl constructs) at each conference---and these aren't just syntactically variations on known languages, they're significantly new (that's why they constitute research!)
They arise from logic, which is the basis of functional programming (some might also say category theory, but they arise there, too. ;)) They are very simple and useful for regular everyday programs, and it's odd that they don't exist ALL in mainstream languages.
... e1 ... ... e2 ...
Product comes from the logical proposition "A and B". It consists of a value of type A, and a value of type B together, ie, a pair. Languages often call the elements of product types "tuples," and usually they are generalized to length-n tuples. This is really convenient when you just want a function to return two or more values.
Sums are more conspicuously missing from popular languages, even though they are a direct dualization of products. They come from the proposition "A or B", so a value of type "A + B" is *either* a value of type A, *or* a value of type B. This is very useful as well. To construct a value of sum type, you say whether you have an A or B:
if x has type A
Left x has type A + (anything)
Right x has type (anything) + A
and if y has type A + B
then
case y of
Left l =>
| Right r =>
Within e1, we know that l has type A, and within e2, we know that r has type B (although only one branch will be run). This is superior to "if (y.tag == T_LEFT)" because there we don't automatically learn anything about the type of the body of y (supposing it is a C union, or something). Well, C and C++ and Java don't have very good type systems...
Of course you can do these things with classes in an OO language, but in general having to use a heavyweight item to do a simple thing is just a pain. (Especially sums -- it seems the standard way to do this is by a series of 'instanceof' tests followed by casts, ugh.)
I think you're way off base. Static typing helps you catch a large fraction of bugs (these fraction of these bugs being proportional to the quality of your type system) before you ever run your program, which is a very real win. Testing is particularly bad at catching problems in unanticipated inputs or situations, so I don't believe testing can replace static typing as a bug-finding mechanism. (Although testing is of course still important, since it provides another avenue to find bugs.) Tracking down the cause of a type error is always easier than tracking down the cause of a runtime error.
Static typing doesn't come at a huge cost in language complexity. C++ is complex and broken, yes, but there are many much simpler languages (like SML, O'Caml, Haskell) that are statically typed and very elegant. Being a user of SML, I can attest to the fact that its static typing helps catch loads of bugs early--to the point where if your program compiles, it is probably right (indeed, many of the undergraduates at our school, even if they hate typed functional programming, believe this by the end of their first semester with it--I have TA'd these classes and watched programmers learn many times!)
The future (and indeed, where most language design research is done today) is in more powerful type systems that let us express our ideas even more cleanly, reducing run-time bugs even more.
(Again, C++ and Java are definitely not exemplars of this ideal.)
The world does not need more C-alike languages, especially if they don't even add in higher order functions and sum/product types. What are they thinking?!
Indeed. The Wacom ArtZ II is the only piece of hardware I still have and use from my first computer 10 years ago!
Impossible! This doesn't take into account... wait, brb...
The size of LCDs is nice, but I prefer them for their pure digital interface, lack of scanning, lower power consumption, and overall crisper pixels. This tech will be good for televisions, but I don't think the LCD will fall to thin CRTS. Now, OLEDs...
Suck it down.
I'm talking about, if you're given a language where = means equality, then it is not ambiguous. (For example: I think ML does this quite well. As a bonus, the code wouldn't even *compile* if you tried to do an assignment in a conditional. This is even better than catching the bug at run-time by causing the loop to "fail", as you get in lisp.)
It is not ambiguous in C either, just confusing because they misuse the symbol. Again, I like functional languages too, so I am not trying to defend C. C has bad syntax, among other problems. I think you are trying to put words into my mouth instead of reading what I'm actually arguing.
Lisp's structured expressions promote better understanding of algebra by dispensing with C's confusing order of operations. In short, infix sucks.
I'm afraid I don't see the content of your argument here. What is it about lisp's structured expressions that promotes a better understanding of algebra? Why does infix suck? C is not the only implementation of infix operators, so citing it as a broken language does not advance your point, unless you can argue that these are intrinsic issues with infix.
To reiterate my argument: Using = to mean equality is better because it has precedent in mathematics, meaning that people who look at it have a (correct) preconception of what it means. Using suggestive notation helps make the meaning of programs more transparent, which means that they are easier to read and write.
I thought the metric was economy?
It is not ambiguous when given the language. Many languages other than C/C++ don't screw this up, and use the equal sign in infix for equality, just like mathematics. You haven't provided an argument for why the lisp expression is preferable to that.
I thought the question was of economy. (I disagree that we should stick that 'if' in there, since the lisp expression computes a truth value, just as the C operator == or the ML operator = does. For the same meaning, the expression 'a = b' is certainly shorter than the lisp one.)
If we're talking about making sense of a program, then of course the question is not just a matter of counting characters. But I still disagree--every language has basic syntactic notions that you must understand before being able to read the program, and lisp is certainly no special case here. If you truly don't know lisp, I expect that prefix notation, knowing that ? is part of the symbol name and not some other syntax, and the parentheses denoting function application are all non-obvious. At least an infix equal sign has precedent in elementary school mathematics (among other places).
I absolutely do not intend to defend C's choice to use = to mean assignment, which I think is misleading on top of being unprecedented.
I'd say that
a = b
beats that expression for economy.
Well, ha ha, but most people I know who use powerful type systems don't actually use type debuggers. Once you get comfortable with that way of structuring your programs, type errors are almost always very shallow.
I do agree with the authors that "natural" problem-specific languages are useful for people who are not normally programmers (those people will increase in number dramatically, soon), but I disagree that this is an appropriate condition for the design of general-purpose languages. The reason is that there already *is* a "natural" model of computation (ie, logic), and I believe that's something that we as humans should be striving to learn and understand, not, as these authors seem to imply, replace with a more "human" notion of natural. (Disclaimer: I do not claim that any existing languages, much less so popular imperative languages like C and Java, succeed in embodying this principle yet.)
I nominate this story for the Most Humorously Broken Title award.
Half Life 2. I hear that it's an "instant classic."
Slashdot of all places should be immune to this kind of argument. Don't you guys pride yourselves on picking technology (even underground technology) based on its merits, not its popularity or corporate backing?
Why is iTunes one of the good guys? Because it has a nice user interface?
Oh, I would recommed the STL if you are in a hurry. I don't know why functional is better, personally it just gave me a headache in school.
Among the many reasons that functional languages are superior for this kind of task is algebraic data types and pattern matching. Since C++ and Java don't even have sum types, the only way to simulate this is with a load of objects and "instanceof" stuff. For example, here's a simple calculator interpreter in ML:
datatype exp =
Int of int
| Plus of exp * exp
| Times of exp * exp
(* if, then, else *)
| Ifzero of exp * exp * exp
(* evaluates an expression, returning an int *)
fun eval (Int i) = i
| eval (Plus (e1, e2)) = eval e1 + eval e2
| eval (Times (e1, e2)) = eval e1 + eval e2
| eval (Ifzero (b, t, f)) = if eval b = 0
then eval t
else eval f
That's it! These sorts of recursive passes over syntax trees is exactly what goes on for the bulk of a compiler or interpreter. Just think about what a mess this would be with the STL.
Perl might not be the best starting point if you want to learn something about desining a programming language. If you're thinking of using that, I'd say you're better off starting from scratch.
;)
Functional languages, especially those with pattern matching primitives (like ML or Haskell), are really good at this kind of program -- in fact, writing compilers and interpreters is really their shining point. I highly recommend using one of these languages rather than C. Lots of undergraduate computer science classes (like 15-212 and 15-312 at my university) write interpreters in functional languages as part of the curriculum. You could try to find some course notes... I speak from experience when I say that this beats the hell out of mucking around in C or C++, not really knowing what you're doing.
Are there (practical) rewrite limits for USB flash drives? Is there a chance that the data would degrade on the drive over time?
Yes and yes.
Losing votes should "accumulate" and credit the party for the next election, so that everyone gets representation eventually. ;)
Okay, will they fix the web site now? I want to learn about bees!
Even saying you have experience with procedural, functional, and OO languages doesn't even begin to cover all of the possibilities. As a programming languages researcher, I see new several new programming languages (or at minimum, pl constructs) at each conference---and these aren't just syntactically variations on known languages, they're significantly new (that's why they constitute research!)
Or the United States Armed Forces?
Even serious programming language researchers don't claim to know every language; there's just too many of them!
We once got an application from someone who claimed to know "every programming language" on his resume.