Feature #1256

Add constant TAILRECURSION to let a program recognize if tail recursion optimization is implemented

Added by Wolfgang Nádasi-Donner almost 3 years ago. Updated 9 months ago.

[ruby-core:22748]
Status:Rejected Start date:03/09/2009
Priority:Normal Due date:
Assignee:- % Done:

0%

Category:core
Target version:2.0.0

Description

Ruby 1.9 has the possibility to support tail recursion optimization for methods and proc objects. Due to technical problems it cannot be easy implemented for every VM or platform, which will support Ruby 1.9 functionality.

Tail recursion optimization is an implementation detail and not a language feature in general. I propose to supply a constant TAILRECURSION, which will be set to "true" if this feature is implemented, otherwise "false".

History

Updated by Shyouhei Urabe almost 3 years ago

I'm curious, how you can be happy if you detect your VM supports tail-call optimization or not (from your script)?

I think you have to write without tail-calls anyway for compatibilities with those no-tail-call enironment.

Updated by Wolfgang Nádasi-Donner almost 3 years ago

Shyouhei Urabe schrieb:
> I'm curious, how you can be happy if you detect your VM supports tail-call optimization or not (from your script)?
> 
> I think you have to write without tail-calls anyway for compatibilities with those no-tail-call enironment.
I don't always write portable programs, but I want a controlled end of 
such a programm, e.g. with a message "Programm cannot run under this 
environment".

It's the same as I do in the moment. When started using Ruby 1.8 they 
tell the user, that it will not work using Ruby 1.8.

This s better than a system error message.

Otherwise it is also possible to present a different implementation, 
which may be much slower, but works and inform the user via a warning 
about this fact.

Wolfgang Nádasi-Donner

Updated by Nobuyoshi Nakada almost 3 years ago

Hi,

At Mon, 9 Mar 2009 02:41:55 +0900,
Wolfgang Nádasi-Donner wrote in [ruby-core:22748]:
> Tail recursion optimization is an implementation detail and
> not a language feature in general. I propose to supply a
> constant TAILRECURSION, which will be set to "true" if this
> feature is implemented, otherwise "false".

RubyVM::InstructionSequence.compile_option[:tailcall_optimization]

-- 
Nobu Nakada

Updated by Wolfgang Nádasi-Donner almost 3 years ago

Nobuyoshi Nakada schrieb:
> Hi,
> 
> At Mon, 9 Mar 2009 02:41:55 +0900,
> Wolfgang Nádasi-Donner wrote in [ruby-core:22748]:
>> Tail recursion optimization is an implementation detail and
>> not a language feature in general. I propose to supply a
>> constant TAILRECURSION, which will be set to "true" if this
>> feature is implemented, otherwise "false".
> 
> RubyVM::InstructionSequence.compile_option[:tailcall_optimization]
> 
Thank you for this information. I saw that it still exists in Ruby 1.9.1-p0.

Yesterday I tried to compile Ruby 1.9.1-p0 with changes named by 
Nobuyoshi Nakada. In vm_opts.h I changed

#define OPT_TAILCALL_OPTIMIZATION    0

to

#define OPT_TAILCALL_OPTIMIZATION    1

Afterwards I rebuilt Ruby, but the stack overflow for both examples I 
posted before are still there.

Should I change additional things in the source?

Wolfgang Nádasi-Donner

Updated by Wolfgang Nádasi-Donner almost 3 years ago

As far as I understand this Ticket can be closed. If RubyVM::InstructionSequence.compile_option exists (defined? RubyVM::InstructionSequence.compile_option) and the value is "true" a program can expect a working tail recursion optimization, otherwise not.

Is this correct? - I yes, I think thee is no additional need for an extra constant.

Updated by Nobuyoshi Nakada almost 3 years ago

Hi,

At Tue, 10 Mar 2009 04:26:51 +0900,
Wolfgang Nádasi-Donner wrote in [ruby-core:22785]:
> Afterwards I rebuilt Ruby, but the stack overflow for both examples I 
> posted before are still there.
> 
> Should I change additional things in the source?

trace_instruction option prevents the optimization.

$ cat ~/tmp/tailcall.rb
#! /usr/bin/ruby
src, file, line = <<SRC, __FILE__, __LINE__+1
def a(n)
  return if (n -= 1) <= 0
  a(n)
end
SRC
tailcallopt = ARGV[0] == "true"
traceinst = ARGV[1] != "false"
puts "tailcall_optimization: #{tailcallopt}, trace_instruction: #{traceinst}"
iseq = RubyVM::InstructionSequence.new(src, file, line,
                                       tailcall_optimization: tailcallopt,
                                       trace_instruction: traceinst)
iseq.eval
begin
  a(1000000)
  puts :ok
rescue SystemStackError => e
  puts "#{e.class} #{e.backtrace.size}"
end

$ ./ruby ~/tmp/tailcall.rb 
tailcall_optimization: false, trace_instruction: true
SystemStackError 8187

$ ./ruby ~/tmp/tailcall.rb true 
tailcall_optimization: true, trace_instruction: true
SystemStackError 8187

$ ./ruby ~/tmp/tailcall.rb true false
tailcall_optimization: true, trace_instruction: false
ok

-- 
Nobu Nakada

Updated by Nobuyoshi Nakada almost 3 years ago

  • Status changed from Open to Rejected

Also available in: Atom PDF