Skip to content

Instantly share code, notes, and snippets.

@hugosenari
Last active March 20, 2024 19:43
Show Gist options
  • Select an option

  • Save hugosenari/7b6b6ea10b4194bdbbe0f5c84b1fa76d to your computer and use it in GitHub Desktop.

Select an option

Save hugosenari/7b6b6ea10b4194bdbbe0f5c84b1fa76d to your computer and use it in GitHub Desktop.
Pragma Helper
Identity Closed Pure Associative Commutative Feature
NoOP early return of X
Memoise early return cache
Idempotent early return cache
Map No need to define
Reduce No need to define
ParMap Parallel Map
ParReduce Parallel Reduce
Means f(X,O) = X F[T](X,Y: T): T F(X,Y)=F(X,Y) F(F(X,Y), Z)=F(X,F(Y,Z)) F(X,Y)=F(Y,X)
@hugosenari
Copy link
Author

In a different context elcritch crafted a macro do add accessors replicating to a box type

import macros
import macrocache
import typetraits

const mcTable = CacheTable"subTest"

macro atomicAccessors*(tp: typed) =

  echo "TP: ", tp.treeRepr

  var timpl, tname: NimNode
  if tp.kind == nnkSym:
    timpl = tp.getImpl()
    timpl.expectKind(nnkTypeDef)
    tname = tp
  elif tp.kind == nnkRefTy:
    timpl = tp[^1].getImpl()
    tname = tp

  echo "TIMPL: ", timpl.treeRepr

  var tbody = timpl[^1]
  if tbody.kind == nnkRefTy:
    tbody = tbody[0]

  if tbody.kind == nnkSym:
    let ity = tbody.getImpl()
    ity.expectKind(nnkTypeDef)
    tbody = ity[^1]
  tbody.expectKind(nnkObjectTy)

  let idents = tbody[^1]
  idents.expectKind(nnkRecList)
  result = newStmtList()
  for ident in idents:
    if ident[0].kind != nnkPostFix:
      echo "TIDENT: cont"
      continue
    let name = ident(ident[0][1].strVal)
    let fieldName = ident ident[0][1].repr
    let fieldTp = ident[1]
    let obj = ident "obj"
    let fieldKd = fieldTp.getType()
    let fieldIsRef = fieldKd.kind == nnkBracketExpr and fieldKd[0].strVal == "ref"
    let fieldIsObj = fieldKd.kind == nnkObjectTy
    let fieldKey = fieldName.repr & "::" & fieldTp.repr

    if fieldKey in mcTable: continue
    else: mcTable[fieldKey] = fieldTp

    if fieldIsRef:
      echo "TP:REF: "
      result.add quote do:
        proc `name`*(`obj`: SharedRc[`tname`]): SharedRc[`fieldTp`] =
          newSharedRcRef(`obj`.unsafeGet().`fieldName`)
        atomicAccessors(`fieldTp`)
    elif fieldIsObj:
      echo "TP:OBJ: "
      result.add quote do:
        proc `name`*(`obj`: SharedRc[`tname`]): SharedRc[`fieldTp`] =
          newSharedRc(`obj`.unsafeGet().`fieldName`)
        atomicAccessors(`fieldTp`)
    else:
      echo "TP:ELSE: "
      result.add quote do:
        proc `name`*(`obj`: SharedRc[`tname`]): `fieldTp` =
          `obj`.unsafeGet().`fieldName`


  echo "RES:\n", result.repr

@hugosenari
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment