@hanlyu: it's not widely known, but instead of `something.call()` you can also write just `something.()` which feels a lot less verbose. On 02/22/2016 05:50 PM, Hanlyu Sarang wrote: > This is one of the few cases where JavaScript is superior to ruby. You > can have just about anything and append parentheses to it and presto, > an invocation will be attempted "just_about_anything(...)". > JavaScript's approach is both powerful and clean. Ruby's approach is > also powerful, but it is complicated. I usually choose between > "->myarg{...}" or "myobj.method :mymethod". I also have to use > ".call(...), a complaint which is really nitpicking. [If I love > JavaScript so much, why don't I just use JavaScript instead of Ruby?] > > But I'm also comparing Apples and Oranges, which isn't fair. > JavaScript doesn't have Blocks, nor does it have a compact poetry > mode. I don't think there is much that is practical which can be done > to clean up Ruby function calling syntax. I appreciate stabby, which > is really very nice. > > > On Mon, Feb 22, 2016 at 9:27 AM, > wrote: > > Issue #11262 has been updated by Jörg W Mittag. > > Project changed from CommonRuby to Ruby trunk > Description updated > > ---------------------------------------- > Feature #11262: Make more objects behave like "Functions" > https://bugs.ruby-lang.org/issues/11262#change-57075 > > * Author: Jörg W Mittag > * Status: Open > * Priority: Normal > * Assignee: > ---------------------------------------- > # What is a Function? > > In Ruby, we have the [`Proc`](http://ruby-doc.org/core/Proc.html) > class to represent objects which are "function-like". But, in true > object-oriented / duck-typing fashion, an object doesn't actually > have to be an instance of `Proc` in order to be treated as a > function, it only needs to respond to > [`call`](http://ruby-doc.org/core/Proc.html#method-i-call). For > cases, where a `Proc` instance is absolutely required (mostly, the > `&` unary prefix ampersand "make-me-a-block" operator), there is > the > [`to_proc`](http://ruby-doc.org/core/Proc.html#method-i-to_proc) > conversion. > > So, in short: if an object wants to be a function, it **MUST** > respond to `call`, and **SHOULD** also respond to `to_proc`. > > There are some objects in Ruby that *could* be seen as functions, > but currently don't respond to `call` or `to_proc`: > > # [`Array`](http://ruby-doc.org/core/Array.html) as mapping > > An array is a mapping from indices to elements. "Mapping" is just > a different word for (partial) function, though! I propose, that > `Array` should implement `call` and `to_proc` in the following manner: > > ~~~ruby > class Array > alias_method :call, :[] > > def to_proc > method(:call).to_proc > end > end > ~~~ > > # [`Hash`](http://ruby-doc.org/core/Hash.html) as mapping > > A hash is a mapping from keys to values. I propose, that `Hash` > should implement `call` and `to_proc` in the following manner: > > ~~~ruby > class Hash > alias_method :call, :[] > > def to_proc > method(:call).to_proc > end > end > ~~~ > > # `Set` as predicate > > A set is a mapping from values to booleans, i.e. a set is the same > as its `include?` predicate. This would mean, for example, that I > can pass a `Set` as a predicate to methods like > [`Enumerable#select`](http://ruby-doc.org/core/Enumerable.html#method-i-select). > I propose, that `Set` should implement `call` and `to_proc` in the > following manner: > > ~~~ruby > require 'set' > > class Set > alias_method :call, :include? > > def to_proc > method(:call).to_proc > end > end > ~~~ > > I believe that these three additions are worthwhile and fairly > uncontroversial. They match with the way arrays, maps and > especially sets are treated in mathematics and in other > programming languages. E.g. in both > [Clojure](http://clojure.org/data_structures#Data%20Structures-Maps%20(IPersistentMap) > ) > and > [Scala](http://scala-lang.org/api/current/#scala.collection.Seq), > arrays, sets and maps are functions and use function application > syntax for accessing values. Scala doesn't even have indexing syntax. > > Here are some potential use cases: > > ~~~ruby > numbers_to_words = %w[zero one two three four five six seven eight > nine ten eleven twelve] > > [4, 7, 1, 0, 8].map(&numbers_to_words) > # => ['four', 'seven', 'one', 'zero', 'eight'] > > > allowed_languages = Set[:ruby, :python, :scala, :scheme] > > %i[ruby c cplusplus scala java perl].select(&allowed_languages) > # => [:ruby, :scala] > ~~~ > > Here is a more "wild" proposal that is much more controversial. I > don't actually propose adding this to Ruby, but I will mention it > here as food for thought: > > # [`Class`](http://ruby-doc.org/core/Class.html) as factory > > If you squint your eyes, tilt your head sideways and look at it > juuuuuuust right, a class is a factory for objects. In other > words, it is a function from constructor arguments to instances: > > ~~~ruby > class Class > alias_method :call, :new > > def to_proc > method(:call).to_proc > end > end > ~~~ > > Example: > > ~~~ruby > class Person > def initialize(name) > @name = name > end > end > > %w[matz ko1 charlie].map(&Person) > # => [#, > #, # @name="charlie">] > ~~~ > > # Incompatibilities > > This proposal conflicts with #10829, which proposes to use > `Array#to_proc` for a completely different purpose. > > I believe that having `Array`s behave as functions from indices to > elements is natural, unsurprising, and well in line with both > mathematics and other languages. > > --- > > # Related > > The code duplication encountered here suggests refactoring to > extract two new mixins in the Ruby core library: > > ~~~ruby > module Callable > def to_proc > method(:call).to_proc > end > end > > module Indexable > alias_method :call, :[] > end > ~~~ > > However, this is out of scope of this discussion and *not* part of > this particular feature proposal. > > --- > > [NOTE: I originally posted this in project:common-ruby, which > according to [[common-ruby:|its wiki]] is "The official place to > submit feature proposal for Ruby" but from my observation, almost > all Ruby feature requests actually get filed at project:ruby-trunk.] > > > > -- > https://bugs.ruby-lang.org/ > > Unsubscribe: ?subject=unsubscribe> > > > > > > Unsubscribe: >