Cuffs
Define your own cuffs to restrict behaviour on a javascript value
cuffs
is a library used to force a type on your javascript value. The main idea comes from the library type-check, where one can check if a javascript value is of a certain type. This library is different in that we force a type onto a certain javascript value. This means that if the javascript value doesn't cohere to the type we forced, it returns an Error, otherwise values are casted or unchanged to fit the needs of the cuffs you defined. Note that forcing is only fully functional when proxies are turned on, otherwise forcing is only done once for array-like, tuple-like and object-like statements. Functions however, are fully proxied even when proxies aren't turned on. The library also allows type casting and custom types. All together this package is really useful for testing, checking input values, or giving your code some structure.
Install
npm install cuffs
General usage and documentation is coming soon. For now you can look at some inspiring examples below.
Examples
//note that OO look just like a pair of handcuffs, but you can call it any way you likevar OO = ; //straightforward usage; //'wow'; //Error //Make a separate function to cuff a specific type//This is espescially handy if your cuff type is pretty complex or needs to be used a lotvar cuffStringOrNumber = ;; //'wow'; // 1; // Error //Cast values; // 5 //Arrays, force all elements of a single type; // [1,2,3,4,5]; // Error; // [1,2,3,4,5] //Tuples, arrays of fixed length; // ['a',1]; // Error;// Error //Object properties; //{foo:'baz',bar:1}; //Error; //{foo:'baz'}; //Error; //{foo:'baz',bar:1,baz:false}; //{foo:'baz',bar:1,baz:false}; //Error //Typed Objects // /foo/ // Error // [1,2,3,4,5] // 'abcde' // Error // Error //Functions, if correct, this returns a function that is forced on the arguments and return valuevar func = ;; //'Hello World'; //Error; //Error; //Error //Cast the arguments of the function, so we can also input other valuesvar func2 = ;; //'12' //Use ellipsis to make the arguments a bit more flexiblevar func3 = ;; //true; //true; //Error var func4 = ;; //undefined; //undefined; //Error ; //Error //Multiple functionsvar func5 = ;; //'test'; //Error //Force even more complex statementsvar obj = obj; //lol!obj; //3obj; //Errorobj //Error
Examples when proxies are turned on
Note: in node.js you need to turn on the harmony_proxies flag to let this work. And depending on whether old-style proxies are used you need to install the harmony-proxy shim.
Note: for browser usage, check out http://caniuse.com/#feat=proxy which browsers are supported
//you can turn on proxies on initializationvar OO = useProxies:true; //or in contextvar OO = ;OO;//Note: If you cuffed a value before (using this OO), new creations of proxies through functions will be prevented or allowed depending on the value you give it in context. //Force objects to stay the way they arevar obj = ; //{foo:'baz',bar:1}objfoo = 'works'; //'works'objbar = "doesn't work"; //Errorobjfoo = 12345; //Errordelete objfoo; //Errorobjbaz = "doesn't work either" //Error //Add ellipsis on objects so more variables can be addedvar obj = ; //{foo:'baz',bar:1}objbaz = "now it works"; //"now it works"delete objbaz; //"now it works" //Force arrays to stay the way they arevar arr = ;arr; //pushes 6 to the arrayarr //Errorarr //[1,2,3,4,5,6] //Force tuples to stay the way they arevar tup = ;tup1 = 'works'; //'works'tup //Errordelete tup1 //Errortuplength = 3 //Errortup //[1,'works']
Examples in livescript
If you use a precompiler that supports infix operators - like livescript (which is used to build this project) - then one can use cuffs infix. This makes it look like it is a real operator!
OO = require('cuffs')! '[String]' `OO` <[ some array of strings ]> # ['some','array','of','strings'] f = '(!Number, !Number) -> Number' `OO` (+) # Here we force a curried function to be uncurried and only accept Number-like variables f 1 2 # 3f \1 \2 # 3f \1 # Errorf true false # 1
Or use it to reinforce your classes (which of course also works in javascript, but this looks more neat)
OO = require('cuffs')! class Dog (@name,@age)-> @name |>= OO \!String @age |>= OO \!Number set-name: '!String ->' `OO` !-> @name = it get-name: '-> String' `OO` -> @name set-age: OO do '!Number ->' !-> @age = it get-age: OO do '-> Number' !-> @age