GithubHelp home page GithubHelp logo

oresoftware / pragmatik Goto Github PK

View Code? Open in Web Editor NEW
1.0 3.0 0.0 102 KB

Parse arguments for variadic functions accordingly.

License: MIT License

JavaScript 55.61% Shell 2.12% TypeScript 42.28%
function arguments parse variadic varargs dynamic dynamic-typing nodejs

pragmatik's Introduction

Pragmatik

This library attempts to solve an age-old problem in JavaScript => how do we correctly parse the arguments inside a function that accepts a variable number of arguments? (See "variadic functions" and "varargs").

This library allows you to elegantly parse arguments at runtime and assign them to the correct/expected variable in the function signature, according to the parsing rules you define. It is most useful for public and private APIs where we want to give our users the convenience of omitting variables, and not requiring them to pass null or other placeholder values. Of course, you should design your APIs well, with simple function calls with limited number of variation in the signature. Using options objects is a great design pattern to keep things simple, but at some point variadic functions become convenient and we must handle them well, without writing buggy code that will fail silently in edge cases.

Disclaimer => the Pragmatik library is in beta

I have seen so many people roll their own solution to this problem - I would be willing to bet at least 1000 JS libraries have public APIs that accept variable number of arguments and/or optional arguments. At best we get bad error messages or no error messages. At worst, we end up with runtimes using the wrong values, until something breaks, or worse until something succeeds. Pragmatik is designed to fail-fast => (1) if your function parsing rules are not valid, an error is thrown (2) if any function cannot be parsed successfully given the runtime arguments and the parsing rules, an error is thrown.

Extensive testing needs to be completed before this library is totally proven. Also need some sanity checks to make sure this is exactly what people need and want. We will incorporate other "types" that can be easily and reliably checked, like 'array'. Unfortunately, type checking beyond simple primitive types is not an effective strategy because you don't know whether the user passed in the argument in the wrong place in the signature or if they passed the wrong value for the right argument.

Basic Usage

The Pragmatik library exports two functions: parse and signature

The following is a function that accepts varargs, and we use Pragmatik to parse the arguments:

const pragmatik = require('pragmatik');

function foo(){
 const [a,b,c,d,e] = pragmatik.parse(arguments, rules);
  
}

so we can call foo above, like so:

foo(true, {zim:'zam'}, function(){});

and Pragmatik can be used to parse the values as they are expected to appear, for example, first we use signature() to define the parsing rules:

const pragmatik = require('pragmatik');

const r = pragmatik.signature({

    mode: 'strict',                        // does not allow two adjacent non-required types to be the same
    allowExtraneousTrailingVars: false,    // no more than 5 arguments allowed
    args: [
      {
        type: 'string',
        required: false,
      },
      {
        type: 'boolean',
        required: true,
      },
      {
        type: 'object',
        required: true,
      },
      {
        type: 'boolean',
        required: false,
      },
      {
        type: 'function',
        required: false,
      }
    ]
 });


function foo(){
 const [a,b,c,d,e] = pragmatik.parse(arguments, rules);
 
 console.log(a,b,c,d,e); 
 // a => undefined
 // b => true
 // c => {zim:'zam'}
 // d => undefined
 // e => function(){}
 
}

if you want better better IDE support, you can do the following instead, but it's fairly unnecessary, (especially considering the purpose of the library is to support varargs):

function foo(a,b,c,d,e){
 var [a,b,c,d,e] = pragmatik.parse(arguments, rules);
  
}

Motivation

As JS is a dynamic language, we can omit arguments completely and still call functions.

For example,

function foo(a,b,c){

}

we can call foo without any arguments at all:

foo();

and this is valid, of course. But in statically typed languages, this probably won't even compile, let alone run :)

So, what if argument a is "optional", but b and c are "required"?

foo might look like:

function foo(a,b,c){
  a = a || 'temp';
  // yadda yadda
  console.log('a:',a,', b:',b,', c:',c);
}

if we call foo like this:

foo('this is b', 'this is c');

then of course, we will get:

a: this is b , b: this is c , c: undefined

Which is totally incorrect, according to our intentions. And the problem only gets worse in more complicated function calls.

We could solve this, by requiring users to always pass 3 arguments, no more, no less, which would be:

foo(null, 'this is b', 'this is c');

But what if we want to make our APIs as beautiful as possible and give our users the convenience of omitting variables?

Enter pragmatik.

Advanced usage

Pragmatik first validates your rules object, to make sure the rules you define are valid according to the way this library works. Parsing varargs is more difficult than you might think, and you have to settle on a good strategy.

Pragmatik uses types ('function','object','string') as a building block for determining if you passed in the expected variable at the given argument index.

pragmatik's People

Contributors

oresoftware avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar

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.