Skip to content

Instantly share code, notes, and snippets.

@hugosenari
Last active March 20, 2024 19:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hugosenari/7b6b6ea10b4194bdbbe0f5c84b1fa76d to your computer and use it in GitHub Desktop.
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

hugosenari commented Mar 16, 2024

After reading Monoid without tears

I was thinking how can I use Nim Effect Tracking to track monoid features (column headers), to optimize the code parallelizability.

But ended with the conclusion that would be easier accept pragmas with desired outcome (line left value), and apply the transformation (line right value), informing developer when is appropriate to use each.

@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