Proc # call
For example, consider the functions ʻadd and
sum`, which output the sum of two arguments. With Python or JavaScript, you can write code like this:
python
def add(x, y):
print(x + y)
sum = add #Can be substituted as it is
add(1, 2)
sum(1, 2) #There is no difference in how to call add and sum
JavaScript
function add(x, y){
console.log(x + y);
}
sum = add //Can be substituted as it is
add(1, 2)
sum(1, 2) //There is no difference in how to call add and sum
However, in Ruby, you can't assign a method to another variable as it is, you have to create a Proc
object with proc
or lambda
and then pass it, and the recipient also passes the call
. You need to call it using. This is also the case around Java where you have to call the ʻapply` method.
Ruby
def add(x, y)
puts (x + y)
end
sum = proc{|x, y| add(x, y)} #Need to wrap in proc or lambda
add 1, 2
sum.call 1, 2 #Need to call with call, the usage of add and sum is different
I see, this is not good. However, there is a counterargument on the Ruby side, and Ruby has the advantage that parentheses can be omitted in method calls when there are no arguments.
JavaScript
function answer(){
console.log(42)
}
answer() //There are parentheses
Ruby
def answer
puts 42
end
answer #No parentheses needed
I also find it a bit clunky and awkward to handle. But, as the text says, this is a trade-off with the unique style that adds value to Ruby.
Attempting to introduce such parentheses omissions into JavaScript or Python is not possible because it conflicts with the syntax that represents the function object itself. That's why, as far as I can see, it doesn't seem like I can say which one is better ...
Haskell / PureScript solves this dilemma.
PureScript
add x y = logShow (x + y) --add has arguments
sum = add --Functions are first-class, so you can assign them normally
answer = logShow 42 --answer has no arguments
fortyTwo = answer --Since the value of answer is also first-class, you can assign it to another variable as it is.
main = do
add 1 2 --3 is output. Of course you can call it normally if there are arguments
sum 1 2 --3 is output. There is no difference in how to call add and sum
answer --42 is output. Of course there are no parentheses even if there are no arguments
fortyTwo --42 is output. Because fortyTwo and answer refer to the same thing.
Ruby has the advantage of being able to omit parentheses in function calls with no arguments, and Python / JavaScript has the advantage of not distinguishing between normal function calls and function object calls. Mysterious! It may be interesting to think for yourself why Haskell / PureScript can do this, what each part of the code above means, and in what order the execution proceeds [^ sample].
[^ sample]: However, if you don't know Haskell / PureScript, you definitely don't know. Since this is PureScript code, Haskell's unique transformation specification "lazy evaluation" that messes up the execution order is irrelevant.
Also, if you look closely at the PureScript code above, there are no periods, no colons, or even a single comma. The only reserved word is do
, which signals the beginning of a code block. You can see that the code looks strangely refreshing, such as the blocks being represented by indentation like Python. This is also a feature of Haskell / PureScript code. I think it's very easy to read because the syntactic noise is narrowed down to the limit, but it is sometimes said that it is difficult to read for some reason.
This is a grammar issue, so maybe a language with a grammar that balances these will be developed in the future.
It has been around for over 15 years. It's not well known because there are too few people using it ...
Many people who use Ruby may dislike such syntactic overhead, such as trying to omit parentheses when there are no arguments. Haskell / PureScript has a simple syntax anyway, so I think it's suitable for people who like Ruby. I don't really care about these details, but I usually have important points like "Abstracting synchronous and asynchronous actions with monads is convenient because it creates consistency." To explain the advantages of this, "I don't know what it means. This time, I explained as briefly as possible the easy-to-understand point that "convenience and simplicity are compatible with the presence or absence of function arguments and whether they are first-class".