I'm new to functional languages and I was wondering why we can't pass a parameter by reference. I found anserws saying that
you are not supposed to change the state of objects once they have been created
but I didn't quite get the idea.
I'm new to functional languages and I was wondering why we can't pass a parameter by reference. I found anserws saying that
you are not supposed to change the state of objects once they have been created
but I didn't quite get the idea.
It's not so much that you can't pass references, it's that with referential transparency there isn't a programmer-visible difference between references and values, because you aren't allowed to change what references point to. This makes it actually safer and more prevalent in pure functional programming to pass shared references around everywhere. From a semantic point of view, they may as well be values.
I think you have misunderstood the concept. Both Scheme and C/C++ are pass by value languages and most values are addresses (references).
Purely functional languages can have references and those are passed by value. What they don't have is redefining variables in the same scope (mutate bindings) and they don't have the possibility to update the object the reference points to. All operations return a fresh new object.
As an example I can give you Java's strings. Java is not purely functional but its strings are. If you change the string to uppercase you get a new string object in return and the original one has not been altered.
Most languages I know of are pass by value. Pass by name is alien to me.
Because if you pass params by reference you could change something in the parameter, which could introduce a side effect. Consider this:
function pay(person, cost) {
person.wallet -= cost;
}
function money(person) {
return person.wallet;
}
let joe = { name: "Joe", wallet: 300 };
console.log(money(joe)); // 300
pay(joe, 20);
console.log(money(joe)); // 280
The two money(joe)
are taking the same input (the object joe
) and giving different output (300, 280). This is in contradiction to the definition of a pure functional language (all functions must return the same output when given the same input).
If the program was made this way, there is no problem:
function pay(person, cost) {
return Object.freeze({ ...person, wallet: person.wallet - cost });
}
function money(person) {
return person.wallet;
}
let joe = Object.freeze({ name: "Joe", wallet: 300 });
console.log(money(joe)); // 300
let joe_with_less_money = pay(joe, 20);
console.log(money(joe)); // still 300
console.log(money(joe_with_less_money)); // 280
Here we have to fake pass-by-value by freezing objects (which makes them immutable) since JavaScript can pass parameters only one way (pass by sharing), but the idea is the same.
(This presupposes the implications of the term "pass-by-reference" that apply to languages like C++, where the implementation detail affects mutability, not the actual implementation detail of modern languages, where references are typically passed under the hood but immutability is assured by other means.)