{"id":13835702,"url":"https://github.com/jdantonio/functional-ruby","last_synced_at":"2025-07-10T10:30:56.841Z","repository":{"id":8307740,"uuid":"9852893","full_name":"jdantonio/functional-ruby","owner":"jdantonio","description":"A gem for adding functional programming tools to Ruby. Inspired by Erlang, Clojure, Haskell, and Functional Java.","archived":true,"fork":false,"pushed_at":"2018-01-09T16:01:47.000Z","size":858,"stargazers_count":553,"open_issues_count":2,"forks_count":22,"subscribers_count":26,"default_branch":"master","last_synced_at":"2024-05-19T02:41:08.177Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"http://www.functional-ruby.com","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jdantonio.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-05-04T11:07:02.000Z","updated_at":"2023-08-10T19:43:29.000Z","dependencies_parsed_at":"2022-08-20T16:00:09.450Z","dependency_job_id":null,"html_url":"https://github.com/jdantonio/functional-ruby","commit_stats":null,"previous_names":["jdantonio/pattern_matching"],"tags_count":21,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdantonio%2Ffunctional-ruby","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdantonio%2Ffunctional-ruby/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdantonio%2Ffunctional-ruby/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jdantonio%2Ffunctional-ruby/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jdantonio","download_url":"https://codeload.github.com/jdantonio/functional-ruby/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225632942,"owners_count":17499890,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-04T14:01:10.039Z","updated_at":"2024-11-20T21:31:16.408Z","avatar_url":"https://github.com/jdantonio.png","language":"Ruby","readme":"# Functional Ruby\n[![Gem Version](https://badge.fury.io/rb/functional-ruby.svg)](http://badge.fury.io/rb/functional-ruby)\n[![Travis CI Build Status](https://secure.travis-ci.org/jdantonio/functional-ruby.png)](https://travis-ci.org/jdantonio/functional-ruby?branch=master)\n[![AppVeyor Build status](https://ci.appveyor.com/api/projects/status/8xfy4a8lmc26112e/branch/master?svg=true)](https://ci.appveyor.com/project/jdantonio/functional-ruby/branch/master)\n[![Coverage Status](https://coveralls.io/repos/jdantonio/functional-ruby/badge.png)](https://coveralls.io/r/jdantonio/functional-ruby)\n[![Code Climate](https://codeclimate.com/github/jdantonio/functional-ruby.png)](https://codeclimate.com/github/jdantonio/functional-ruby)\n[![Inline docs](http://inch-ci.org/github/jdantonio/functional-ruby.png)](http://inch-ci.org/github/jdantonio/functional-ruby)\n[![Dependency Status](https://gemnasium.com/jdantonio/functional-ruby.png)](https://gemnasium.com/jdantonio/functional-ruby)\n[![License](http://img.shields.io/license/MIT.png?color=green)](http://opensource.org/licenses/MIT)\n\n**A gem for adding functional programming tools to Ruby. Inspired by [Erlang](http://www.erlang.org/),\n[Clojure](http://clojure.org/), and [Functional Java](http://functionaljava.org/).**\n\n## Introduction\n\nTwo things I love are [Ruby](http://www.ruby-lang.org/en/) and\n[functional](https://en.wikipedia.org/wiki/Functional_programming)\n[programming](http://c2.com/cgi/wiki?FunctionalProgramming).\nIf you combine Ruby's ability to create functions sans-classes with the power\nof blocks, `proc`, and `lambda`, Ruby code can follow just about every modern functional\nprogramming design paradigm. Add to this Ruby's vast metaprogramming capabilities\nand Ruby is easily one of the most powerful languages in common use today.\n\n### Goals\n\nOur goal is to implement various functional programming patterns in Ruby. Specifically:\n\n* Be an 'unopinionated' toolbox that provides useful utilities without debating which is better or why\n* Remain free of external gem dependencies\n* Stay true to the spirit of the languages providing inspiration\n* But implement in a way that makes sense for Ruby\n* Keep the semantics as idiomatic Ruby as possible\n* Support features that make sense in Ruby\n* Exclude features that don't make sense in Ruby\n* Keep everything small\n* Be as fast as reasonably possible\n\n## Features\n\nThe primary site for documentation is the automatically generated [API documentation](http://jdantonio.github.io/functional-ruby/).\n\n* Protocol specifications inspired by Clojure [protocol](http://clojure.org/protocols),\n  Erlang [behavior](http://www.erlang.org/doc/design_principles/des_princ.html#id60128),\n  and Objective-C [protocol](https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/WorkingwithProtocols/WorkingwithProtocols.html).\n* Function overloading with Erlang-style [function](http://erlang.org/doc/reference_manual/functions.html)\n  [pattern matching](http://erlang.org/doc/reference_manual/patterns.html).\n* Simple, thread safe, immutable data structures, such as `Record`, `Union`, and `Tuple`, inspired by\n  [Clojure](http://clojure.org/datatypes), [Erlang](http://www.erlang.org/doc/reference_manual/records.html),\n  and other functional languages.\n* Thread safe, immutable `Either` and `Option` classes based on [Functional Java](http://functionaljava.org/) and [Haskell](https://hackage.haskell.org/package/base-4.2.0.1/docs/Data-Either.html).\n* [Memoization](http://en.wikipedia.org/wiki/Memoization) of class methods based on Clojure [memoize](http://clojuredocs.org/clojure_core/clojure.core/memoize).\n* Lazy execution with a `Delay` class based on Clojure [delay](http://clojuredocs.org/clojure_core/clojure.core/delay).\n* `ValueStruct`, a simple, thread safe, immutable variation of Ruby's [OpenStruct](http://ruby-doc.org/stdlib-2.0/libdoc/ostruct/rdoc/OpenStruct.html) class.\n* Thread safe data structures, such as `FinalStruct` and `FinalVar`, which can be written to at most once\n  before becoming immutable. Based on [Java's `final` keyword](http://en.wikipedia.org/wiki/Final_(Java)).\n\n### Supported Ruby Versions\n\nMRI 2.0 and higher, JRuby (1.9 mode), and Rubinius 2.x. This library is pure Ruby and has no gem dependencies.\nIt should be fully compatible with any interpreter that is compliant with Ruby 2.0 or newer.\n\n### Install\n\n```shell\ngem install functional-ruby\n```\n\nor add the following line to Gemfile:\n\n```ruby\ngem 'functional-ruby'\n```\n\nand run `bundle install` from your shell.\n\nOnce you've installed the gem you must `require` it in your project:\n\n```ruby\nrequire 'functional'\n```\n\n## Examples\n\nSpecifying a [protocol](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/Protocol):\n\n```ruby\nFunctional::SpecifyProtocol(:Name) do\n  attr_accessor :first\n  attr_accessor :middle\n  attr_accessor :last\n  attr_accessor :suffix\nend\n```\n\nDefining immutable [data structures](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/AbstractStruct) including\n[Either](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/Either),\n[Option](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/Option),\n[Union](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/Union) and\n[Record](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/Record)\n\n```ruby\nName = Functional::Record.new(:first, :middle, :last, :suffix) do\n  mandatory :first, :last\n  default :first, 'J.'\n  default :last, 'Doe'\nend\n\nanon = Name.new #=\u003e #\u003crecord Name :first=\u003e\"J.\", :middle=\u003enil, :last=\u003e\"Doe\", :suffix=\u003enil\u003e\nmatz = Name.new(first: 'Yukihiro', last: 'Matsumoto') #=\u003e #\u003crecord Name :first=\u003e\"Yukihiro\", :middle=\u003enil, :last=\u003e\"Matsumoto\", :suffix=\u003enil\u003e\n```\n\n[Pattern matching](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/PatternMatching)\nusing [protocols](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/Protocol),\n[type](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/TypeCheck) checking,\nand other options:\n\n```ruby\nclass Foo\n  include Functional::PatternMatching\n  include Functional::Protocol\n  include Functional::TypeCheck\n\n  def greet\n    return 'Hello, World!'\n  end\n\n  defn(:greet, _) do |name|\n    \"Hello, #{name}!\"\n  end\n\n  defn(:greet, _) { |name|\n    \"Pleased to meet you, #{name.full_name}!\"\n  }.when {|name| Type?(name, CustomerModel, ClientModel) }\n\n  defn(:greet, _) { |name|\n    \"Hello, #{name.first} #{name.last}!\"\n  }.when {|name| Satisfy?(name, :Name) }\n\n  defn(:greet, :doctor, _) { |name|\n    \"Hello, Dr. #{name}!\"\n  }\n\n  defn(:greet, nil, _) { |name|\n    \"Goodbye, #{name}!\"\n  }\n\n  defn(:greet, _, _) { |_, name|\n    \"Hello, #{name}!\"\n  }\nend\n```\n\nPerformance improvement of idempotent functions through [memoization](http://rubydoc.info/github/jdantonio/functional-ruby/master/Functional/Memo):\n\n```ruby\nclass Factors\n  include Functional::Memo\n\n  def self.sum_of(number)\n    of(number).reduce(:+)\n  end\n\n  def self.of(number)\n    (1..number).select {|i| factor?(number, i)}\n  end\n\n  def self.factor?(number, potential)\n    number % potential == 0\n  end\n\n  memoize(:sum_of)\n  memoize(:of)\nend\n```\n\n## Contributing\n\n1. Fork it\n2. Create your feature branch (`git checkout -b my-new-feature`)\n3. Commit your changes (`git commit -am 'Add some feature'`)\n4. Push to the branch (`git push origin my-new-feature`)\n5. Create new Pull Request\n\n## License and Copyright\n\n*Functional Ruby* is free software released under the [MIT License](http://www.opensource.org/licenses/MIT).\n","funding_links":[],"categories":["Ruby","Ruby Library Collections"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdantonio%2Ffunctional-ruby","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjdantonio%2Ffunctional-ruby","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjdantonio%2Ffunctional-ruby/lists"}