Emmy has a big use of concepts: <https://github.com/andreaferretti/emmy> type AdditiveMonoid* = concept x, y, type T x + y is T zero(T) is T AdditiveGroup* = concept x, y, type T T is AdditiveMonoid -x is T x - y is T MultiplicativeMonoid* = concept x, y, type T x * y is T id(T) is T MultiplicativeGroup* = concept x, y, type T T is MultiplicativeMonoid x / y is T Ring* = concept type T T is AdditiveGroup T is MultiplicativeMonoid EuclideanRing* = concept x, y, type T T is Ring x div y is T x mod y is T Field* = concept type T T is Ring T is MultiplicativeGroup Run
And besides Arraymancer, I use this simple Hash function concept to build further cryptography on top of hash functions: <https://github.com/mratsim/constantine/blob/58d8d2c/constantine/hashes.nim#L17-L38> type CryptoHash* = concept h, var ctx, type H ## Interface of a cryptographic hash function ## ## - digestSizeInBytes is the hash output size in bytes ## - internalBlockSize, in bits: ## hash functions are supposed to ingest fixed block size ## that are padded if necessary ## - SHA256 block size is 64 bits ## - SHA512 block size is 128 bits ## - SHA3-512 block size is 72 bits # should we avoid int to avoid exception? But they are compile-time H.digestSize is static int H.internalBlockSize is static int # Context # ------------------------------------------- ctx.init() ctx.update(openarray[byte]) ctx.finish(var array[H.digestSize, byte]) ctx.clear() Run And with all those primitives, I can create a generic `hash` func hash*[DigestSize: static int]( HashKind: type CryptoHash, digest: var array[DigestSize, byte], message: openArray[byte], clearMem = false) {.genCharAPI.} = ## Produce a digest from a message static: doAssert DigestSize == HashKind.type.digestSize var ctx {.noInit.}: HashKind ctx.init() ctx.update(message) ctx.finish(digest) if clearMem: ctx.clear() func hash*( HashKind: type CryptoHash, message: openArray[byte], clearmem = false): array[HashKind.digestSize, byte] {.noInit, genCharAPI.} = ## Produce a digest from a message HashKind.hash(result, message, clearMem) Run And then I can do `sha256.hash(message)`