Documenting functions in javascript
The idea of this repository is to continue with the last 2 projects that I raised on functional programming in js.
But why?
For some time I have been dedicated to javascript and I see that there is still no standard on how developers should document what data should be passed as parameters. Although JS is not a typed language, somehow we have to specify what data is sent in each parameter.
Currently: Currently this is one of my functions, I have started working with this format.
/*
Receive currency code and return money simbol.
Params
currency : string
Return
string
*/
const getSymbol = (currency)=>{
switch(currency){
case 'ARS':
return '$';
case 'USD':
return 'U$S';
default:
return '$';
}
}
New format: I'm moving to this new format.
/*
Receive currency code and return money simbol.
getSymbol:: string → string
*/
const getSymbol = (currency)=>{...}
Solution - Type Signatures
These type notations are a meta language called Type Signatures, defines the inputs and outputs for the function, sometimes including the number of arguments, the types of arguments and order of arguments contained by a function.
Type Signatures are based on Hindley-Milner Type system as a standard type system which is also followed by ML-influenced languages, including Haskell.
Some examples:
// length :: String → Number
const length = s => s.length;
// length :: [Number] → Number
const length = arr => arr.length;
// join :: (String, [String]) → String
const join = (separator, arr) => arr.join(separator)
Code examples:
The sections are divided in One parameter / Multiple parameters / High order functions.
One parameter:
Examples using 1 parameter as input and one flat return data, f(x) = y.
- STRING - f(String) = Number:
//length :: String → Number
const length = (a)=>a.length;
- NUMBER - f(Number) = Number:
//increase :: Number → Number
const increase = value => value+10;
- BOOLEAN - f(Bool) = Bool.
//inverse :: Bool → Bool
const inverse = value => !value;
- ARRAY - f([x]) = Number.
//length :: [a] → Number
const length = list => list.length;
//length :: [string] → Number
const length = list => list.length;
//length :: [Number] → Number
const length = list => list.length;
- DATE - f(date) = Bool.
//expire :: Date → Bool
const expire = expireDate => new Date()<=expireDate;
- FUNCTION - f(g([a])) = [b].
//map :: (a → b) → [a] → [b]
const map = fn => arr => arr.map(fn)
- ANY - f(*) = b.
//isNull :: * → Bool.
const isNull = obj => !!obj;
- OBJECT - f(object) = String.
Generic format
//map :: object → string
const toJson = obj => JSON.stringify(obj);
Custom format
//map :: {name:String, age: Number} → string
const toJson = people => JSON.stringify(people);
Array of objects
//map :: [{name:String, age: Number}] → [string]
const encode = people => people.map(p=>btoa(p));
Multiple parameters:
Examples using 2 parameters as input and one flat return data, f(x,y) = z.
- STRING:
// join :: (String, [String]) → String
const join = (separator, arr) => arr.join(separator)
- Number - f(x,y) ) = z.
// sum :: (Number, Number) → Number
const sum = (x,y) => x+y;
- Array - f([a],b) = c.
//concat :: [*],string → string
const concat = (list,char) => list.join(char).
High order parameters:
When a function is passed as parameter, we wrap it’s signature in a parentheses to present a more meaningful overall Type Signature. f(g(x)) = y
// addOneToAll :: ((Number → Number),[Number]) → [Number]
const addOneToAll = (addOne = x=>x+1 , arr) => arr.map(addOne)
Using in real world JS
Examples converting functions, comments signature.
Example 1
Before, code example.
/*
Receive two arrays with field, analyze both parameters and return the situation.
Params
flowFields : {fields:[],onboarding_vu:string,document_attached:string}
clientFields : {fields:[],onboarding_vu:string,document_attached:string}
Return
[string] : required fields
*/
const underAge = birth => !birth || (birth && moment().diff(birth, 'years')) < 18;
After, code example using the meta lenguage notation.
/*
Receive two arrays with field, analyze both parameters and return the situation.
underAge :: date → bool
*/
const underAge = birth => !birth || (birth && moment().diff(birth, 'years')) < 18;
Example 2
Before, code example.
/*
GET a file from S3 bucket.
Params
S3 : aws s3 instance,
params : {Bucket:'xxxx',Key:'xxxx'}
Return
promise
*/
const getFile = (s3,params) => s3.getObject(params).promise();
After, code example using the meta lenguage notation.
/*
GET a file from S3 bucket.
getFile :: object, {Bucket:string, Key:string} → promise
*/
const getFile = (s3,params) => s3.getObject(params).promise();
Top comments (0)