Functional Ruby
A gem for adding functional programming tools to Ruby. Inspired by Erlang, Clojure, and Functional Java.
NOTE: Version 1.0 is a complete rewrite. Previous versions lacked a unified focus. Version 1.0 is a cohesive set of utilities inspired by other languages but designed to work together in ways idiomatic to Ruby.
Introduction
Two things I love are Ruby and
functional
programming.
If you combine Ruby's ability to create functions sans-classes with the power
of blocks, proc, and lambda, Ruby code can follow just about every modern functional
programming design paradigm. Add to this Ruby's vast metaprogramming capabilities
and Ruby is easily one of the most powerful languages in common use today.
Goals
Our goal is to implement various functional programming patterns in Ruby. Specifically:
- Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why
- Remain free of external gem dependencies
- Stay true to the spirit of the languages providing inspiration
- But implement in a way that makes sense for Ruby
- Keep the semantics as idiomatic Ruby as possible
- Support features that make sense in Ruby
- Exclude features that don't make sense in Ruby
- Keep everything small
- Be as fast as reasonably possible
Features
Complete API documentation can be found at Rubydoc.info.
- Protocol specifications inspired by Clojure protocol, Erlang behavior, and Objective-C protocol
- Function overloading with Erlang-style function pattern matching
- Simple, immutable data structures, such as record and union, inspired by Clojure, Erlang, and others
EitherandOptionclasses based on Functional Java and Haskell- Memoization of class methods based on Clojure memoize
- Lazy execution with a
Delayclass based on Clojure delay
Supported Ruby Versions
MRI 2.0 and higher, JRuby (1.9 mode), and Rubinius 2.x. This library is pure Ruby and has no gem dependencies. It should be fully compatible with any interpreter that is compliant with Ruby 2.0 or newer.
Install
gem install functional-ruby
or add the following line to Gemfile:
gem 'functional-ruby'
and run bundle install from your shell.
Once you've installed the gem you must require it in your project:
require 'functional'
Examples
Specifying a protocol:
Functional::SpecifyProtocol(:Name) do
attr_accessor :first
attr_accessor :middle
attr_accessor :last
attr_accessor :suffix
end
Pattern matching using protocols, type checking, and other options:
class Foo
include Functional::PatternMatching
include Functional::Protocol
include Functional::TypeChecking
def greet
return 'Hello, World!'
end
defn(:greet, _) do |name|
"Hello, #{name}!"
end
defn(:greet, _) { |name|
"Pleased to meet you, #{name.fulle_name}!"
}.when {|name| Type?(CustomerModel, ClientModel) }
defn(:greet, _) { |name|
"Hello, #{name.first} #{name.last}!"
}.when {|name| Satisfy?(:Name) }
defn(:greet, :male, _) { |name|
"Hello, Mr. #{name}!"
}
defn(:greet, :female, _) { |name|
"Hello, Ms. #{name}!"
}
defn(:greet, nil, _) { |name|
"Goodbye, #{name}!"
}
defn(:greet, _, _) { |_, name|
"Hello, #{name}!"
}
end
Memoization:
class Factors
include Functional::Memo
def self.sum_of(number)
of(number).reduce(:+)
end
def self.of(number)
(1..number).select {|i| factor?(number, i)}
end
def self.factor?(number, potential)
number % potential == 0
end
memoize(:sum_of)
memoize(:of)
end
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature) - Commit your changes (
git commit -am 'Add some feature') - Push to the branch (
git push origin my-new-feature) - Create new Pull Request
License and Copyright
Functional Ruby is free software released under the MIT License.





