Skip to content

Utility library to ease functional programming in Nim.

License

Notifications You must be signed in to change notification settings

thenjip/funcynim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

funcynim

Build Status Licence

Utility library to ease functional programming in Nim.

This project focuses on maximum backend compatibility, that is:

  • C
  • C++
  • Objective-C
  • JavaScript
  • NimScript (not tested yet)
  • Compile time expressions in all the backends above

Installation

nimble install 'https://github.com/thenjip/funcynim'

Dependencies

Documentation

Overview

The Unit type

Adapting a procedure returning void

import pkg/funcynim/[unit]


proc println*(s: string): Unit =
  echo(s)
  #[
    No need for explicit return.
    Since "Unit" is a single valued type, default initialization has already
    initialized "result" to the only valid value.
  ]#

Procedure composition

func pow2[N: SomeNumber](n: N): N =
  n * n

proc debugPrintlnAndReturn[T](x: T): T =
  debugEcho(x)
  x

when isMainModule:
  import pkg/funcynim/[chain]
  import std/[sugar]

  const
    input = 4.Natural
    got = pow2[input.typeof()].chain(debugPrintlnAndReturn)(input)

  doAssert(got == input * input)

Procedure aliases for operators

discard operator

import pkg/funcynim/[ignore]
import std/[sequtils]

discard
  "abc"
    .`&`('\n')
    .filterIt(it == 'b')
"abc"
  .`&`('\n')
  .filterIt(it == 'b')
  .ignore()

if ...: else: ... expression as a proc

import pkg/funcynim/[fold, into, unit]
import std/[os, sugar]

paramCount()
  .`==`(0)
  .fold((_: Unit) => "no args", (_: Unit) => "got args")
  .into(s => echo(s))

Common math operators

import pkg/funcynim/[operators]

doAssert(5.plus(5).divInt(5) == 2)
doAssert(not true.logicOr(false).logicNot())

Currying

Thanks to nim_curry.

import pkg/funcynim/[curry, ignore, run, unit]
import std/[terminal]

proc writeLn(f: File; styles: set[Style]; self: string): Unit {.curry.} =
  f.styledWriteLine(styles, self)

writeLn(stdout)
  .with({styleUnderscore})
  .run("abc")
  .ignore()

Partial application

Not to be confused with currying.

import pkg/funcynim/[chain, operators, partialproc]

let f =
  partial(1 + ?:int) # (i: int) => 1 + i
  .chain(partial(1.mult(?_))) # (_: auto) => 1.mult(_)

doAssert(f(10) == 11)

And more

See documentation.