Skip to content

Instantly share code, notes, and snippets.

type BigObject = object
field: ExpensiveToCopy
proc complexNestedAccessors(o: var Obj) : var ExpensiveToCopy =
var localVariable : BigObject = computeFromComplexAlgorithm()
return o.AggregatedObject.accessor(localVariable)
@zah
zah / gist:1211075
Created September 12, 2011 11:41
The case of unwanted copies
# While programming in nimrod, I often miss the reference types from c++
# Consider this example:
type CompositeObject = object
unwantedCopy: string
expensiveToCopy: list[matrix]
impossibleToCopy: map[string, TNetworkConnection]
proc properAccessor(o: var CompositeObject) : var string =
return o.unwantedCopy
template HelperTemplate(a, b, c: expr) : expr =
....
template AnotherHelper(x: expr, y: stmt) : stmt =
macro ComplexBuilder(a, b, c, d: expr, y: stmt) : stmt =
var ast1 = getAst(helperTemplate(a,b,c))
var ast2 = getAst(anotherHelper(d, y))
proc foo(this: var TBar) =
barMethod(10) # the compiler tries both this.barMethod(10) and just barMethod(10)
a = 340 # the compiler tries both this.a = 340 and assignment to global a = 340
proc applyOperatorToTuple(tp: tuple[T...], operator: symbol) = transformedTyple #couldn't be a specific proc type
...
proc apply[OpSymbol, T: tuple](t: T) : auto =
macro:
var retType = newNimrodType(ntkTuple)
for fields in T:
retType.add(inferType(newCall(OpSymbol, T[1])) #skiping some detail
var transformedExp = .. build and expression of the type (OpSymbol(T[0]), OpSymbol(T[1]), )
template:
var x : retType = transformedExp
proc foo[T](x: T) =
var y = ...
bar(baz)
macro:
var typeOfY = inferType(y)
@zah
zah / gist:1180457
Created August 30, 2011 08:26
How to get side effects from template instantiations
# First, we introduce advices that modify existing methods:
before foo(b: string): int =
b = "input parameters could be modified" & b
after foo(b: string): int =
result = result & "results too"
wrap foo(b: string): int =
# here, we can write arbitrary code
if flipCoin():
#the problem is this
proc `+=`, 10, left (a: int, b: int)
proc `+=`, 20, right (a: string, b: string)
# what about this?
operator `+=`, 10, left
proc `+=` (a: int, b: int)
proc `+=` (a: string, b: string)
template repeatStmt(N: int, code: stmt) : stmt =
when N > 0:
code
repeatStmt(N-1, code)
template repeatTemplate(N: int, tmpl: expr) : stmt =
when > 0:
tmpl(N)
repeatTemplate(N-1, tmpl)