DEV Community

Discussion on: Why I love Ruby: almost everything is a call

Collapse
 
naqvis profile image
Ali Naqvi

Talking about intuitiveness, don't know why Proc is treated differently in Crystal. Other languages treats function pointers as normal functions and one don't need special syntax or invoke special methods for that.

Collapse
 
asterite profile image
Ary Borenszweig

This is the same in Ruby too. The main reason is that you can invoke methods without parentheses. Let's say you have this:

def foo
  ->{ 1 }
end
Enter fullscreen mode Exit fullscreen mode

And suppose we could invoke a Proc just by using parentheses, like a regular method invocation. So it would be like this:

f = foo # this returns the Proc
f() # this would in theory invoke it
Enter fullscreen mode Exit fullscreen mode

But then there are some ambiguities with the above... The main one is this:

f = foo() # does this return the Proc and executes it, or it just returns the proc?
Enter fullscreen mode Exit fullscreen mode

Another ambiguity is what happens if there's an f method in the same scope:

def f
  2
end

f = foo
f() # Does this call the `f` Proc, or the `f` method?
Enter fullscreen mode Exit fullscreen mode

If we decide it calls the method, then if f didn't exist and it now exists (someone added it after we wrote those two lines), the meaning would change. If we decide it calls the f Proc, then all foo_bar() calls must be treated like assuming they are procs, if there's a foo_bar local variable in the current scope. But maybe once the language was popular they thought about doing that but it would be a huge breaking change. It's very common to have local variables and methods be named the same in Ruby.

In Crystal we made it the same as in Ruby. I actually think having a call method simplifies things: you can be sure what you have is a Proc. Also procs in Crystal aren't used that much...