From: Recursive Madman <recursive.madman@gmx.de>
To: Ruby developers <ruby-core@ruby-lang.org>
Subject: [ruby-core:73928] Re: [Ruby trunk Feature#11262] Make more objects behave like "Functions"
Date: Mon, 22 Feb 2016 17:53:40 +0100 [thread overview]
Message-ID: <56CB3D14.5010006@gmx.de> (raw)
In-Reply-To: <CAE3kKutTLEMxJDwUa10rfLM7fqdJPumhbg_6vsYPx+hyx_9EVQ@mail.gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 7453 bytes --]
@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, <Ruby-Lang@joergwmittag.de
> <mailto:Ruby-Lang@joergwmittag.de>> 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)
> <http://clojure.org/data_structures#Data%20Structures-Maps%20%28IPersistentMap%29>)
> 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)
> # => [#<Person:0xdeadbeef481523 @name="matz">,
> #<Person:0xdeadbeef815234 @name="ko1">, #<Person:0xdeadbeef152342
> @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: <mailto:ruby-core-request@ruby-lang.org
> <mailto:ruby-core-request@ruby-lang.org>?subject=unsubscribe>
> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>
>
>
>
>
> Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
> <http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>
[-- Attachment #1.2: Type: text/html, Size: 12962 bytes --]
[-- Attachment #2: Type: text/plain, Size: 138 bytes --]
Unsubscribe: <mailto:ruby-core-request@ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>
next prev parent reply other threads:[~2016-02-22 16:18 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <redmine.issue-11262.20150615115504@ruby-lang.org>
2015-06-15 11:55 ` [ruby-core:69590] [CommonRuby - Feature #11262] [Open] Make more objects behave like "Functions" JoergWMittag+Ruby-Lang
2015-07-09 5:10 ` [ruby-core:69906] [CommonRuby - Feature #11262] " 2851820660
2016-02-22 15:27 ` [ruby-core:73919] [Ruby trunk Feature#11262] " Ruby-Lang
2016-02-22 16:50 ` [ruby-core:73927] " Hanlyu Sarang
2016-02-22 16:53 ` Recursive Madman [this message]
2016-02-22 15:46 ` [ruby-core:73922] " zverok.offline
2016-02-23 0:55 ` [ruby-core:73939] " Ruby-Lang
2016-02-23 0:58 ` [ruby-core:73940] " Ruby-Lang
2016-06-24 8:40 ` [ruby-core:76136] " Ruby-Lang
2016-06-24 8:43 ` [ruby-core:76137] " Ruby-Lang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-list from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.ruby-lang.org/en/community/mailing-lists/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=56CB3D14.5010006@gmx.de \
--to=ruby-core@ruby-lang.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).