This Month with Nim: September 2021
01 October 2021 The Nim Community
Kombinator
Author: ArMour85
Application to run a command line with lot of combinations of values.
Kombinator parses a TOML configuration file in and generate combinations of commandline invocations.
An example configuration file is as follows:
cmd = "ffmpeg -i $here/../ForBiggerFun.mp4 -s $heightx$width -c:v $codec -ab $audio_bitrate output-$audio_bitrate-$heightx$width-$codec.mp4"
height = [640, 800]
width = [480, 600]
codec = ["libx264", "libxvid"]
audio_bitrate = {min = 128, max = 192, step = 32}
Explanation of its usage can be seen here.
Drawim
Authors: Gabriel Lasso
A drawing library in Nim, inspired by p5js. Builds to native, using OpenGL, and to JavaScript, using HTML5 Canvas.
It allows you to create simulations, visualize structures, make 2D plots and even prototype 2D games with an easy and intuitive syntax.
Example to draw a recursive tree:
import drawim, std/math
proc branch(len: int) =
if (len < 1):
return
line(0, 0, 0, len)
push()
translate(0, len)
rotate(PI / 5)
branch(int(float(len)*0.7))
pop()
push()
translate(0, len)
rotate(-PI / 5)
branch(int(float(len)*0.7))
pop()
proc draw() =
background(200)
stroke(30, 150, 15)
translate(int(width / 2), height)
rotate(PI)
branch(100)
run(600, 400, draw)
Result:
More examples:
Nim for Beginners #26 Reference Objects
Author: Kiloneie
In this video I talk about Reference Objects, what they are, their use cases and a brief talk about Nim’s memory management model.
Chapters/sub chapters of this video:
- What are reference objects ?
- Reference object definition
- “repr” procedure for outputting advanced data types
- Dereferencing a reference object
- Reference objects are passed by reference
- new() procedure for reference types
- Reference object use cases
- Shared ownership
- Nim’s memory management
- Values created on the stack
- Values created on the heap
- .acyclic and .cursor annotations for optimization(just a mention)
Loony
Author: cabboose, disruptek
Multi-threading can be a headache. Especially when it’s so difficult to organise and efficiently communicate between your worker threads. Most of the time you end up with a data-racey unsafe hot mess. Why does it have to be so difficult to safely pass reference objects between threads with some level of determinism? Locks are cumbersome; you have to consider all the possibilities of dead-locking and friends!
Do you wish there was some simple and flexible solution to your multi-threaded nightmare?
Say hello to this loo-natic: Loony. Loony is a lock-free (no dead locks!) multi-producer multi-consumer leak-free FIFO queue! Don’t be concerned by the details of having to distribute work between threads using multiple queues when you can use loony.
Loony can handle up to 32,255 consumer and 64,610 producer threads lock-free (default is 512/1025; see README for details).
Any ref object can be passed through loony. The API? Dead simple:
import loony
type
YourRefObjectHere = ref object
var ruhroh = new YourRefObjectHere
var lqueue = newLoonyQueue[YourRefObjectHere]()
# Setting up your loony queue is as simple as this!
lqueue.push ruhroh
# Don’t be concerned with having to get Consumer/Producer permissions!
# Do what you were born to do and ~move it move it ~ move it move it
var scooby = lqueue.pop()
Are you worried about memory validity? Don’t be!
If you’re not too savvy, the standard push
and pop
API use atomic thread fences
to ensure your CPU caches are synchronised.
Does this have performance costs though? Sure does; however this will be removed with future iterations of the project in conjunction with development of CPS.
You can always use unsafePush
and unsafePop
if you can handle the memory
synchronisation yourself!
The only difference is that we don’t call atomic thread fences for you!
Want to see your project here next month?
Follow this to add your project to the next month’s blog post.