Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    defnpublic

    defn Build Status

    defn is a used to define/overload functions with type signature. It uses type-check for choosing the signature that matches the arguments, and type-precedence to choose the most specific signature.

    $ npm install defn

    Signature definition

    defn supports all the types that can be checked with type-check for arguments signature. It assumes that the signature is a tuple, but the pharantesis are not required. So, (Number, Number) and Number, Number are equivalent. However, a special type notation is added, ...Type, which means that all the arguments are of type Type (... matches any arguments with any type). So, here are few examples of signatures:

    • ... (translates to [*]) - matches anything
    • ...String (translates to [String]) - matches f(\a), f(\a, \b), etc
    • [*] (translates to ([*])) - matches f([1 2 3]), but doesn't match f(1, 2, 3)
    • Number | String - matches f(1) or f(\a), but not f(1, \a)
    • {x: Number, y: Number} - matches f({x: 1, y: 1})

    Usage

    require! \defn
    fn = defn \String, (s) -> "#s is a string"
    fn.overload \Number, (n) -> "#n is a number"
     
    fn \s # "s is a string"
    fn 1 # "1 is a number"

    defn(fn-impl)

    Defines a function with a implementation without a signature (assumes ... as default)

    fn = defn -> it
    fn 1 # 1
    fn \a # 'a'

    defn(signature, fn-impl)

    Defines a function with an implementation having the provided signature

    fn = defn \String -> '#it is a string'
    fn \a # 'a is a string'
    fn 1 # throws Error - Can't call on 1: fn requires one of (String)

    defn(definitions)

    Defines a function with multiple signatures

    {fold, reject} = require \prelude-ls
     
    diff = defn do
      'Number, Number': (a, b) -> a - b
      '[Number], Number': (list, item) -> reject (is item), list
      '[Number], [Number]': (list, sublist) -> fold diff, list, sublist
     
    diff 1, 2 # -1
    diff [1 2 3 1], 1 # [2 3]
    diff [1 2 3 1], [1 2] # [3]

    fn.overload(...)

    Same usage as for defn(...)

    fn = defn -> 'default'
    fn.overload '...String' -> 'string args'
     
    fn \a, \b # 'string'
    fn [1 2] # 'default'

    fn.signatures()

    Returns all signatures defined for the function

    fn = defn do
      '...' -> 'default'
      '{x: *, y: *}' -> 'x:y'
      'Number, Number' -> 'n,n'
     
    fn.signatures! # ['[*]' '({x: *, y: *})' '(Number, Number)']

    fn.has-signature(sig)

    Checks that a certain signature is defined for fn

    fn = defn -> 'default'
    fn.overload \String -> '#it is a string'
     
    fn.has-signature '...' # true
    fn.has-signature 'String' # true
    fn.has-signature '(String)' # true
    fn.has-signature '[*]' # false

    fn.can-call(args)

    Returns true if the arguments args can be called on fn

    fn = defn \Number -> 0
     
    fn.can-call 1 # true
    fn.can-call 1, 2 # false
    fn.can-call [1] # false

    fn.call(...), fn.apply(...)

    Overriden Function methods. Will point to the implementation matched by the provided arguments

    fn = defn \Number -> @.number + it
    fn.overload \String -> @.string + it
     
    obj = number: 1, string: \s
     
    fn.call obj, 20 # 21
    fn.apply obj, [\tring] # 'string'

    Misc

    Chains

    defn and overload are chainable:

    fn = defn -> 'default'
      .overload \String -> 's'
      .overload \Number -> 0
     
    fn.signatures! # ['[*]' '(String)' '(Number)']

    Defs Overwrites

    If a signature gets another implementation, it overwrites the previous

    fn = defn -> 'default'
    fn.overload -> 'the new default'
     
    fn! # 'the new default'

    Signature precedence

    The order in which the signatures are defined is irelevant: the most specific signature for the given arguments is chosen each time, using type-precedence:

    fn = defn do
      '...' -> default
      \Array -> 'a generic array'
      '[Number]' -> 'an array of numbers'
     
    fn [1 2] # 'an array of numbers'
    fn [\a \b] # 'a generic array'
    fn {x: 1} # 'default'

    Keywords

    none

    install

    npm i defn

    Downloadsweekly downloads

    1

    version

    0.2.0

    license

    none

    last publish

    collaborators

    • avatar