Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

A gem for adding functional programming tools to Ruby. Inspired by Erlang, Clojure, Haskell, and Functional Java.

License

Notifications You must be signed in to change notification settings

efeng1st/functional-ruby

Repository files navigation

Functional Ruby

Gem Version Build Status Coverage Status Code Climate Inline docs Dependency Status License

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.

Please see the changelog for more information.

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, thread safe, immutable data structures, such as Record, Union, and Tuple, inspired by Clojure, Erlang, and other functional languages.
  • Thread safe, immutable Either and Option classes based on Functional Java and Haskell.
  • Memoization of class methods based on Clojure memoize.
  • Lazy execution with a Delay class based on Clojure delay.
  • Thread safe data structures, such as FinalStruct and FinalVar, which can be written to at most once before becoming immutable. Based on Java's final keyword.

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

Defining immutable data structures including Either, Option, Union and Record

Name = Functional::Record.new(:first, :middle, :last, :suffix) do
 mandatory :first, :last
 default :first, 'J.'
 default :last, 'Doe'
end
anon = Name.new #=> #<record Name :first=>"J.", :middle=>nil, :last=>"Doe", :suffix=>nil>
matz = Name.new(first: 'Yukihiro', last: 'Matsumoto') #=> #<record Name :first=>"Yukihiro", :middle=>nil, :last=>"Matsumoto", :suffix=>nil>

Pattern matching using protocols, type checking, and other options:

class Foo
 include Functional::PatternMatching
 include Functional::Protocol
 include Functional::TypeCheck
 def greet
 return 'Hello, World!'
 end
 defn(:greet, _) do |name|
 "Hello, #{name}!"
 end
 defn(:greet, _) { |name|
 "Pleased to meet you, #{name.full_name}!"
 }.when {|name| Type?(name, CustomerModel, ClientModel) }
 defn(:greet, _) { |name|
 "Hello, #{name.first} #{name.last}!"
 }.when {|name| Satisfy?(name, :Name) }
 defn(:greet, :doctor, _) { |name|
 "Hello, Dr. #{name}!"
 }
 defn(:greet, nil, _) { |name|
 "Goodbye, #{name}!"
 }
 defn(:greet, _, _) { |_, name|
 "Hello, #{name}!"
 }
end

Performance improvement of idempotent functions through 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

  1. Fork it
  2. Create your feature branch (git checkout -b my-new-feature)
  3. Commit your changes (git commit -am 'Add some feature')
  4. Push to the branch (git push origin my-new-feature)
  5. Create new Pull Request

License and Copyright

Functional Ruby is free software released under the MIT License.

About

A gem for adding functional programming tools to Ruby. Inspired by Erlang, Clojure, Haskell, and Functional Java.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

AltStyle によって変換されたページ (->オリジナル) /