Re: Procs that work only inplace like strutils.removeSuffix()
That is something quite general and a decision in the end of library authors (including standard library). In my case, I try to design a "low-level" API that works completely in-place, this has the side-benefits of allowing the return value to be an error code, nd also a high-level API that returns a new value (and uses exception). The low-level is important because in scientific computing, allocating is often a bottleneck and you want to avoid it if you can. The high-level is because `let c = a + b` is much nicer than any in-place alternative that would require pre-allocation. One approach that was really nice was Lua's which allow chaining of methods that had in-place results: [http://lua-users.org/wiki/MethodChainingWrapper](http://lua-users.org/wiki/MethodChainingWrapper)
Re: Compile time vs run time
Compile time: string my_value = Console.ReadLine(); int i = my_value; A string value can't be assigned a variable of type int, so the compiler knows for sure at compile time that this code has a problem Run time: string my_value = Console.ReadLine(); int i = int.Parse(my_value); Here the outcome depends on what string was returned by ReadLine(). Some values can be parsed to an int, others can't. This can only be determined at run time. More on... [http://net-informations.com/python/iq/checking.htm](http://net-informations.com/python/iq/checking.htm)
Re: Trouble creating type containing generic array
Check how the [stats standard library](https://nim-lang.org/docs/stats.html) is [implemented](https://github.com/nim-lang/Nim/blob/master/lib/pure/stats.nim#L56) or just reuse it.
Re: wNim - Nim's Windows GUI Framework
Print dialog is added as you wish, and more (page setup dialog, printer support, region and shaped window, high DPI support, etc).
Re: Trouble creating type containing generic array
My apologies for not being more clear. I could easily simply create and pass around the plain seqs. But that defeats the purpose. The purpose is to maintain state and knowledge of the array or seq that a smarter object can do. For example in time series data that I collect as time goes on or on historical data that I operate on as if I am in the moment. It is far less expensive to maintain state of a seq than to perform operations on it. Especially if those operations are being done over and over. I tried for a minimal example that would teach me what I needed to know to fix my understanding and solve my problem. However it is not a complete example. An easy example is if I had a seq of which I wanted to know the sum, average, max and min. All these things are easily achieved in a seq or array and computed when desired. They can also become expensive. What is the cost of sum, max and min over a arbitrarily large array? Verses the cost of maintaining a sum, max and min. And then you multiply that cost by every object which has a reference to that seq. That is what I am trying to achieve. Nim is amazing. Its performance in those computation is outstanding. However, if I can avoid them in the first place. I can do better. Creating such an object even in a dynamic language makes knowing the sum, max and min instant even over a multi-million valued array. Then the question might be why have the array not simply maintain state. The array is part of the state. And I do not know that there are no other requirements which can only be met by the array itself. Hope this helps. Thanks for engaging in the conversation.
Re: Trouble creating type containing generic array
Thanks. That works and got me going. I wasn't trying to pass types as a string so much as knowledge about the type. I am still working on understanding generics. I have not found much documentation regarding generics. I have the book and I have read the Tutorial II. Most documentation is regarding defining a proc not a type. Is there documentation I am overlooking? Or is there a good source of source code which would have good examples that are comprehensible by mortals. :) Again thanks.
Re: What text editor are you using for Nim?
VSCode. There is a nice extension for Nim with debugging etc
Re: Procs that work only inplace like strutils.removeSuffix()
> is what you want? Obviously not really -- strutils.removeSuffix() was only an example for some Nim procs which works only in place, while user may need a proc that returns a modified value. (English is not my native language, but after rereading my initial post, I think that my description was not too bad. But maybe I can write my next post more clearly :-) But I think Araq has understood the core of my concern.
Re: Data loss with async sockets
Few cents from my side Seeing all that makes me kinda sad. Nim is pretty neat language and the ecosystem seems to be moving into the proper direction BUT situation like that especially just in sight of 1.0 is at least super concerning. My experience with asyncdispatch is mostly positive BESIDES times where I've hit some corner cases / weird behaviour / undefined behaviour. Having something that is having a lot (let's be honest there...) corner cases, and kinda unexpected design decisions (.connect with UDP) is not super optimal I think, especially that the aim is 1.0. Not having cancellation is really hard block for me, I can't imagine having something running on production without being able to cancel the futures. It will basically screw up most of the error handling. I'm not saying that asyncdispatch is wrong, it's okish, but it requires A LOT of extra testing and stabilization. The community split between asyncdispatch and chronos (a hard fork of asyncdispatch) sounds very bad for me, especially that our community is rather small. In the same time, the existence of chronos proves that async is possible outside of stdlib which is great I think. Seeing and having that situation is definitely not helping nim with adoption... is there any sight how that can be solved/mitigated?
Re: Procs that work only inplace like strutils.removeSuffix()
Maybe proc changeFileExt(filename, ext: string): string {...} ( [https://nim-lang.org/docs/os.html#changeFileExt%2Cstring%2Cstring](https://nim-lang.org/docs/os.html#changeFileExt%2Cstring%2Cstring) ) is what you want?
Re: Trouble creating type containing generic array
I'm not too sure of your end goal but Nim is a static language so types must be known at runtime, you can't pass them a a string. Also your type is generic over int or float so you need to use the generic syntax: type MyArray*[T: int|float] = ref object length*: int index: int arr: seq[T] proc createMyArray[T: int|float](length: int, tp: typedesc[T]): MyArray[T] = result = MyArray[T]( length: length, index: 0, arr: newSeq[T](length) ) var ma = createMyArray(1000, float) Run
Re: Trouble creating type containing generic array
Why are you trying to create such a thing? I am sure you could make such thing in nim (you can do anything in nim). Buy why? I think the reason its hard to do such a thing is that nim is trying to say don't do it this way. If you know the type of array at compile time just use: var ma = newSeq[float](rows) Run If you don't, use a case object: type OddArrayKind = enum OddInt, OddFloat OddArray* = ref object case kind: OddArrayKind of OddInt: intSeq: seq[int] of OddFloat: floatSeq: seq[float] proc createMyArray(length: int, strSind: string): OddArray = if strSind == "int": OddArray(kind: OddInt, intSeq: newSeq[int](length)) else: OddArray(kind: OddFloat, floatSeq: newSeq[float](length)) var rows = 23 var ma = createMyArray(rows, "float") Run I would strongly suggest creating the intSeq or the floatSeq and passing that around instead of doing case objects and these odd string types.
Re: Wow. It all 'just works'
Once more, this is hardly on topic and the wrong forum to discuss these things.
Trouble creating type containing generic array
I am trying to create a type which is basically an Array with additional information. I want to use only [int | float] for the Array. type MyArray* = ref object length*: int index: int arr: seq[int|float] proc createMyArray(length: int, tp: string): MyArray = if tp == "int": let ttype = int elif tp == "float": let ttype = float result = MyArray( length: length, index: 0, arr: newSeq(ttype)[length] ) var ma = createMyArray(int(rows), "float") Run The code is probably naive as I am still learning. The MyArray type compiles if everything below is commented out. As soon as I uncomment, it gives me this error. /home/jimmie/Dev/Nim/ntplayground.nim(125, 19) Error: invalid type: 'int or float' in this context: 'proc (length: int, tp: string): MyArray' for proc Run Any help, wisdom or understanding greatly appreciated.
Re: What text editor are you using for Nim?
I have been briefly exploring Kakoune. I like the idea of a less bloated editor. Currently I have been using Atom. I have not yet really gotten into Vim, or Emacs. I wish it were available for Android. I don't see Nim support. Are you using the lsp plugin? Thanks.
Re: What text editor are you using for Nim?
Neovim user here.
Re: Fastest Prime Sieve, in Nim
@mratsim > Not sure if it's the only bug but for now this is the one to fix for > multithreading on --newruntime #11844. It seems that @Araq has pushed a commit to fix that issue; all that remains is to compile the DEVEL branch and test or wait for a new release... As to exploring different alternative multi-threading: > approaching the limits of OpenMP (nested parallelism especially) I rejected OpenMP early as it is too C'ish and therefore somewhat cludgy although I have used it before with C and see how its use can be expanded beyond the basics available "out-of-the-box". > raw Threads is a too low-level abstraction At first I thought using the low-level would be the answer as in easily emulating GoLang's green threads and that channels would work like GoLang channels; however, it kept getting more complex due to the limitations of not having GoLang's multi-threaded GC and therefore all the Nim limiations on the use of channels, meaning that one has to stoop to the use of low level features as in use of Lock and Cond and essentially building a Nim version of Haskell's "MVar" to pass through the channels. This has caused me to explore @Araq's recommended threadpool. > Nim's FlowVars have contention issues and no load balancing Funny you should say that about FlowVar's as your link to the "pibench2" project doesn't use theadpool and therefore doesn't use FlowVar's. I agree that the linked project using the raw thread's isn't very efficient and should be re-written to use threadpool and spawn as per the following: # Compute PI in an inefficient way but multi-theaded... from cpuinfo import countProcessors from threadpool import FlowVar, spawn, `^` from times import epochTime const DELTA = 1_000_000 # number of terms calculated per thread call! let numprocs = countProcessors() proc pi(numterms: int64): float = result = 0 proc terms(k, klmt: int64): float {.inline.} = result = 0 for i in countup(k, klmt, 2): let frst = i + i + 1; result += 1 / frst.float - 1 / (frst + 2).float # [ # take out the space between the `#` and the `]` to comment this out! var rslt = newSeq[FlowVar[float]](numprocs) # acts as a rotary queue! for i in 0 ..< numprocs: # preload waiting queue! let k = i * DELTA; let klmt = k + (if k + DELTA > numterms: numterms - k else: DELTA - 1) rslt[i] = terms(k, klmt).spawn for i in 0 .. numterms div DELTA: let id = i mod rslt.len; result += ^rslt[id] # get values from queue! let k = (i + numprocs) * DELTA let klmt = k + (if k + DELTA > numterms: numterms - k else: DELTA - 1) rslt[id] = terms(k, klmt).spawn # add new tasks to queue! # ]# #[ # put a space between the `#` and the `]` to uncomment this! for k in countup(0, numterms, DELTA): # do it without threading for comparison let xtra = (if k + DELTA > numterms: numterms - k else: DELTA - 1) result += terms(k, k + xtra) # ]# result *= 4 let start = epochTime() let answr = pi(10_000_000_000) let elpsd = (epochTime() - start) * 1000.0 echo answr, " in ", elpsd, " milliseconds." Run The above code does the same calculations as the "pibench2" with default settings which calculates 10^10 = 10 billion terms for 10 "digits". One can vary DELTA to see that it starts to lose scaling across threads at something below about a hundred thousand when the thread task is something about a millisecond. The above takes about 3.X seconds on a Sandy Bridge CPU with three cores at 2.5 Gigahertz to do a tenth of the job as per the following WandBox link: [https://wandbox.org/permlink/9gOlb1WsjjgWFGIm](https://wandbox.org/permlink/9gOlb1WsjjgWFGIm) but that isn't too certain as the two of the three threads will likely be shared cores; it takes about 54.2 seconds on my Intel Atom i5-Z8350 Windows tablet CPU (Silvermont) at 1.44 GHz and four cores and about 36.25 seconds on my Intel i3-2100 at 3.1 GHz with two cores and four threads. From all of that, your processor being a half again faster clock speed than this last and with nine times the number of cores as well as being seven generations newer might make your 18 core/36 thread machine able to run this in a half second but I would more expect it to be about two to three seconds. One can comment out the multi-threading code and uncomment the single threaded code to see that the code scales with the number of cores other than the uncertainty of Hyperthreading/Simultaneous Multi-Threading threads and the number of floating point execution units there are per core and how they are used by the CPU. It is easy to calculate from these times (especially single threaded ones) that it is taking about 30 CPU clock cycles per term calculation on these older generation CPU's so that seems about right and explains why we need at least about a hundred thousand