Let's say you wanted to implement I/O in a language without side effects. You could put all your interactions with the world in a special "World" object. Every time you called world.putString("foo"), you'd get back a new world object that represents the state of the world with "foo" having been written out.
So the code (quoting from samstoke's hello world):
main :: IO ()
main = do
putStrLn "Please enter your name"
name <- getLine
putStrLn ("Hello " ++ name ++ "!")
would get translated to:
main :: World -> World
main world = let newWorld = putStrLn world "Please enter your name" in
let (newerWorld, name) = getLine newWorld in
let newestWorld = putStrLn newerWorld ("Hello " ++ name ++ "!") in
newestWorld
Note that this makes the order of operations explicit, and that no World needs to be modified. Note also that now main has to take and return one of these World objects, so that a World needs to be threaded through all computations that will interact with the World (just like IO actions can only be executed from within other IO actions).
A monad lets you thread implicit state through a computation.
"Assuming the US Mint and my bank weren’t trying to scam me, that only left myself as the scam artist and I knew I wasn’t trying to cheat anyone, so that took care of that concern."
I guess if ignorance of the way he's hurting people counts as "not cheating them" this is true.
He gets the airline miles because the US mint takes in between a 1% and 3% loss on the transaction to pay the credit card company. They also lose money when they ship him the coins for free. The reason the US mint is willing to do this is because coins are so much cheaper for them in the long run than bills, once they go into circulation; they're paying this guy and UPS a fee for helping them put dollar coins into circulation. This guy is taking that fee, but not putting the coins into circulation. Its not like the money in his rewards account appeared out of nowhere.
The US Mint buys brass slugs an turns them into US dollars -- I bet there is a pretty high margin in that business so I don't think they are taking any loss. More like the US taxpayer is taking the loss.
The intrinsic value of the metal has literally nothing to do with it. If you take $0.01 of brass and turn it into $1 coin you didn't make any "profit."
This is not at all correct because passing by reference and value have defined and distinct meanings. Consider the difference between C++, which has actual pass by reference:
void swap(int& x, int& y) { int t = x; x = y; y = t; }, and Java: void swap(Integer x, Integer y) { Integer t = x, x = y; y = t; }. The C++ version will result in changes to the variables in the calling function and the Java version will not.
The real problem is that Java created needless confusion by calling its pointers references for purely marketing reasons.
No the real problem is that you fail to understand that Java gets to call these things what ever it likes because language has context. And your example fails to compare apples to apples. In Java Integer is an object, but int is not. You are confusing Java things with C++ things. As you can see, Java is not C++, and so your C++ terms and definitions do not apply here. Thank you for playing. Move along.
"No the real problem is that you fail to understand that Java gets to call these things what ever it likes because language has context."
This is silly; "pointer" and "reference" both had meanings before Java came along. If Java called pointers "names" instead of "references" it wouldn't mean that its function call semantics were pass-by-name either. And besides; if your argument is that we should use the Java terminology to describe all the aspects of Java under discussion, the fact that the all the Java designers make explicit that the function call semantics pass references as values, not objects as values.
"And your example fails to compare apples to apples. In Java Integer is an object, but int is not. You are confusing Java things with C++ things."
The argument applies if you use int in place of Integer just the same; or if you make a C++ Integer wrapper class analogous to the Java one. Any comparison here will of course be apples to oranges because C++ supports pass by reference and Java does not. The swap function is impossible to write in Java because it requires allowing called functions to change the values viewed in the caller, which is almost the definition of passing arguments by value.
"As you can see, Java is not C++, and so your C++ terms and definitions do not apply here. Thank you for playing. Move along."
Leaving aside the childish and insulting tone, the definition of "pass by reference" has nothing to do with C++; if the code were in perl it would still be pass by reference, because "pass by reference" has a meaning that exists outside of any particular programming language and describes a concept. Java function calls are not part of that concept; "there is exactly one parameter passing mode in Java - pass by value".
In which case there is no such thing as passing by reference. Ever. In C++ when you "pass by reference", what actually happens is that the address of the thing is taken, and a pointer is generated, and then that pointer is passed by value. Do you see? Any argument you put forth to the contrary will involve language specific features and conventions of C++. Your will have to claim that because the C++ compiler does this for you, that makes it special. In Java there are primitives and objects. Primitives are only passed by value. Objects are passed by reference. If you pass an object as a parameter, and then modify a property of the parameter, then it is the original object that is modified. This, in fact, is the same as when you pass an Object in C++ by reference. In contrast, in C++ you can also pass an object by value: the entire object is copied onto the stack.
class Foo; void modify( Foo& x) { x.setBar(1);} ; <- pass by reference in C++.
class Foo; void modify( Foo x) { x.setBar(1);} ; <- pass by reference in Java.
Java spares you the & because Java only passes by reference.
Again, to argue the contrary, simply because it passes an object pointer by value, automatically, is to argue that C++ never passes by reference because it too takes the address automatically.
The fact is that Java passes by reference exactly as C++ does. However, even if this were not the case, it would also be completely acceptable for Java to refer to what it does as pass by reference simply because it chooses too. These things are object references. If I pass a java object reference, is it acceptable to say I'm passing by reference? If Java people want to say it is, then it is. Will the world end, for example, because the word "heap" means two different things in computer science? http://en.wikipedia.org/wiki/Heap OMG! Who is right?
You are where the physicist is standing. You insist that Java biologists are using your terms wrong while oblivious to the mathematician. You have your abstractions. Java has theirs.
Of course, maybe you're the chemist, and I'm the physicist (I still write assembly) and the hardware guys are the mathematicians. Whatever.
As for the insulting tone, yes its a character flaw. When someone makes a statement like "I'm really tired of hearing folks (incorrectly) state [whatever]", its insulting. Its especially insulting when its wrong. In an ideal world I'd be able to respond without resorting to responding in kind, but I'm flawed. Sorry. You're still wrong.
The argument "well, passing by reference gets compiled to passing a pointer by value so really there is no passing by reference" is silly because passing by reference is a description of language semantics and function call evaluation. Your argument applies just as well to the statements "there is no such thing as lambda functions" or "there is no such thing as garbage collection" because those language features also get converted into representations that don't have either of them present.
The Java code you give isn't an example of passing by reference because, while you can change the value that x points to in Java, you can't change x to point to something different. No java function can change its arguments; the example you gave has the java function changing something that its argument points to.
Your argument that Java people can call language features the same name as distinct language features is: a. dumb, because it's just "words mean whatever anyone wants them to mean", and b. doesn't come anywhere close to applying here; the quotation at the end of my last response: "there is exactly one parameter passing mode in Java - pass by value" is a direct quote from 'The Java Programming Language'. The authors of Java disagree with you.
More from them:
"All parameters to methods are passed 'by value'. In other words, values of parameter variables in a method are copies of the values the invoker specified as arguments. If you pass a double to a method, its parameter is a copy of whatever value was being passed as an argument, and the method can change its parameter's value without affecting values in the code that invoked the method.
...
You should note that when the parameter is an object reference, it is the object reference - not the object itself - that is passed "by value." Thus, you can change which object a parameter refers to inside the method without affecting the reference that was passed. But if you change any fields of the object or invoke methods that change the object's state, the object is changed for every part of the program that holds a reference to it.
...
Some people will say incorrectly that objects are passed "by reference." In programming language design, the term pass by reference properly means that when an argument is passed to a function, the invoked function gets a reference to the original value, not a copy of its value. If the function modifies its parameter, the value in the calling code will be changed because the argument and parameter use the same slot in memory.
...
The Java programming language does not pass objects by reference; it passes object references by value. Because two copies of the same reference refer to the same actual object, changes made through one reference variable are visible through the other. There is exactly one parameter passing mode - pass-by-value - and that helps keep things simple."
Your last few paragraphs are beside the point; the question is not about which languages offer which levels of abstraction; the point is that different abstractions have different names and Java doesn't offer the abstraction named "pass by reference".
I suppose Hacker News is the only place where people might relate to this comment: Did anyone else look at the first picture and wonder why Mendel Rosenblum was on the set of Star Trek?
The history behind this actually goes the other way if I remember correctly; it was unclear for a time whether or not this sort of thing was allowed. The standard was modified so that Duff's device would be legal code after it was being used.
The device is legal dpANS C. I cannot quote chapter and verse, but
Larry Rosler, who was chairman of the language subcommittee (I think),
has assured me that X3J11 considered it carefully and decided that
it was legal. Somewhere I have a note from dmr certifying that all the
compilers that he believes in accept it. Of course, the device is also
legal C++, since Bjarne uses it in his book.
Agreed, the risk of libel/slander/defamation is typically too great to be worth any such threats even if they do make you feel better. It is like the old angry email technique: if you must vent, write what you want in a non-email format and get it out of your system, then get back to your life with a clear head.
Now go get a lawyer.
Put NOTHING of a threatening nature in any form of writing or voicemail. Hell, write nothing that doesn't document that you are in the right for that matter. Consider everything you do as possible evidence in a future court hearing and act accordingly.
I'm surprised no one has mentioned yet what I regard as the key reason decorators are useful: they maintain the property that you can always find the definition of a function named "foo" by textually searching for "def foo". Lots of alternate syntaxes break that.
Baby Rudin is a great choice, especially for self study, since there are a number of study guides for it that go through solutions, additional explanation of material, etc. I'd recommend against the chapters on differential forms, though, just because the treatment is outdated. Marsden and Hoffman's approach is to focus on explanations for why theorems are true before giving proofs, which some people find useful.
Axler is a good choice for linear algebra. Dummit and Foote is the standard choice for algebra generally. I'm of the opinion that we should teach algebra before linear algebra in general, but this seems like a minority view.
The problem sets are nearly legendary and the writing is terse. I might have to read through it again myself sometime.
"Algebra" by Artin is also a great choice if you want to learn about modern algebra. There's some good stuff in there for looking at linear transformations in, say, 2-space, as groups.
The much more self-serving reason to spend time learning about activities outside of your specialty: applying techniques of your discipline to another discipline is a great way to crank out some easy papers for the second discipline's journals. There's some good work waiting to be done applying dynamic code generation to graphics, artificial intelligence, or probably some other fields. This sort of work probably wouldn't cut it in a systems journal, but would probably excite some people in the respective target groups.
So the code (quoting from samstoke's hello world):
would get translated to: Note that this makes the order of operations explicit, and that no World needs to be modified. Note also that now main has to take and return one of these World objects, so that a World needs to be threaded through all computations that will interact with the World (just like IO actions can only be executed from within other IO actions).A monad lets you thread implicit state through a computation.