bloom-lang / bud

Prototype Bud runtime (Bloom Under Development)
http://bloom-lang.net
Other
854 stars 60 forks source link

map => pro rewrite is overly aggressive #225

Closed neilconway closed 13 years ago

neilconway commented 13 years ago

I think this should be legal Bloom code:

require "rubygems"
require "bud"

class TcSortPro
  include Bud

  state do
    interface input, :dump, [:payload]
    interface output, :pickup, [:ident] => [:payload]
  end

  bloom do
    pickup <= dump.sort.each_with_index.map {|a, i| [i, a]}
  end
end

TcSortPro.new.run_bg

However, it fails:

/Users/neilc/.rvm/gems/ruby-1.8.7-p334/gems/bud-0.0.5/lib/bud.rb:755:in `stratum_fixpoint': Exception during Bud evaluation. (Bud::BudError)
Exception: #<NoMethodError: undefined method `pro' for #<Enumerable::Enumerator:0x101aa5198>>.
Rule: pickup <= (dump.sort.each_with_index.pro { |a, i| [i, a] })

The problem appears to be that map2pro in rewrite.rb changes the map call into a pro call. map2pro claims that to "Look for top-level map on a base-table on rhs, and rewrite to pro", but clearly it bites off more than it can chew here.

Two fixes come to mind:

  1. Make map2pro more conservative, by actually checking that the map is being applied to a Bud collection
  2. Monkeypatch Enumerable::Enumerator to define pro as an alias for map

Implementing #1 might be hard without ruling-out some cases where the rewrite can be done safely (e.g., rewrite applied to an expression that returns a BudCollection).

neilconway commented 13 years ago

The test case can be simplified slightly:

    pickup <= dump.keys.map {|a| a}

produces the same result (albeit we'd need to fix it by monkeypatching Enumerable or Array).