ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:69208] [Ruby trunk - Bug #11156] [Open] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
       [not found] <redmine.issue-11156.20150515224930@ruby-lang.org>
@ 2015-05-15 22:49 ` faraz.yashar
  2015-05-16  0:19 ` [ruby-core:69210] [Ruby trunk - Bug #11156] [Rejected] " nobu
  2015-05-16  8:06 ` [ruby-core:69213] [Ruby trunk - Bug #11156] " faraz.yashar
  2 siblings, 0 replies; 4+ messages in thread
From: faraz.yashar @ 2015-05-15 22:49 UTC (permalink / raw
  To: ruby-core

Issue #11156 has been reported by Faraz Yashar.

----------------------------------------
Bug #11156: Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
https://bugs.ruby-lang.org/issues/11156

* Author: Faraz Yashar
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
Given a function that takes an argument and a block, the behavior wildly varies when parenthesis are omitted from the functions argument.

Consider the following function:

~~~
require 'time'

def example(arg)
  puts arg
  if block_given?
    puts yield
  else
    puts "no block"
  end
end
~~~

Each of the following example sets presents one `example` call with parentheses explicitly defined and one whether the parenthesis are omitted.

For most literals (e.g. 1, 'string', true, false, nil, %w[array]), missing parenthesis causes a syntax error.

~~~
example(1) { "block" }
# 1
# block
example 1 { "block" }
# SyntaxError: syntax error, unexpected '{', expecting end-of-input
~~~

Array literals, however, succeed:

~~~
example([1]) { "block" }
# 1
# block
example [1] { "block" }
# 1
# block
~~~

Identifiers are called as methods if parentheses are omitted:

~~~
example(Time) { "block "}
# Time
# block 
example Time { "block" }
# NoMethodError: undefined method `Time' for main:Object

a = 1
example(a) { "block" }
# 1
# block
example a { "block" }
# NoMethodError: undefined method `a' for main:Object
~~~

Object with method calls simply skip the block when no parenthesis are present:

~~~
example(Time.now) { "block" }
# 2015-05-15 18:16:50 -0400
# block
example Time.now { "block" }
# 2015-05-15 18:16:50 -0400
# no block
~~~

Method calls with arguments behave about the same as the above...

~~~
example(Integer(1)) { "block" }
# 1
# block
example Integer(1) { "block" }
# 1
# no block
~~~

...except `Time.parse` gets weird:

~~~
example(Time.parse('2015-01-01 0:00:00+00:00')) { "block" }
# 2015-01-01 00:00:00 +0000
# block
# => nil 
example Time.parse('2015-01-01 0:00:00+00:00') { "block" }
# 0000-01-01 00:00:00 +0000  <---- Year 2000?! 
# no block
# => nil
~~~

The lack of consistency across these use cases is extremely confusing and misleading. I'm of the opinion that parentheses omission should, in all cases, lead to a syntax error.




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:69210] [Ruby trunk - Bug #11156] [Rejected] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
       [not found] <redmine.issue-11156.20150515224930@ruby-lang.org>
  2015-05-15 22:49 ` [ruby-core:69208] [Ruby trunk - Bug #11156] [Open] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis faraz.yashar
@ 2015-05-16  0:19 ` nobu
  2015-05-16  8:06 ` [ruby-core:69213] [Ruby trunk - Bug #11156] " faraz.yashar
  2 siblings, 0 replies; 4+ messages in thread
From: nobu @ 2015-05-16  0:19 UTC (permalink / raw
  To: ruby-core

Issue #11156 has been updated by Nobuyoshi Nakada.

Description updated
Status changed from Open to Rejected

What's your point?

`Time.parse` states as:

    # If a block is given, the year described in +date+ is converted by the
    # block.  For example:
    #
    #     Time.parse(...) {|y| 0 <= y && y < 100 ? (y >= 69 ? y + 1900 : y + 2000) : y}


----------------------------------------
Bug #11156: Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
https://bugs.ruby-lang.org/issues/11156#change-52464

* Author: Faraz Yashar
* Status: Rejected
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
Given a function that takes an argument and a block, the behavior wildly varies when parenthesis are omitted from the functions argument.

Consider the following function:

~~~ruby
require 'time'

def example(arg)
  puts arg
  if block_given?
    puts yield
  else
    puts "no block"
  end
end
~~~

Each of the following example sets presents one `example` call with parentheses explicitly defined and one whether the parenthesis are omitted.

For most literals (e.g. 1, 'string', true, false, nil, %w[array]), missing parenthesis causes a syntax error.

~~~ruby
example(1) { "block" }
# 1
# block
example 1 { "block" }
# SyntaxError: syntax error, unexpected '{', expecting end-of-input
~~~

Array literals, however, succeed:

~~~ruby
example([1]) { "block" }
# 1
# block
example [1] { "block" }
# 1
# block
~~~

Identifiers are called as methods if parentheses are omitted:

~~~ruby
example(Time) { "block "}
# Time
# block 
example Time { "block" }
# NoMethodError: undefined method `Time' for main:Object

a = 1
example(a) { "block" }
# 1
# block
example a { "block" }
# NoMethodError: undefined method `a' for main:Object
~~~

Object with method calls simply skip the block when no parenthesis are present:

~~~ruby
example(Time.now) { "block" }
# 2015-05-15 18:16:50 -0400
# block
example Time.now { "block" }
# 2015-05-15 18:16:50 -0400
# no block
~~~

Method calls with arguments behave about the same as the above...

~~~ruby
example(Integer(1)) { "block" }
# 1
# block
example Integer(1) { "block" }
# 1
# no block
~~~

...except `Time.parse` gets weird:

~~~ruby
example(Time.parse('2015-01-01 0:00:00+00:00')) { "block" }
# 2015-01-01 00:00:00 +0000
# block
# => nil 
example Time.parse('2015-01-01 0:00:00+00:00') { "block" }
# 0000-01-01 00:00:00 +0000  <---- Year 2000?! 
# no block
# => nil
~~~

The lack of consistency across these use cases is extremely confusing and misleading. I'm of the opinion that parentheses omission should, in all cases, lead to a syntax error.




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:69213] [Ruby trunk - Bug #11156] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
       [not found] <redmine.issue-11156.20150515224930@ruby-lang.org>
  2015-05-15 22:49 ` [ruby-core:69208] [Ruby trunk - Bug #11156] [Open] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis faraz.yashar
  2015-05-16  0:19 ` [ruby-core:69210] [Ruby trunk - Bug #11156] [Rejected] " nobu
@ 2015-05-16  8:06 ` faraz.yashar
  2015-05-17 19:42   ` [ruby-core:69218] " Austin Ziegler
  2 siblings, 1 reply; 4+ messages in thread
From: faraz.yashar @ 2015-05-16  8:06 UTC (permalink / raw
  To: ruby-core

Issue #11156 has been updated by Faraz Yashar.


I'm trying to demonstrate that the syntax is very confusing and error-prone, especially given that `do ... end` blocks do not behave similarly due to precedence differences.

Consider the `travel_to` time travel method given by Rails' `ActiveSupport::Testing::TimeHelpers`. One would naturally expect that the following two statements would behave equivalently...

~~~ruby
travel_to Time.parse('2015-01-01 00:00:00 +0000') do
 Time.now # => 2015-01-01 00:00:00 +0000
end

travel_to Time.parse('2014-01-01 00:00:00 +0000') {
 Time.now # => 2015-05-16 03:52:24 -0400
}
~~~

...but they don't because of precedence behaviors. To me, these differences violate the principle of least astonishment, and they cause more confusion and open room for errors.

----------------------------------------
Bug #11156: Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
https://bugs.ruby-lang.org/issues/11156#change-52465

* Author: Faraz Yashar
* Status: Rejected
* Priority: Normal
* Assignee: 
* ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
Given a function that takes an argument and a block, the behavior wildly varies when parenthesis are omitted from the functions argument.

Consider the following function:

~~~ruby
require 'time'

def example(arg)
  puts arg
  if block_given?
    puts yield
  else
    puts "no block"
  end
end
~~~

Each of the following example sets presents one `example` call with parentheses explicitly defined and one whether the parenthesis are omitted.

For most literals (e.g. 1, 'string', true, false, nil, %w[array]), missing parenthesis causes a syntax error.

~~~ruby
example(1) { "block" }
# 1
# block
example 1 { "block" }
# SyntaxError: syntax error, unexpected '{', expecting end-of-input
~~~

Array literals, however, succeed:

~~~ruby
example([1]) { "block" }
# 1
# block
example [1] { "block" }
# 1
# block
~~~

Identifiers are called as methods if parentheses are omitted:

~~~ruby
example(Time) { "block "}
# Time
# block 
example Time { "block" }
# NoMethodError: undefined method `Time' for main:Object

a = 1
example(a) { "block" }
# 1
# block
example a { "block" }
# NoMethodError: undefined method `a' for main:Object
~~~

Object with method calls simply skip the block when no parenthesis are present:

~~~ruby
example(Time.now) { "block" }
# 2015-05-15 18:16:50 -0400
# block
example Time.now { "block" }
# 2015-05-15 18:16:50 -0400
# no block
~~~

Method calls with arguments behave about the same as the above...

~~~ruby
example(Integer(1)) { "block" }
# 1
# block
example Integer(1) { "block" }
# 1
# no block
~~~

...except `Time.parse` gets weird:

~~~ruby
example(Time.parse('2015-01-01 0:00:00+00:00')) { "block" }
# 2015-01-01 00:00:00 +0000
# block
# => nil 
example Time.parse('2015-01-01 0:00:00+00:00') { "block" }
# 0000-01-01 00:00:00 +0000  <---- Year 2000?! 
# no block
# => nil
~~~

The lack of consistency across these use cases is extremely confusing and misleading. I'm of the opinion that parentheses omission should, in all cases, lead to a syntax error.




-- 
https://bugs.ruby-lang.org/

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [ruby-core:69218] Re: [Ruby trunk - Bug #11156] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis
  2015-05-16  8:06 ` [ruby-core:69213] [Ruby trunk - Bug #11156] " faraz.yashar
@ 2015-05-17 19:42   ` Austin Ziegler
  0 siblings, 0 replies; 4+ messages in thread
From: Austin Ziegler @ 2015-05-17 19:42 UTC (permalink / raw
  To: Ruby developers

[-- Attachment #1: Type: text/plain, Size: 4319 bytes --]

These are well-established rules of precedence for blocks in Ruby for a
long time. As a Rubyist for the last thirteen years, changing this would
surprise me more. You may as well ask about precedence of mathematical
operators in general (because people *do* find that surprising across all
languages). If you want to use braces against a function, use parentheses
just as if you want to do addition before multiplication.

Note that using POLS/POLA in an argument is specious. The measure of
surprise is whether Matz is surprised by the behaviour. *Everyone* finds
Ruby surprising early on for various reasons.

-a

On Sat, May 16, 2015 at 4:06 AM, <faraz.yashar@gmail.com> wrote:

> Issue #11156 has been updated by Faraz Yashar.
>
>
> I'm trying to demonstrate that the syntax is very confusing and
> error-prone, especially given that `do ... end` blocks do not behave
> similarly due to precedence differences.
>
> Consider the `travel_to` time travel method given by Rails'
> `ActiveSupport::Testing::TimeHelpers`. One would naturally expect that the
> following two statements would behave equivalently...
>
> ~~~ruby
> travel_to Time.parse('2015-01-01 00:00:00 +0000') do
>  Time.now # => 2015-01-01 00:00:00 +0000
> end
>
> travel_to Time.parse('2014-01-01 00:00:00 +0000') {
>  Time.now # => 2015-05-16 03:52:24 -0400
> }
> ~~~
>
> ...but they don't because of precedence behaviors. To me, these
> differences violate the principle of least astonishment, and they cause
> more confusion and open room for errors.
>
> ----------------------------------------
> Bug #11156: Indeterminate Behavior for Curly-braced Blocks with Function
> Argument Missing Parenthesis
> https://bugs.ruby-lang.org/issues/11156#change-52465
>
> * Author: Faraz Yashar
> * Status: Rejected
> * Priority: Normal
> * Assignee:
> * ruby -v: ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-linux]
> * Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
> ----------------------------------------
> Given a function that takes an argument and a block, the behavior wildly
> varies when parenthesis are omitted from the functions argument.
>
> Consider the following function:
>
> ~~~ruby
> require 'time'
>
> def example(arg)
>   puts arg
>   if block_given?
>     puts yield
>   else
>     puts "no block"
>   end
> end
> ~~~
>
> Each of the following example sets presents one `example` call with
> parentheses explicitly defined and one whether the parenthesis are omitted.
>
> For most literals (e.g. 1, 'string', true, false, nil, %w[array]), missing
> parenthesis causes a syntax error.
>
> ~~~ruby
> example(1) { "block" }
> # 1
> # block
> example 1 { "block" }
> # SyntaxError: syntax error, unexpected '{', expecting end-of-input
> ~~~
>
> Array literals, however, succeed:
>
> ~~~ruby
> example([1]) { "block" }
> # 1
> # block
> example [1] { "block" }
> # 1
> # block
> ~~~
>
> Identifiers are called as methods if parentheses are omitted:
>
> ~~~ruby
> example(Time) { "block "}
> # Time
> # block
> example Time { "block" }
> # NoMethodError: undefined method `Time' for main:Object
>
> a = 1
> example(a) { "block" }
> # 1
> # block
> example a { "block" }
> # NoMethodError: undefined method `a' for main:Object
> ~~~
>
> Object with method calls simply skip the block when no parenthesis are
> present:
>
> ~~~ruby
> example(Time.now) { "block" }
> # 2015-05-15 18:16:50 -0400
> # block
> example Time.now { "block" }
> # 2015-05-15 18:16:50 -0400
> # no block
> ~~~
>
> Method calls with arguments behave about the same as the above...
>
> ~~~ruby
> example(Integer(1)) { "block" }
> # 1
> # block
> example Integer(1) { "block" }
> # 1
> # no block
> ~~~
>
> ...except `Time.parse` gets weird:
>
> ~~~ruby
> example(Time.parse('2015-01-01 0:00:00+00:00')) { "block" }
> # 2015-01-01 00:00:00 +0000
> # block
> # => nil
> example Time.parse('2015-01-01 0:00:00+00:00') { "block" }
> # 0000-01-01 00:00:00 +0000  <---- Year 2000?!
> # no block
> # => nil
> ~~~
>
> The lack of consistency across these use cases is extremely confusing and
> misleading. I'm of the opinion that parentheses omission should, in all
> cases, lead to a syntax error.
>
>
>
>
> --
> https://bugs.ruby-lang.org/
>



-- 
Austin Ziegler * halostatue@gmail.com * austin@halostatue.ca
http://www.halostatue.ca/ * http://twitter.com/halostatue

[-- Attachment #2: Type: text/html, Size: 5882 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2015-05-17 19:27 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <redmine.issue-11156.20150515224930@ruby-lang.org>
2015-05-15 22:49 ` [ruby-core:69208] [Ruby trunk - Bug #11156] [Open] Indeterminate Behavior for Curly-braced Blocks with Function Argument Missing Parenthesis faraz.yashar
2015-05-16  0:19 ` [ruby-core:69210] [Ruby trunk - Bug #11156] [Rejected] " nobu
2015-05-16  8:06 ` [ruby-core:69213] [Ruby trunk - Bug #11156] " faraz.yashar
2015-05-17 19:42   ` [ruby-core:69218] " Austin Ziegler

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).