Neiro | Functional programming, software architecture
28 Nov 2015

Functional Ruby gem

Ruby is a great example of multi-paradigm programming language: it allows you to write code in object-oriented, imperative or functional styles. Ruby have much in common with functional programming languages: high-order functions, closures, anonymous functions, continuations, statements all values. If you want to use more functional programming patterns and tools, you might want to take a look on Functional Ruby gem.

1 Features

  • Thread-safe, immutable data structures
  • Protocol specifications
  • Functions overloading
  • Either, Option classes
  • Immutable variation of Ruby’s OpenStruct class
  • Memoization
  • Lazy execution
  • Tuples
  • Pattern matching

2 Installing

Install this gem with or without bundler:

gem install functional-ruby
#  gem 'functional-ruby'

And then require it in your project:

#+beginsrc ruby require ’functional’ #+endsrc

3 Immutable data structures

#+beginsrc ruby Address = Functional::Record.new(:city, :country, :street, :house) do mandatory :country, :city default :city, ’Moscow’ default :country, ’Russia’ end # <record Address :city=>“Moscow”, :country=>“Russia”, :street=>nil, :house=>nil> #+endsrc

4 Immutable OpenStruct

Immutable, thread-safe, write-once and read-only object variation of OpenStruct:

#+beginsrc ruby name = Functional::ValueStruct.new firstname: ’Hodor’, lastname: ’Hodor’ name.get :firstname # Hodor name.lastname # Hodor name.firstname? # true #+endsrc

5 Tuples

Tuple is a data structure that is similar to array, but is immutable and has a fixed length.

#+beginsrc ruby tuple = Functional::Tuple.new %w(one two three) tuple.at 0 # one tuple.last 0 # three tuple.fetch 4, ’four’ # four tuple.tail.toa # [’two’, ’three’] tuple.repeat(2).toa.join ’,’ # one, two, three, one, two, three #+endsrc

6 Protocols

Protocols are specifications to provide polymorphism and method-dispatch mechanism with strong typing, inspired by Clojure protocols:

#+beginsrc ruby Functional::SpecifyProtocol(:Address) do attraccessor :city attraccessor :country attraccessor :street attraccessor :house end #+endsrc

7 Pattern matching

#+beginsrc ruby

class AddressChecker include Functional::PatternMatching include Functional::Protocol include Functional::TypeCheck

def msg ’You live in Moscow, Russia’ end

defn(:msg, _) do |addr| “You live in #{addr}” end

defn(:msg, _) { |addr| “You live in #{addr.house}, #{addr.street}, #{addr.city}, #{addr.country}” } .when { |addr| Satisfy?(addr, :Address) }

defn(:msg, :name, _) do |addr| “Somebody live in #{addr}” end

defn(:msg, _) { |zip| “Your zip is #{zip}” }.when { |addr| Type?(addr, Fixnum) } end #+endsrc

8 Conclusion

If you like functional programming, and want to use it’s patterns and tools with Ruby, then you can use Functional Ruby gem to write code in more functional style. You can find more information in API documentation.

Tags: ruby functional