Giter Site home page Giter Site logo

jozty / fae Goto Github PK

View Code? Open in Web Editor NEW
44.0 3.0 7.0 874 KB

A functional module for Deno inspired from Ramda.

Home Page: http://fae.jozty.io/

License: MIT License

TypeScript 99.82% Shell 0.01% Dockerfile 0.17%
functional-programming javascript typescript deno deno-module denoland functional-js functional krow jozty ramda ramdajs fae

fae's Introduction

Fae

CodeFactor GitHub release (latest by date) GitHub Workflow Status GitHub codecov

Fae is a fully-fledged library that supports the functional style of programming in Deno and is inspired from Ramda. This style provides many benefits like it never mutates input data and is used to create function pipelines. Fae functions are automatically curried. The data to be operated on is generally supplied last. It results in easy to build functions as sequences of simpler or atomic functions (pipelines), each of which transforms the data and passes it along to the next.

Fae provides over 110 functions that help programmers to write clean and concise code.

Installing

Deno allows you to directly import modules from URLs!

To import and use the client in your file, add the following import statement:

import * as Fae from 'https://deno.land/x/[email protected]/mod.ts';

Function usage and documentation can be found here

Running tests

deno test
# for coverage tests
deno test --coverage --unstable

Usage

import * as Fae from 'https://deno.land/x/[email protected]/mod.ts';

// arithmetic functions
Fae.add(10, 20); // 30
Fae.add(10)(20); // 30

const add20 = Fae.add(20);
add20(10); // 30
add20(125); // 145

// Expression - (2*5+5-10)/2
const double = Fae.multiply(2);
const half = Fae.divide(Fae._, 2);
const add5 = Fae.add(5);
const subtract10 = Fae.subtract(Fae._, 10);

half(subtract10(add5(double(15)))); // 12.5
Fae.compose(half, subtract10, add5, double)(15); // 12.5
Fae.pipe(double, add5, subtract10, half)(15); // 12.5

With lenses

import {
  inc,
  lens,
  over,
  set,
  view,
} from 'https://deno.land/x/[email protected]/mod.ts';

const array = [1, 2, 3, 4, 5, 6, 7, 8];

// gets element at index `0`
function getter(a: number[]) {
  return a[0];
}

// returns a new array by setting passed value `val` at index `0`
function setter(val: number, a: number[]) {
  const x = [...a];
  x[0] = val;
  return x;
}

const l = lens(getter, setter);

const viewResult = view(l, array);
const overResult = over(l, inc, array);
const setResult = set(l, 12, array);

console.log(viewResult); // 1
console.log(overResult); // [2, 2, 3, 4, 5, 6, 7, 8]
console.log(setResult); // [12, 2, 3, 4, 5, 6, 7, 8]

fae's People

Contributors

ch-shubham avatar code-factor avatar divakar-lakhera avatar jyotijangid avatar masterdammu avatar meenu-yadav avatar neelra8n avatar singla-shivam avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

fae's Issues

New functions- omit, pick, pickOrDefault, pickBy

Is your feature request related to a problem? Please describe.
NA

Describe the solution you'd like
Need to have some more functions. These functions operate on an object (functor) and return a new object.

  1. Omit- This function will take a list of keys (strings) and will return new object with those list of keys not included in the objects.
Fae.omit(['a', 'd'], { a: 1, b: 2, c: 3, d: 4 });  // { b: 2, c: 3 }
  1. Pick- This function will take a list of keys (strings) and will return new object with including those keys only which are in given list of keys.
Fae.pick(['a', 'd', 'e'], { a: 1, b: 2, c: 3, d: 4 }); // { a: 1, d: 4 }
  1. PickOrDefault- This function will take a list of keys (strings) and will return new object with including those keys only which are in given list of keys, and assign a value calculated by given default function if the corresponding key doesn't exist on the object.
Fae.pickOrDefault(['a', 'c'], (key: string) => key + '-default', { a: 1, b: 3 }) //  { a: 2, c: 'c-default' }
Fae.pickOrDefault(['a', 'c', 'd'], Fae.always(4), { a: 1, b: 3 }) //  { a: 2, c: 4, d: 4 }
  1. PickBy- This function will take a predicate function, and will return a new object including keys which satisfy the predicate function.
Fae.pickBy((key: string) => k.length >= 2, { a: 1, bc: 2, def: 3 }) // { bc: 2, def: 3 }

Additional context
Add any other context or screenshots about the feature request here.

style: use deno lint and fmt for formatting purposes

We were using prettier for formatting and nothing for linting. Since prettier was an npm module, we need to install and Node.js too to run it and then use the formatter. That is being an overkill.

To mitigate it, we need to use the Deno built-in formatter and linter. These all will go in a config file (config.json). In Deno, the TypeScript compiler and Deno configurations go in same file. Currently, we have a tsconfig.json file which is used by declarations generator. We will need to move this file to config.json.

`dropWhile` function skips the error when the functor is a `string`

Which function does need to have its types refine/fix?

dropWhile

What is the problem you faced with current types?

When the functor is a string (not an array of strings), the predicate is not forced to take the string as the parameter.

import * as Fae from "[email protected]"

function f(a: number) {
    return a > 10
}

Fae.dropWhile(f, 'df')
Fae.dropLastWhile(f, 'df')

Playground

Expected behavior

It should have result in an error.

Additional context

The same problem was for dropLastWhile but it has been fixed #84. Change

Versions (please complete the following information):

  • Fae: v1.1.1

Support for array-like for the function `indexOf`

Is your feature request related to a problem? Please describe.
Currently, the function indexOf supports the searching over the arrays only. It should also support the same functionality on the array-like too

lint: use `ban-ts-comment` lint rule

In #71, we had added lint to Deno config. To pass the CI/CD for sometime, we had added some of the rules to lint-exclude. We need to remove those one by one. In this issue, we will removing ban-ts-comment lint rule from the lint-exclude option.

[Placeholder] types: improve lens related functionalities

Which function does need to have its types refine/fix?
Lens related functionalities

What is the problem you faced with current types?
A clear and concise description of problem along with an example code.

Expected behavior
A clear and concise description of what you expected to happen along with an example code.

Versions (please complete the following information):

  • Deno:
  • Fae:

lint: use `no-explicit-any` lint rule

In #71, we had added lint to Deno config. To pass the CI/CD for sometime, we had added some of the rules to lint-exclude. We need to remove those one by one. In this issue, we will removing no-explicit-any lint rule from the lint-exclude option.

[Placeholder] types: `andThen`

Which function does need to have its types refine/fix?

andThen

What is the problem you faced with current types?

A clear and concise description of problem along with an example code.

Expected behavior

A clear and concise description of what you expected to happen along with an example code.

Versions (please complete the following information):

  • Deno:
  • Fae:

Refine types- flip

Which function does need to have its types refine/fix?
flip

What is the problem you faced with current types?
The flip function does not have any types as of now. It takes a function with parameters as any and return type is also any.

Expected behavior
The first two and the rest of the parameters should be inferred properly and the return function should have appropriate type. For example-

declare function func(a: string, b: number, c: boolean, d: string[]): number[]

// `flippedFunc` should have a type of-
// (b: number, a: string, c: boolean, d: string[]): number[]
const flippedFunc = Fae.flip(func)

Versions (please complete the following information):

  • Fae: v1.0.0

research: `pipe` and `compose`

Which function does need to have its types refine/fix?

pipe and compose

What is the problem you faced with current types?

pipe and compose returns which take unknown arguments and returns unknown. The developer needs to type assert the returned function always to correctly use it.

Expected behavior

Need to do some research such that pipe and compose returns the function such they are able to better infer types and return inferred function type properly

Versions (please complete the following information):

  • Fae: 1.x.x

lint: use `no-unused-vars` lint rule

In #71, we had added lint to Deno config. To pass the CI/CD for sometime, we had added some of the rules to lint-exclude. We need to remove those one by one. In this issue, we will removing no-unused-vars lint rule from the lint-exclude option.

Heavy use of any types

There are any types all over the place ๐Ÿ˜ฑ .

I mean, that's fine ๐Ÿ˜„ , but you might want to document it in the readme. Many will refrain from using something that undermines type safety!

implementation of `complement`

Is your feature request related to a problem? Please describe.

Currently, the function definition and signature is there for complement but actual implementation is not there. Need to write the implementation. Along with that, need to write the examples and tests for complement.

Make all find functions consistent

Currently there are following find functions-

  1. find- finds the first element which satisfies the given predicate
  2. findIndex- finds the index of the given element. Equality by referential strict equality ===
  3. findLast- finds the last element which satisfies the given predicate
  4. findLastIndex- finds the index of last element which satisfies the given predicate

Three of these function takes predicate while one take the element directly. Moreover, the equality is referential only instead of equals.
We need to make the interface consistent.

For that, we need to change the signature of findIndex. This will be a breaking change. findIndex should take a predicate function. Moreover, need to add examples in the JSDoc for all the functions to show the case for equality check. E.g.

const findInFunctor = Fae.find(Fae._, [4, [1, 2], {a: 1}, 3, 5, false, 'abc', null])

findInFunctor(Fae.equals(3)) // 3
findInFunctor(Fae.equals([1, 2])) // [1, 2]
findInFunctor(Fae.equals([1, 2, 3])) // undefined
findInFunctor(Fae.equals({a: 1})) // { a: 1 }
findInFunctor(Fae.equals(false)) // false

lint: use `ban-types` lint rule

In #71, we had added lint to Deno config. To pass the CI/CD for sometime, we had added some of the rules to lint-exclude. We need to remove those one by one. In this issue, we will removing ban-types lint rule from the lint-exclude option.

'import type' errors from TypeScript in Deno 1.4.0

For some reason, when I run Deno 1.4.0's new deno test --unstable --coverage command, I get errors from Fae that didn't previously appear:

$ deno test --unstable --coverage lib_test.ts 
Debugger listening on ws://127.0.0.1:9229/ws/4f1e8421-8cec-4f18-8def-09808684fc03
Check file:///home/scott/Projects/dotfiles/scripts/.deno.test.ts
error: TS1371 [ERROR]: This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'.
import { Func } from "./types.ts"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/utils/set.ts:1:1

TS1371 [ERROR]: This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'.
import { Func } from "./types.ts"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/utils/curry_n.ts:3:1

TS1371 [ERROR]: This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'.
import { Func, PH } from "./utils/types.ts"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/zipWith.ts:1:1

TS1371 [ERROR]: This import is never used as a value and must use 'import type' because the 'importsNotUsedAsValues' is set to 'error'.
import { PH } from "./utils/types.ts"
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    at https://deno.land/x/[email protected]/zip.ts:3:1

Found 4 errors.

I am importing only the zip function, but I assume similar issues would arise in other parts of Fae.

ci: add examples to the CI/CD workflow

Is your feature request related to a problem? Please describe.

In the site, we have a feature Try on playground. For that to be implemented in the site, we were writing the example in the playground and writing the corresponding base64 string in the all.md file. This was posing mainly two problems-

  1. The file all.md was getting larger and larger. And the code was hard to change and it looked messy in the file
  2. There was no way to test the example against the latest version of Fae

Describe the solution you'd like

To solve the problem, we will be write the examples in the examples directory in Fae as Deno files only. They would import the latest version of Fae from Deno servers. Then, the website will fetch these examples files for a given function on demand. When the person clicks on the button Try on playground,

  1. the site server will fetch the file (if doesn't exists),
  2. will do appropriate sanitization on the imports,
  3. covert it to url-safe base64 and generate the playground url,
  4. and then redirects the developer to playground populated with the example for that function.

The functionality is already implemented in the website. See Jozty/website#29

In Fae, we will have checks on CI/CD pipelines to run all those examples against the latest version of Fae.

Additional context

Issues for adding examples in incremental manner- #59, #61

BDD in tests

Recently, Deno had added a module to support Behavior-driven development. We are using custom describe and it which are not so like actual bdd. So, we can replace it with Deno provided bdd.

Improve types for `dissoc`

Which function does need to have its types refine/fix?
dissoc

What is the problem you faced with current types?
The the types for dissoc are not properly inferred and are not returned properly.

Expected behavior
It should take a generic obj T and prop P and the return should be the type omitting P from the keys of T

Versions (please complete the following information):

  • Fae: 1.x.x

Bug: dropRepeats tansformer doesn't work curried dispatched

Describe the bug
dropRepeats has a transformer- DropRepeatsTransformer. The final function is curried (1-arrity) version of the dispatched version.

export const dropRepeats: DropRepeats = curryN(1, dispatched)

Since its arrity is one, we don't need a curried version. But after removing curryN, the transformer version of dropRepeats fails. It is working when a single array is passed. This can be a bug in the core dispatch or transformer-transducer logic.

Expected behavior
After removing curryN, the transformer version should have worked

Versions (please complete the following information):

  • Fae: 1.0.0

Additional context
Add any other context about the problem here.

lint: use `no-fallthrough` lint rule

In #71, we had added lint to Deno config. To pass the CI/CD for sometime, we had added some of the rules to lint-exclude. We need to remove those one by one. In this issue, we will removing no-fallthrough lint rule from the lint-exclude option.

lint: use `no-var`, `no-empty` and `require-await` lint rule

In #71, we had added lint to Deno config. To pass the CI/CD for sometime, we had added some of the rules to lint-exclude. We need to remove those one by one. In this issue, we will removing no-var, no-empty and require-await lint rule from the lint-exclude option

Remove unnecessary curried types

There are some functions which has unnecessary curried types

e.g function add has following types

type Add_2 = (b: number) => number

type Add_1 = (a: number) => number

type Add =
  & ((a: number, b?: PH) => Add_2)
  & ((a: PH, b: number) => Add_1)
  & ((a: number, b: number) => number)

Here, add takes two args of same type. Thus, calling add like add(3) or add(3, _) or add(_, 3) are equivalent. So we can remove such types from the definition. So final type will be-

type Add_2 = (b: number) => number

type Add =
  & ((a: number) => Add_2)
  & ((a: number, b: number) => number)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.