All Projects → hissssst → pathex

hissssst / pathex

Licence: BSD-2-Clause license
Fastest way to access data in Elixir

Programming Languages

elixir
2628 projects

Projects that are alternatives of or similar to pathex

To.ml
OCaml library for TOML
Stars: ✭ 68 (-71.9%)
Mutual labels:  lenses
Focus
Lightweight Elixir lenses
Stars: ✭ 224 (-7.44%)
Mutual labels:  lenses
lentes
Functional references for Clojure and ClojureScript
Stars: ✭ 80 (-66.94%)
Mutual labels:  lenses
Lens Regex Pcre
Text lenses using PCRE regexes
Stars: ✭ 116 (-52.07%)
Mutual labels:  lenses
Documentation
How does it all fit together?
Stars: ✭ 177 (-26.86%)
Mutual labels:  lenses
spark-hats
Nested array transformation helper extensions for Apache Spark
Stars: ✭ 21 (-91.32%)
Mutual labels:  nested-structures
Lens
A Racket package for creating and composing pure functional lenses
Stars: ✭ 54 (-77.69%)
Mutual labels:  lenses
exercises-monocle
Scala Exercises for the Scala Optics library Monocle http://julien-truffaut.github.io/Monocle/
Stars: ✭ 12 (-95.04%)
Mutual labels:  lenses
Python Lenses
A python lens library for manipulating deeply nested immutable structures
Stars: ✭ 179 (-26.03%)
Mutual labels:  lenses
xml-lens
XML Optics library for Scala
Stars: ✭ 32 (-86.78%)
Mutual labels:  lenses
Typed
The TypeScript Standard Library
Stars: ✭ 124 (-48.76%)
Mutual labels:  lenses
Sauron
Yet another Scala lens macro
Stars: ✭ 166 (-31.4%)
Mutual labels:  lenses
react-native-nested-listview
A UI component for React Native for representing nested arrays of N levels
Stars: ✭ 163 (-32.64%)
Mutual labels:  nested-structures
Datum
pure functional and generic programming for Erlang
Stars: ✭ 111 (-54.13%)
Mutual labels:  lenses
lenticular.ts
(Yet another) implementation of functional lenses in JavaScript/TypeScript.
Stars: ✭ 29 (-88.02%)
Mutual labels:  lenses
Prolens
👓 Profunctor based lightweight implementation of Lenses
Stars: ✭ 63 (-73.97%)
Mutual labels:  lenses
Microlens
A lightweight (but compatible with ‘lens’) lenses library
Stars: ✭ 254 (+4.96%)
Mutual labels:  lenses
program-imperatively-using-purescript
Program imperatively using PureScript, State monad and lenses
Stars: ✭ 23 (-90.5%)
Mutual labels:  lenses
futils
Utilities for generic functional programming
Stars: ✭ 21 (-91.32%)
Mutual labels:  lenses
Maat
Validation and transformation library powered by deductive ascending parser. Made to be extended for any kind of project.
Stars: ✭ 27 (-88.84%)
Mutual labels:  nested-structures

Pathex

Speed or composability? Choose both!

What is Pathex?

Pathex is a library for performing fast actions with nested data structures in Elixir. With pathex you can trivially set, get and update values in structures in a functional manner. It provides all necessary logic to manipulate data structures in different ways using flexible functional lens pattern.

Why another library?

Existing methods of accesssing data in nested structures are either slow (like Focus) or do not provide enough functionality (like Access). For example setting the value in structure with Pathex is 70-160x faster than Focus or 2-3x faster than put_in and get_in

You can checkout benchmarks at https://github.com/hissssst/pathex_bench

Usage

Pathex is really simple and straightforward to use (almost like Enum). You don't need to learn any specific language, just create paths with path and use verbs with them.

Add it to your module

# This will import path macro and operators and require Pathex
use Pathex

Or just import Pathex

Create the path

path_to_streets = path :user / :private / :addresses / 0 / :street
path_in_json = path "users" / 1 / "street", :json

This creates closure which can get, set, update and delete values in this path

Use the path

{:ok, "6th avenue" = street} =
    %{
      user: %{
        id: 1,
        name: "hissssst",
        private: %{
          phone: "123-456-789",
          addresses: [
             [city: "City", street: "6th avenue", mail_index: 123456]
          ]
        }
      }
    }
    |> Pathex.view(path_to_streets)

%{
  "users" => %{
    1 => %{"street" => "6th avenue"}
  }
} = Pathex.force_set!(%{}, path_in_json, street)

Features

Pathex has a lot of different features and can even compete with code written by hand in terms of efficiency. Pathex significantly reduces the time to write a code which manipulates nested structure, while providing efficiency and composability. No more functions like get_users, set_users, update_users! No more XPaths, JSONPaths, CSS Selectors!

Easy to use

It's not harder to use than Map or Enum! Check out the cheatsheet for common tasks.

Pathex also provides more information about errors than any other tool.

iex(1)> field = :email
iex(2)> Pathex.view!(%{}, path(:users) ~> all() ~> path(:personal / field))
** (Pathex.Error)
  Couldn't find element

    Path:      path(:users) ~> all() ~> path(:personal / :email)

    Structure: %{}

Fast

Paths are just a set of pattern-matching cases. This is done to extract maximum efficiency from BEAM's pattern-matching compiler.

# Code for viewing variables for path
path(1 / "y", :map)

# Almost equals to
case input do
  %{1 => %{"y" => res}} ->
    {:ok, res}

  _ ->
    :error
end

Reusable

One path can be used to update, get, set, delete a value in the structure! And paths can be composed together. This composition is very efficient, there's no need to concat lists like Access does.

# User structure
user = %User{
  personal: %{fname: "Kabs", sname: "Rocks"},
  phone: "123-456-789"
}

# Path to username in user structure
username = path(:personal / :fname)

# Get a username
{:ok, "Kabs"} = Pathex.view(user, username)

# Set a username
another_user =
  %User{
    personal: %{fname: "Blabs", sname: "Rocks"},
    phone: "123-456-789"
  } = Pathex.set!(user, username, "Blabs")

# Get all usernames!
import Pathex.Lenses
["Kabs", "Blabs"] =
  [
    user,
    another_user
  ]
  |> Pathex.view!(all() ~> username)

Pathex can be used to manipulate different nested data structure. From GenServer state to HTML or Elixir's AST!

Extensible

Pathex is built around simple primitive called path-closure, which is a simple closure with clearly defined specification. Anything complying with Pathex.t() spec can be used within Pathex.

Installation

def deps do
  [
    {:pathex, "~> 2.0"}
  ]
end

Contributions

Welcome! If you want to get your hands dirty, you can check existing TODO's.

By the way

If you have any suggestions or want to change something in this library don't hesitate to open an issue. If you have any whitepapers about functional lenses, you can add them in a PR to the bottom of this readme

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].