Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@chrisseaton
Created July 11, 2015 15:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisseaton/4464807d93b972813e49 to your computer and use it in GitHub Desktop.
Save chrisseaton/4464807d93b972813e49 to your computer and use it in GitHub Desktop.
$ jt run --graal test/truffle/can-we-fold-yet.rb test/truffle/can-we-fold-yet.rb
Can Truffle constant fold yet?
> 14
Yes! Truffle can constant fold this to 14
> 14 + 2
Yes! Truffle can constant fold this to 16
> eval([1, 2, 3].inspect).sort[1] * 2
Yes! Truffle can constant fold this to 4
> eval(rand < 0.5 ? '14 - 2' : '10 + 2')
Yes! Truffle can constant fold this to 12
> eval('rand')
No :( Truffle can't constant fold that
@chrisseaton
Copy link
Author

Some more examples:

Proc#binding returns an object representing the environment captured in a block - even if the variables aren't actually lexically referenced. People have said it makes it 'impossible' to optimise local variables like the x in this example http://www.sitepoint.com/laurent-sansonetti-on-rubymotion-internals/. This example proves that wrong:

> x = 14; p = Proc.new { }; p.binding.local_variable_get(:x)
Yes! Truffle can constant fold this to 14

We can merge equal results from two control flow paths, even if we don't know which path is actually taken:

> eval(rand < 0.5 ? '14 - 2' : '10 + 2')
Yes! Truffle can constant fold this to 12

We can constant fold through Hash creation and lookup:

> ({x: 1, y: 2, z: 3})[:y]
Yes! Truffle can constant fold this to 2

We can constant fold through higher order functions like map:

> ({x: 1, y: 2, z: 3}).map { |k, v| v } [1]
Yes! Truffle can constant fold this to 2

We can constant fold through metaprogramming, even if the method that we call is not determinable statically:

> 14.send(:*, 2)
Yes! Truffle can constant fold this to 28
> 14.send('*', 2)
Yes! Truffle can constant fold this to 28
> 14.send((')'.ord + 1).chr, 2)
Yes! Truffle can constant fold this to 28

Metadata can also be constant folded:

> 14.object_id
Yes! Truffle can constant fold this to 29

Some examples of things that don't work for balance:

> rand * 2
No :( Truffle can't constant fold that
> 14.5.object_id
No :( Truffle can't constant fold that
> 'foo' + 'bar'
No :( Truffle can't constant fold that

@mikehearn
Copy link

'foo' + 'bar'
No :( Truffle can't constant fold that

Huh? I am not a Rubyist (anymore) but is there some bizarre gotcha in this example? How comes you can constant fold 14.send((')'.ord + 1).chr, 2) but not two strings being concatenated?

@chrisseaton
Copy link
Author

It's because strings are mutable. A dynamic value 14 is the same as a constant value 14, but 'foo' + 'bar' generates a new value each time, so it's not clear how to make that constant.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment