Skip to content

Instantly share code, notes, and snippets.

Cheap exceptions

Goals:

  • Avoid Rust's Option/Either manual error handling strategy.
  • Make exceptions cheaper.
  • Avoid error translation between Nim libraries by construction. The new vocabulary type ErrorCode is what should be used. Wrappers should translate errors to ErrorCode.
  • Make the error out of memory easier to handle.
  • Resolve once and for all the "error codes vs exceptions" choice.

Pointer free programming

What do ParaSail, "modern" C++ and Rust have in common? They focus on "pointer free programming" (ok, maybe Rust doesn't, but it uses similar mechanisms). In this blog post I am exploring how we can move Nim into this direction. My goals are:

@Araq
Araq / LL.rst
Last active May 30, 2024 13:00

This document describes how Lambda Lifting (LL) works. LL is responsible for transforming 'closures' into (environment, function) pairs.

The basic approach is that captured vars need to be put on the heap and that the calling chain needs to be explicitly modelled. Things to consider:

proc a =
  var v = 0
@Araq
Araq / bintrees.nim
Created May 8, 2023 06:12
Binary trees benchmark
include prelude
type
Node {.acyclic.} = ref object
le, ri: owned Node
proc checkTree(n: Node): int =
if n.le == nil: 1
else: 1 + checkTree(n.le) + checkTree(n.ri)
import macros
proc generateAccessors(name, hidden, typ, fieldTyp: NimNode): NimNode =
template helper(name, hidden, typ, fieldTyp) {.dirty.} =
proc name*(self: typ): auto = self.hidden
proc `name=`*(self: var typ; val: fieldTyp) =
self.hidden = val
result = getAst(helper(name, hidden, typ, fieldTyp))
proc transform(n: NimNode; stmts, obj: NimNode): NimNode =
discard """
cmd: "nim c --gc:orc $file"
output: '''
{"age": 12, "bio": "Я Cletus", "blob": [65, 66, 67, 128], "name": "Cletus"}
true
true
alpha 100
omega 200
0'''
"""
import asynchttpserver, asyncdispatch, strutils, json, tables, streams
# about 130 MB of alive data:
var sessions: Table[string, JsonNode]
for i in 0..<10:
sessions[$i] = parseJson(newFileStream("1.json", fmRead), "1.json")
var served = 0
import macros
macro awaitE(call: typed, r: untyped): untyped =
let x = call[0]
let tx = x.getType()
expectKind tx, nnkBracketExpr
var t = newTree(nnkProcTy)
var p = newTree(nnkFormalParams, tx[1])
import strutils, os
type Target = tuple[repo, package, ext: string]
proc newTarget*(path: string): Target =
let splat = path.splitFile
result = (repo: splat.dir, package: splat.name, ext: splat.ext)
let mem = getOccupiedMem()
const
intrin = "<x86intrin.h>"
{.localPassC: "-msse4.2".}
type
M128i {.importc: "__m128i", header: intrin, bycopy.} = object
const
SIDD_CMP_RANGES = 0b0000_0100'i32
SIDD_NEGATIVE_POLARITY = 0b0001_0000'i32