Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yeah, and that's not what first-class usually means. I simply can't say "my_method = Kernel.puts" the same way I can say "my_class = Kernel". Ruby authors seemed to want to make parentheses optional by any price, and that killed the opportunity to make methods first class.


You can literally write my_method = Kernel.method(:puts) and it’ll give you the method to do what you wish with.

As far as defining anonymous functions, literally all you have to do is:

my_func = -> (input) { output }

That makes a “lambda” which is literally just a function you can pass around anonymously.

You call it via either my_func.call(input) or simply my_func[input].

That capability is used all over the place.

Ruby absolutely has first class functions, the only thing you can say is it the syntax is slightly different if you want to use them anonymously (with no object context).


> my_method = Kernel.method(:puts)

That's exactly what being first-class is not. You tell Kernel to wrap you a method called puts into an object of class Method, rather than assigning a method to a variable. You don't have to look further than JS for a counterexample.


Ruby has two kinds of functions. Methods are functions attached to objects. Lambdas are functions that are not. Ruby lambdas are exactly like javascript arrow functions, or python functions.

There's a _reason_ for the difference, since it determines the implicit self, which is a meaningful part of how Ruby works. Because that difference is meaningful it is reflected in the syntax. `lambda`, or the shorthand `->` creates a function not attached to an object, and `def` creates a function and attaches it to the calling context (making it a method).

Perhaps you don't like this, that's fine. But to say "nope I want my methods and functions to be interchangeable and not to be called lambdas" is purely a subjective argument.

Objectively, Ruby has first-class functions that can be assigned to variables and passes around and returned from other function calls etc etc. They're just called lambdas.


This is clearly a misunderstanding of what a first-class function is. If it doesn't meet your criteria in the colloquial sense of "first-class", that's one thing. But in computer science and programming in general, "first-class function" has a very specific meaning [1], and Ruby absolutely meets the criteria.

The other bit of confusion is that the actual syntax in Ruby optimizes for the common case, which is calling methods. Yehuda Katz wrote a good article explaining this [2]. Among other things, it allows you to create very concise DSLs in Ruby that would never be quite as clean in Python.

1: https://en.wikipedia.org/wiki/First-class_function

2: https://yehudakatz.com/2010/02/21/ruby-is-not-a-callable-ori...


So the functionality is equivalent, but ruby's syntax is slightly longer. Is there something other than ruby's slightly longer syntax that you find lacking?

Ruby's Method class matches the design "everything is an object" (strings, numbers, modules & classes themselves...). Are regular expressions first class in ruby? There is top-level syntactic sugar for REs (/.../) but REs are just instances of `Regexp`. It's just syntax. I don't think you can argue Python REs are first class: I have to drag in `re` and then `re.compile()` a string (and my editor won't know to syntax highlight metachars or interpolation). I use REs more often than method references in either language...

But I'm not trying to "whataboutwhataboutwhatabout" here. I'm trying to say there's a difference of philosophy. Ruby Methods are just more objects (Method<Object). They aren't some sort of blessed type, just like everything else. Everything descends from Object. Kernel is just a module. Method is just a class. And so on. In that context, what does it mean to be "first class"? Objects are first class and methods are objects. QED. No?

(FWIW I agree on ruby's optional parens, too much inconsistency for a few less lit pixels on the screen).


> In that context, what does it mean to be "first class"

It's easy. First, what does it mean to be "first class"?

> a first-class citizen (also type, object, entity, or value) in a given programming language is an entity which supports all the operations generally available to other entities. These operations typically include being passed as an argument, returned from a function, modified, and assigned to a variable

Secondly, how does that apply to functions?

> [First class functions] means the language supports passing functions as arguments to other functions, returning them as the values from other functions, and assigning them to variables or storing them in data structures

In what way doesn't Ruby have first class functions? This article explains it better: https://codequizzes.wordpress.com/2014/05/19/ruby-methods-ar...

In practice, because of Proc, you can use Proc wherever you'd use functions and get the same effect in practice, so this is not a big issue. But just because Ruby has Procs, doesn't mean it has first class functions, which is a specific concept.


Thanks, I had also looked for a definition. Instances of Method fulfill both of the cited criteria -- example in this thread, above. Also: Method != Proc, but the article's comments help.

I, aha, notice this:

    $ irb
    2.3.3 :001 > Kernel.method(:puts).object_id
     => 47165335040720 
    2.3.3 :002 > Kernel.method(:puts).object_id
     => 47165334993360 # not the same!
    2.3.3 :003 > 
That is: #method doesn't return the Kernel.puts method, it returns a new Kernel.puts Method instance on each invocation. So the returned object from Kernel#method isn't the "real" (first-class) method object.

I feel like I'm a lot closer but I'd still like a better definition :)


Isn't the main issue that Ruby simply doesn't have functions? Ruby is pure OOP, and there is no way to define a method without the implicit 'self' argument. Maybe the reasoning was that methods themselves aren't really meant to be passed around. Because in today's idiomatic Ruby, they mostly aren't -- the late binding behavior of 'send' feels much more Rubyish.


Exactly. And Ruby methods are not even "functions with self" they are message-handlers. Like in Smalltalk or Objective-C.

Different heritage


Sorry, Ruby methods are not objects. They can surely be wrapped in objects of class Method, but this feature is used quite rarely. Whether this is due to the syntax, the confusion regarding the evaluation scope, or something else, I have no idea.


The only way of obtaining a method in Ruby returns it as an object. Whether or not they "are" an object is thus entirely an implementation detail.

I think part of the confuction here is that "ob.puts" for example, does not directly access a method. It denotes passing a message to "ob". That message may or may not be routed to a "puts" method.

But at no point does Ruby allow you to get hold of any kind of reference to a method that is anything but an object.


Yeah, you got it, see my reply to capableweb. Thanks!


> and my editor won't know to syntax highlight metachars or interpolation

IntelliJ editors do this and it’s insanely useful. Works with SQL, regex and any other language.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: