Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Go-like parallelism in Nim?

Tags:

nim-lang

One thing I like in Go and can't seem to find in Nim yet is Go-like, "modified CSP" kind of parallelism.

I have not even started learning Nim yet, just considering my options for now. I quite liked the Go model, but Nim seems to have threads only.

Is there some package that I can reasonably use for parallelism other than threads in Nim?

Are there any plans to introduce such model(s) in Nim language, like Go or Erlang model (actor model if I understand correctly), broadly in the spirit of message passing?

like image 337
LetMeSOThat4U Avatar asked Jan 21 '20 14:01

LetMeSOThat4U


People also ask

Is Nim statically typed?

Nim is a statically typed compiled systems programming language. It combines successful concepts from mature languages like Python, Ada and Modula.

Why does Nim compile to C?

Nim connects to the C compilation process in order to compile the C source code that was generated by it. This means that the Nim compiler depends on an external C compiler, such as GCC or Clang. The result of the compilation is an executable that's specific to the CPU architecture and OS it was compiled on.

What is Nim coded in?

[Nim] ... presents a most original design that straddles Pascal and Python and compiles to C code or JavaScript. As of October 2021, Nim compiles to C, C++, JavaScript, and Objective-C.

Is Nim strongly typed?

Strong Statically Typed Language Nim boasts efficiency, expressiveness, and elegance. It is a statically typed and compiled language with a very ergonomic type system.


1 Answers

Nim has async/await type coroutines for concurrency within a single thread

Channels are designed for communication between threads, but if you compile with --threads:on it's certainly possible to use them in coroutines.

Here's a simple demonstration of two coroutines passing messages to a third, all concurrent with the main thread.

import asyncdispatch,strformat,random    
    
var chan: Channel[string]     #global declaration

template fakeDelay() = await sleepAsync(rand(2))

proc f(name:string) {.async.} =                              
  for i in 0..6:      
    echo &"{name}: {i}"
    if i==3: chan.send(&"{name}:halfway done")     
    fakeDelay
                                                  
proc monitor() {.async.} =                    
  while true:                                 
    let tmp = chan.tryRecv                    
    if tmp.dataAvailable:                     
      echo tmp.msg                            
    else: await sleepAsync(1)    
                                 
proc main() =  #main doesn't need to be async     
  chan.open()                 
  let steve = f("steve")     
  let mary = f("mary")       
  asyncCheck monitor() #we don't wait for monitor to finish, so we don't need its Future    
  echo "main thread continues"    
  waitFor(steve and mary)    
  
main()

output:

steve: 0
mary: 0
main thread continues
mary: 1
steve: 1
mary: 2
steve: 2
mary: 3
mary:halfway done
steve: 3
mary: 4
steve:halfway done
mary: 5
steve: 4
mary: 6
steve: 5
steve: 6
like image 193
shirleyquirk Avatar answered Oct 08 '22 15:10

shirleyquirk