Re: using nimble for package management
I am not quite sure what you are asking? * If you have a package that you are developing and making local updates use nimble develop then you can make edits, use git pull etc... and package stays in sync. * If you want to update a package that you don't own, increment its version in your *.nimble file and run nimble install in your directory? Does your project have its own *.nimble file? * If you want to know when new versions come out of your packages so that you can update... I am not sure ... is this the question you are asking? 1) Nim will install all versions you require so if some one requires sdl2_nim-2.0.12.0 it will be installed, if some one requires sdl2-2.0.2, if some one requires sdl2_nim-#head it will be installed. 2) You should not need to update or clean packages in your pkg directory, you do that in your *.nimble file. Then nimble install in your project go gets the right versions.
Re: Understanding Pragmas
Pragmas are just a way to attach more info to the functions. The compiler takes the data in the pragmas and does some thing special with it. Take the {.inline.} pragma it just marks the functions with inline=true and then when compiler sees the function it inlines it. You can also create your own pragmas and use them in your own code. You can also use pragmas with macros. Most famous example is the {.async.} pragma which chops a linear function into several sections and provides async capabilities. Pragmas can be used for so many things, here is a massive list: [https://nim-lang.org/docs/manual.html#pragmas](https://nim-lang.org/docs/manual.html#pragmas) Other languages have keywords such as static, final, inline... but you can't add your own keywords like that, but in nim you can... through pragmas.
Re: How to set up/start a Project?
This is project structure I use: [https://github.com/treeform/nimtemplate](https://github.com/treeform/nimtemplate)
Re: Why Seq search is faster than Table search
I love performance puzzles like this! Answer: Turns it it just optimizes the for loops away! Timings i get with the code provided: List: (seconds: 0, nanosecond: 9180) Table: (seconds: 0, nanosecond: 2794545) Run Really strange! Added dummy counter so that for loops don't get optimized out. In fact, program ran so slow I had to change the counter to 1000: import std/monotimes import tables import random var myTable = initTable[int, int]() var myList: seq[int] for i in 0 .. 1_000: myTable[i] = i myList.add(i) myList.shuffle() var start = getMonoTime() var dummyCounter = 0 for i in 0 ..< 1_000: if myList.contains(i): inc dummyCounter echo("List: ", getMonoTime() - start) start = getMonoTime() for i in 0 ..< 1_000: if myTable.hasKey(i): inc dummyCounter echo("Table: ", getMonoTime() - start) echo dummyCounter Run List: (seconds: 0, nanosecond: 142290) Table: (seconds: 0, nanosecond: 3060) Run Tables are soo soo much faster!
Re: Why Seq search is faster than Table search
I did some more work on it, I measured time at each array size from 0 to 10_000, see chart: [https://dl3.pushbulletusercontent.com/4m74W8NlcdcrpJnVgCT53RkL2nxUPimc/image.png](https://dl3.pushbulletusercontent.com/4m74W8NlcdcrpJnVgCT53RkL2nxUPimc/image.png) It shows you how much tables are faster during each number of elements. run with nim c -r --d:danger import times import tables import random var myTable = initTable[int, int]() var myList: seq[int] for i in 0 .. 1_000: myTable[i] = i myList.add(i) myList.shuffle() var dummyCounter = 0 for n in 0 .. 10_000: const trytimes = 10 var start = epochTime() for j in 0 .. trytimes: for i in 0 ..< n: if myList.contains(i): inc dummyCounter let listTime = epochTime() - start start = epochTime() for j in 0 .. trytimes: for i in 0 ..< n: if myTable.hasKey(i): inc dummyCounter let tableTime = epochTime() - start echo n, ", ", listTime/trytimes, ", ", tableTime/trytimes echo dummyCounter Run
Re: Introducing --gc:arc
Wow amazing improvement. It's nearly manual speed.
Re: Multithreaded await
In my system I do all async/await and asyncdispatch on a single thread. Then I have a work Q to do other the actual work. Was very simple to put together.
Re: New blog post: Ray tracing in Nim
Very nice blog post!
Re: Problem sending binary file by socket never ending.
EOF or End of file in linux is usually when getChar returns -1. But you can't actually send -1 with a socket. All bytes must be 0-255. End of file in DOS was ASCII character 'x04', also known as End of Transmission or ^D in linux. You could send that and check for that character. But the problem is that you said binary. It's very easy for a binary file to have a 0x04 byte some where inside which will cut off your file. Its best to just send length of the file first. Read the length and then read the number of bytes you need for the rest of the file.
Re: New garbage collector --gc:orc is a joy to use.
Yes I "move" the ownership of objects from the main thread to the work threads. And I "move" the ownership back from work thread to the main thread. Once and objects moves a way from the thread it was created on I will not be touching the object or its internal sub objects on that thread. Nim does not have any notion of ownership so I have to do that manually. I don't expect that both threads reading/writing to objects without locking to work. Does that make sense? Please check out the code. Will the new islolated: block help with making sure I don't touch objects or sub objects without locking them first?
Re: New garbage collector --gc:orc is a joy to use.
There is this: * [https://nim-lang.org/docs/gc.html](https://nim-lang.org/docs/gc.html) * [https://www.youtube.com/watch?v=aUJcYTnPWCg](https://www.youtube.com/watch?v=aUJcYTnPWCg) * [https://www.youtube.com/watch?v=yA32Wxl59wo](https://www.youtube.com/watch?v=yA32Wxl59wo) * [https://nim-lang.org/araq/destructors.html](https://nim-lang.org/araq/destructors.html) * [https://nim-lang.org/araq/ownedrefs.html](https://nim-lang.org/araq/ownedrefs.html)
New garbage collector --gc:orc is a joy to use.
Nim has a new garbage collector called Orc (enabled with --gc:orc). It’s a reference counting mechanism with cycle direction. Most important feature of --gc:orc is much better support for threads by sharing the heap between them. Now you can just pass deeply nested ref objects between threads and it all works. My threading needs are pretty pedestrian. I basically have a work queue with several work threads and I need work done. I need to pass large nested objects to the workers and the workers produce large nested data back. The old way to do that is with channels, but channels copy their data. Copying data can actually be better and faster with “share nothing” concurrency. But it’s really bad for my use case of passing around large nested structures. Another way was to use pointers but then I was basically writing C with manual allocations and deallocations not nim! This is why the new --gc:orc works so much better for me. You still need to use and understand locks. But it’s not that bad. I just use two locks for input queue and output queue. They try to acquire and release - hold the locks - for as little as possible. No thread holds more than 1 lock at a time. See my threaded work example here: [https://gist.github.com/treeform/3e8c3be53b2999d709dadc2bc2b4e097](https://gist.github.com/treeform/3e8c3be53b2999d709dadc2bc2b4e097) (Feedback on how to make it better welcome.) Before creating objects and passing them between threads was a big issue. Default garbage collector (--gc:refc) gives each thread its own heap. With the old model objects allocated on one thread had to be deallocated on the same thread. This restriction is gone now! Another big difference is that it’s more deterministic and supports distructors. Compilers can also infer where the frees will happen and optimize many allocations and deallocations with move semantics (similar to Rust). Sadly it can’t optimize all of them a way that is why reference counting exists. Also the cycle detector will try to find garbage cycles and free them as well. This means I do not have to change the way I write code. I don’t have to mark my code in any special way and I don’t really have to worry about cycles. The new Orc GC is simply better. This makes the new garbage collector--gc:orc a joy to use. (If there are any factual errors about the GC let me know.)
Re: First look
Space between function and parameters is important. echo ("\nProcessor count ", countProcessors()) echo 1 echo () Run is same as: echo(("\nProcessor count ", countProcessors()) echo(1) echo(()) Run Just remove the space between function and parameters and you are all set.
Re: jester: one handler for several routes?
You can use templates like this: [https://play.nim-lang.org/#ix=2pC5](https://play.nim-lang.org/#ix=2pC5) import tables var routeMap: Table[string, proc()] template routes(body: untyped) = # init server pre routs body template get(url: string, body: untyped) = routeMap[url] = proc() = body proc resp(data: string) = discard routes: get "/hello": resp "Hello" get "/helloWorld": resp "Hello World" for k, v in routeMap: echo k Run
Re: Has anyone wrapped zlib or reimplemented deflate?
I wrapped miniz which implements low level zip but not expanded gzip protocol [https://github.com/treeform/miniz](https://github.com/treeform/miniz) But if you control both ends, I highly recommend [https://github.com/jangko/snappy](https://github.com/jangko/snappy) . Its fast, its very simple and its all pure nim.
Re: Perf: Table.del(key)is taking 85% of my code's time
I also experienced really bad Table performance which was related to really bad hash generation. Print out the hash(key) and see if you hashes are usually bad.
Re: Nim version 1.2.2 is out!
Wow thanks for all of the hard work! I love new new versions.
Re: Nim's popularity
This talk has a pretty good part about how most popular languages got popular: [https://www.youtube.com/watch?v=QyJZzq0v7Z4](https://www.youtube.com/watch?v=QyJZzq0v7Z4) To summarize, according to the talk, there are 5 major ways to popularly (top 10): 1. Killer App: C, Ruby, PHP 2. Platform Exclusivity: JS, Obj-C, Swift, C# 3. Quick Upgrade: C++, Kotlin, TypeScript 4. Epic Marketing: Java 5. Slow & Steady: Python I think Nim right now is doing a little bit in 3 out of 5 directions. 1\. Killer App: Nim has the ability compile to both JS and Native allowing same code. If only Nim could do this it would be really cool, but Node/JavaScript can do this as well. Nim needs to find some thing else. Nim can interface between c/c++ and other languages. The FFI is really good. Is this enough for a killer app? 2\. Platform Exclusivity: Nim is not doing anything here. There is no only Nim platforms and probably never will be. 3\. Quick Upgrade: Nim is kind of a quick upgrade from Python and maybe C++. But it does not feel quick "enough", but it's there. Languages like Kotlin and TypeScript are much quicker. 4\. Epic Marketing: Nim is doing nothing here. No one is spending a million dollars on Nim ads or Nim conferences. 5\. Slow & Steady. The slow community path. This is probably where Nim is growing the most right now. But not sure its fast enough. I also think that most languages have this path as well. This path is way too crowded.
Re: Can't access fields of object returned by a procedure
For oldcommers too! Error should say x is not public, not that x is missing.
Re: Lambda syntax is awkward
I actually prefer the "original problem" syntax. It's only like couple of characters of extra typing. The do, -> and => feel less clear.
Re: How mature is async/threading in Nim?
> which GC is the default The _\--gc:refc_ (deferred reference counting/heap per thread) is the default right now. The _\--gc:arc_ (immediate reference counting/shared heap) or _\--gc:orc_ (immediate reference counting/shared heap + cycle detector) is set to replace it. The _async_ stuff works well with _\--gc:refc_ but buggy with _\--gc:arc_ because it creates cycles for which you need _\--gc:orc_. Both _\--gc:arc_ and _\--gc:orc_ are pretty new. The _async_ stuff works badly with threads because it kind of requires _\--gc:refc_ right now and passing stuff between thread requires copying between heaps. Soon _\--gc:arc_ and _\--gc:orc_ will work with _async_ and will replace _\--gc:refc_. Then _async_ will work with threads better.
Re: How mature is async/threading in Nim?
> Could you explain why not? Current current gc:refc does not allow refs object to be passed between threads willy nilly. Async creates a reactor ref object per thread. So you can't really share the async corutines between threads. Threads are just kind of hard to use with gc:refc, that is why gc:arc is getting worked on. > This project is a library for (primarily) mobile apps. I have limited experience with nim mobile apps. But knowing what I know don't think I would use async on the client. Async is great if you are doing tons of http style requests. But really a mobile client? Just regular threads are probably better if you are just writing and reading from a single websocket connection. I would try both methods to see which one fits you better. I am also a huge fan of UDP, packed based protocol instead of streaming http/tcp. You don't even need threads to have a good UDP system. Here is what I use [https://github.com/treeform/netty](https://github.com/treeform/netty) if I control both ends. But some times you just have to go with WebSockets, I wrote a library for that too: [https://github.com/treeform/ws](https://github.com/treeform/ws) though its async based.
Re: How mature is async/threading in Nim?
I use async/await in production, but only server side on Linux. It's pretty mature for a simple web application. My app runs on multiple servers instead of threds. Async does not mesh well with threds. Multiprocessing is more scalable anyways.
Re: Revisiting my oldest Nim project.
> that's a C++ problem; nim doesn't have this problem. Look at the std/times > module which abstracts the internal representation as (secs,nsecs) For me Nim does have this problem. That is why I don't use std/times module. It just works badly in JS mode. Yes in theory a more accurate time representation is best. But in practice the float64 wins out because it's easy to use and an interoperate between many systems. > good reason almost all datetime libraries use fixed point/integral > arithmetics internally to represent time instead of FP I don't think this is true. As I deal with float64 timestamp system all the time, its just it's usually in milliseconds because of javascript/java or seconds if I am dealing with python.
Re: Revisiting my oldest Nim project.
> Bummer, I still like them better than json. :-) String stream only started to work with JS recently and still can't do pointer stuff. I wish binary formats was better supported in JS. > There are cases where you want to store a (timestamp, timezone) tuple Exactly, I view timestamp as kind of a string and timezone kind of language code. If you need to store what language a string is in, yes store it. But most of the time that is not needed, and you just need to display time in the user's "language." > nimble removes the src directory I never had an issue with that. Maybe you need to use staticRead instead of readFile? > float64 for timestamp I still will stand for float64 timestamp for my application. Yes there are special places like banking that don't use float points. They are special. You would not use float points for money too. For almost every one else float64 since 1970 fits the bill. * Seconds is the SI time unit. Not using it is like using decameters or distance. Its just strange. * Seconds from 1970 works great as its when unix time started. * You can't use int64 in JS. Most of my work is in JS. You can't encode that in json. So you would have to use two numbers ... maybe seconds and microseconds? BigInt in json looks like a pain. * I interface with many systems and they give me random scaling. I always have bugs with this conversions. Even with nim, is sleep() in seconds, milliseconds, or microseconds? In python I always know its seconds. Because everything else is seconds. Python does it best. Just use single scaling, its not so hard! Here is what I deal with on daily bases > * python 1.0 > * java 1000 > * js 1000 > * bigquery 1000_000 > * go 1000_000_000 > That is why I use float64 seconds from 1970 utc. > leap seconds I should add a j2000 mode as that will enhance my [https://github.com/treeform/orbits](https://github.com/treeform/orbits) library.
Revisiting my oldest Nim project.
My first serious project was Chrono a Timestamps, Calendars, and Timezones library for Nim. [https://github.com/treeform/chrono](https://github.com/treeform/chrono) I have become much better at Nim than when I first wrote it. I recently went over the project and wanted to share things that I have improved. 1\. Github actions. Github actions are easy to set up and make sure your project/library stays tested. I now use this as a standard for all my Nim projects: [https://github.com/treeform/chrono/blob/master/.github/workflows/build.yml](https://github.com/treeform/chrono/blob/master/.github/workflows/build.yml) It just runs nimbe test which means it will probably work for your project too without changes. 2\. Turns out nimbe test just runs all files that start with test in the test directory. Easy. No need to configure how the tests are to be run. 3\. When I was new to Nim I wanted everything static and pointerless. For this I thought not using a string but instead using this packed string in an array was smarter. But now I learned - just use a string, it's fine. Don’t over complicate your code. 4\. I did not want to use json. I wanted to use binary formats .. compressed binary formats. If you are storing nested data just use json. It’s simply an eraser. I removed a bunch of the code for creating and loading the binary formats and my life became simpler. I mostly use this library in JS mode so binary format was not really needed. 5\. Always put your code into a src dir. Even though nimble supports not having src dir, it’s just better in every way. 6\. Use nimpretty. It’s easy to use and formats your code so it’s more inline with the Nim standard. I feel tools like nimpretty from bikeshedding discussion on how code should be formatted. It just does its thing. I wish it did more though. 7\. Write good tools with command line parameters. In my earlier version I had people modify the src file to run it. That was just stupid. I added parameters to generate and now you can generate a timezone dump of any time slice you want. nim c -r tools/generate.nim json --startYear:2010 --endYear:2030 --includeOnly:"utc,America/Los_Angeles,America/New_York,America/Chicago,Europe/Dublin" Run Some things have not changed and I still firmly stand by on: A. For a time library, the lowest building block should be the timestamp of a single float64, not a complex calendar object. You should store timestamps and transfer timestamps. Calendar should only be used in time calculation like next month, previous week, 60 days from now… its a display/compution object that should be short lived. B. Normalizing a calendar is an easy way to work with it. Instead of not allowing a month of 60 days… just allow it and have a function that normalizes it. It just spills the days into next month. It’s very easy to do calendar math this way, as you can overflow calendar fields for a short time. C. You need to make the user aware of timezone files. On some OSs there is a location where you can get timezone information that is up to date, but that is not the case on Windows and JS-Browser mode. That is why I provide a way to generate timezones from the source and ship them with your JS or native app. It’s an important feature for me. D. Adding a timezone to a calendar is complex. There needs to be two functions … I call apply and shift. Both functions will make your calendar have the new timezone offset. applyTimezone: "1970-05-23T21:21:18Z" -> "1970-05-23T14:21:18-07:00" shiftTimezone: "1970-05-23T21:21:18Z" -> "1970-05-23T21:21:18-07:00" Run But apply will not shift your time stamp, while shift will.
Re: New blog, with some Nim articles
Having written a fair amount of Assembly, it's kind of hard to optimize. Most optimizations are done with taking a different approach to solve your problem and not some cleaver SIMD instruction, in fact a random single SIMD can really slow down your code... I think this is what Nim does really well because of template and macros you can try a ton of different approaches and see what fits best. I love optimizing stuff.
Re: Nim support for CodeRunner app
Nice! Good job. We need Nim in more places.
Re: New blog, with some Nim articles
You can use my quote, but I don't think "optimization walls" will be understood by most people.
Re: Some week-of-year procs for use with the times library
I like this I have weekday, but I don't have week of the year in my library, I should add it. [https://github.com/treeform/chrono/blob/master/src/chrono/calendars.nim#L224](https://github.com/treeform/chrono/blob/master/src/chrono/calendars.nim#L224)
Re: help call string ??
I can see some thing like Glade needing this. I will be interested to see it when you have some thing to show.
Re: Sorting JSON data by a specified field
Unrelated "id":"582090251837636960" gives me flash backs on how JS can't store large numbers. I like making IDs ascii characters so that people don't accidentally parse them and have pain. Speaking for personal experience.
Re: help call string ??
One way to do that is to add them to some sort of structure like a hash table: [https://play.nim-lang.org/#ix=2m18](https://play.nim-lang.org/#ix=2m18) import tables var calls: Table[string, proc()] proc hi() = echo "hi" proc bye() = echo "bye" calls["hi"] = hi calls["bye"] = bye let s = "bye" calls[s]() Run Nim is not a dynamic language so you kind of have to implement/fake dynamic language features. Why do you want todo that? There might be better static and idiomatic ways to accomplish what you want.
Re: New blog, with some Nim articles
Nice! I feel like its blog posts like you that get Nim out there and more popular. Thank you! Your points about private access are really good, instead of saying undeclared identifier or function it should say trying to call or access a private identifier or function. Would be great improvement! "Performance is typically on par with, or slightly trailing, C." Performance always depends on how well you write it. It's a topic I really like! One can write super slow Nim as well as super slow C. But I think nim offers is "no boundaries." In languages like python/js you are kind of just stuck. Having optimizing python/js you kind of hit a barrier where you can't go any further. And it sucks. I feel with nim, there is no barrier. You can always go faster! Slow? Try fancy C/C++ profilers like vTune. Figure out your bottleneck? Try ref vs regular objects, try arrays vs seq, try pointer arithmetic, disable array bounds checks, disable stack traces etc... you can always try faster and faster. Even crazy things like compute shaders or CUDA are available to you. It's not that Nim is fast, it's that Nim does not have "optimization walls." This always allows you to be faster.
Re: A good word for idiomatic nim?
nimatic
Re: Making 4k intro with Nim
I really liked the write up. Thank you for this!
Re: Typography update - now it can render 99% the Google Fonts ttf.
Kerning already supported ... text would look broken without it. glyph composition and rtl/ttb/btt - I don't support that now, but I want to support it eventually. Hebrew and Arabic are the only major rtl languages I want to support. Almost no one uses ttb/btt in computer UIs, CJK use it in signage and books though. Even traditional Mongolian which is hard ttb is replaced by Cyrillic letters on computers. Doing boustrophedon direction could be fun... but probably just as pointless as Egyptian hieroglyphs pointing their heads in correct orientations.
Re: Typography update - now it can render 99% the Google Fonts ttf.
Rmarkdown looks cool. But I think you might want to use a different tool to generate PDFs... they already support fonts! My plan is to use this for my UI framework called fidget ( [https://github.com/treeform/fidget](https://github.com/treeform/fidget) ). It turns out UI's are like 80% fonts by difficulty.
Typography update - now it can render 99% the Google Fonts ttf.
When I started typography ( [https://github.com/treeform/typograph](https://github.com/treeform/typograph) ) with an aim for writing a full font and typography engine from scratch, I did not know much about fonts. I did not know what I was getting into, its been quite a journey. At first it could only render SVG Fonts but over time I added TrueType support and fixed issues with fonts I found. Most of the time stuff would break because a font feature was not supported. But I think I reached a new milestone where I can render most of the Google Fonts ( [https://fonts.google.com](https://fonts.google.com)/ ). Which means any font your find will probably work as well. I just had to share! Check out the output of the test here: [https://github.com/treeform/typography/blob/master/tests/samples/google.md](https://github.com/treeform/typography/blob/master/tests/samples/google.md) Thanks!
Re: Introducing --gc:arc
Is there a way to disable automatic tracing runs of --gc:orc and only run them when we want to -- say between rendering frames or loading levels? Is there a way to limit the time the tracing step runs? You can pass --gc:arc refs between threads right? Which thread does --gc:orc run on?
Re: What's the most favourable way to get documentation as an automated process?
nim jsondoc -o:doc.json I use this for [https://github.com/treeform/mddoc](https://github.com/treeform/mddoc)
Re: Iterate over fields
Field fieldPairs are great! I use it to print arbitrary structures and deserialize json in a more looser way: [https://github.com/treeform/print/blob/master/src/print.nim#L79](https://github.com/treeform/print/blob/master/src/print.nim#L79) [https://github.com/treeform/jsutils/blob/master/src/jsutils/jsons.nim#L28](https://github.com/treeform/jsutils/blob/master/src/jsutils/jsons.nim#L28)
Re: how to properly release memory?
Short answer you can't. Nim will keep the free memory for itself in case it needs to use it. Many libraries have a way to supply it a memory allocator: [https://github.com/nim-lang/Nim/blob/version-1-2/lib/wrappers/openssl.nim#L495](https://github.com/nim-lang/Nim/blob/version-1-2/lib/wrappers/openssl.nim#L495) [https://forum.nim-lang.org/t/4932](https://forum.nim-lang.org/t/4932)
Re: String constant concatenation
And an "I agree with Araq" button.
Re: Calling C function causes Sigsegv
I have wrapped plenty of C programs with Nim. My experience is that sig faults are caused by some thing simple ... like me not understanding the parameters. An equivalent C program should crash with a sig fault there too. I bet BASS_Init(-1, 44100, 0, 0, nil) would crash in C as well.
Re: Nim 1.2 is here
Yes! Thank you everyone who contributed!
Re: Idea: Nim Online Conference
Yes [https://github.com/treeform/orbits](https://github.com/treeform/orbits)
Re: Idea: Nim Online Conference
Twitch is probably the best place to stream things... then archive on Youtube. I can give a presentations on following topics: * Fidget Library and Desktop/Web UI programming. * Chrono Library and everything related to calendars and timezones. * Typography Library and everything about fonts. * Chroma Library and color theory. * Game programming with Nim. * Orbital Mechanics with Nim.
Re: upperBound/lowerBound in algorithm O(log n) or O(n) ?
Yes shr 1 is divide by 2. It looks like the function does what you would except at O(log n). But... The O(log n) stuff works in theory, but in practice memory access and cache hotness have bigger impact on performance. I don't think it's that useful to specify this. [http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html](http://www.brendangregg.com/blog/2017-05-09/cpu-utilization-is-wrong.html) Always measure! The main thing I like about Nim is that I can always make some thing faster... there are no limits. But you got to measure!
Re: ways to comunicate between different application
You only need one socket to communicate between python and nim.
Re: (Meta) Why is there no beginners' section in the forum?
Arn't we all beginners? I prefer category-less forum.
Re: Help prlm this Time
I think the problem is that the strformat's fmt macro is not good enough to realize that date format is not part of it's format. So it gets confused. That is why you get the error: : could not parse `a.Data.format("HH`. Run I recommend doing what you already done: """ "{h}" """ Run Format your date into a string variable, include the string in your final format.
Re: Nim for Beginners Video Series
Nice!
Re: Documenting one liner
Well its not 1 line any more? I would just make it 3 lines :) proc createMap(this: VS):ptr VSMap = ## Creates a new property map. It must be deallocated later with freeMap(). this.vsapi.createMap() Run
Re: Async web servers and database
Also don't forget mine! [https://github.com/treeform/pg](https://github.com/treeform/pg)
Re: Bug with makeNimstrLit on JS backend
You can't emulate Nim's strings which are mutable and utf8 with JS strings which are immutable and utf16. So instead Nim uses JS array of integers acting as bytes (0 to 255) to implement strings. JS strings have a ton of crazy properties which Nim strings don't have. See [https://mathiasbynens.be/notes/javascript-unicode](https://mathiasbynens.be/notes/javascript-unicode) But some times using JS strings in JS compile mode is useful I have defined some methods to make it easier and faster: [https://github.com/treeform/jsutils/blob/master/src/jsutils/strings.nim](https://github.com/treeform/jsutils/blob/master/src/jsutils/strings.nim)
Re: Templates and imports
Hmm, I think it always worked like this. Template just substitute code. If the code where you have template can't access some thing... then it's an error. It also is an error if template calls a private proc: proc b() = # private b echo "hi" tempalte a*() = # public a b() Run Calling a() in another module will not work because b() is private.
Re: How to get Nim running on iOS and Android using GLFM.
It looks like your wiish project is exactly what I want! I am working on my own UI thing called fidget ( [https://github.com/treeform/fidget](https://github.com/treeform/fidget)/ ) - my long term goal is to make fidget just work on Android and iOS, just like it does on Win/Mac/Linux and Web now. I'll be looking at your thing very closely. Thank you for doing this.
Re: I have a super doubt
I also would recommend Kiloneie's videos: [https://www.youtube.com/watch?v=5tVIsDYPClA](https://www.youtube.com/watch?v=5tVIsDYPClA) They start with the very basic and work up.
Re: How to package a nim program in an APK file
Can you compile your apk with Android studio without docker? Does it run? I would try docker approach after I got that to work.
Re: Paranim and Pararules - my new gamedev libraries
Looks cool!
Re: Nim Community Survey 2019
Nice, thank you for the write up!
Re: RayCasting Problem
Oh I diffed the two files and found the error: [https://dl3.pushbulletusercontent.com/XulFI2T1reCunTVRZEXwGlORRV28pdXi/image.png](https://dl3.pushbulletusercontent.com/XulFI2T1reCunTVRZEXwGlORRV28pdXi/image.png) You have one important "(" in the wrong place.
Re: RayCasting Problem
Here is your exact code fixed: [https://gist.github.com/treeform/bb3f4618d24535590043e264825f350d](https://gist.github.com/treeform/bb3f4618d24535590043e264825f350d) I recommend using getKeyboardState() like I did, other wise it moves only on key repeats.
Re: RayCasting Problem
I am pretty sure Nim's sin() and cos() work exact same way as the C++ ones. I never had an issue with them working differently. I think error is some place else. Some thing I noticed: * you use uint32 for time while C++ uses double. * you hard code w to 640 while C++ does not. * your right and left key is flipped from the C++ code. * C++ article warns about the problem you hare having. * you are doing one extra line should be 0 ..< 640 not 0..640 running your code i get: (61, 29) Error: type mismatch: got but expected 'array[0..3, int32]' I switched to using .byte for color values. I switched to using w and h like C++ code. I can't find the issue in you code, ... but I did my own C++ to nim conversion and it works without issues: import sdl2 import math var worldMap =[ [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1], [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1], [1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ] proc main() = var posX: float = 22 # x and y start position posY: float = 12 dirX: float = -1 # initial direction vector dirY: float = 0 planeX: float = 0 # the 2d raycaster version of camera plane planeY: float = 0.66 time: float = 0 # time of current frame oldTime: float = 0 # time of previous frame w = 680 h = 420 window = createWindow("NIM RayCasting", 100,100,cint w,cint h, SDL_WINDOW_SHOWN or SDL_WINDOW_OPENGL) render = createRenderer(window, -1, Renderer_Accelerated or Renderer_PresentVsync) evt = sdl2.defaultEvent runGame = true while(runGame): render.setDrawColor(0,0,0,255) render.clear() for x in 0 ..< w: # calculate ray position and direction var cameraX = 2 * float(x) / float(w) - 1 # x-coordinate in camera space rayDirX = dirX + planeX * cameraX rayDirY = dirY + planeY * cameraX # which box of the map we're in mapX: int = int(floor(posX)) mapY: int = int(floor(posY)) # length of ray from current position to next x or y-side sideDistX: float sideDistY: float # length of ray from one x or y-side to next x or y-side deltaDistX = abs(1 / rayDirX) deltaDistY = abs(1 / rayDirY) perpWallDist: float # what direction to step in x or y-direction (either +1 or -1) stepX: int stepY: int hit = 0 # was there a wall hit? side: int # was a NS or a EW wall hit? # calculate step and initial sideDist if rayDirX < 0: stepX = -1 sideDistX = (posX - float(mapX)) * deltaDistX else: stepX = 1 sideDistX = (float(mapX) + 1.0 - posX) * deltaDistX if rayDirY < 0: stepY = -1 sideDistY = (posY - float(mapY)) * deltaDistY else: stepY = 1 sideDistY = (float(mapY) + 1.0 - posY) * deltaDistY # perform DDA while hit == 0: # jump to next map square, OR in x-direction, OR in y-direction if sideDistX < sideDistY: sideDistX += deltaDistX mapX += stepX side = 0 else: sideDistY += deltaDistY mapY += stepY side = 1 # Check if ray has hit a wall if worldMap[mapX][mapY] > 0: hit = 1 # Calculate
Re: Why does `k in t.keys.toSeq.sorted` works but `k in t.keys.toSeq.sorted()` does not.
Thanks! I am glad the explanation exists.
Why does `k in t.keys.toSeq.sorted` works but `k in t.keys.toSeq.sorted()` does not.
import tables, sequtils, algorithm var t: Table[int, int] # this works: for k in t.keys.toSeq.sorted: echo $k # this does not? for k in t.keys.toSeq.sorted(): echo $k Run A very strange error in the second case: Error: undeclared field: 'keys' Run Is this some sort of iterator/macro bug or a feature? [https://play.nim-lang.org/#ix=2c4I](https://play.nim-lang.org/#ix=2c4I)
Re: Threadpool slower than single-core
\--d:danger just does all of the possible optimizations.| ---|--- I use --threads:on and when compileOption("threads"): to include or not include threadpool. See line 3: [https://play.nim-lang.org/#ix=2bFk](https://play.nim-lang.org/#ix=2bFk)
Re: Threadpool slower than single-core
I don't think threads run slower in my case. I changed your program slightly to support threads and non threads: [https://play.nim-lang.org/#ix=2bFk](https://play.nim-lang.org/#ix=2bFk) nim c -d:release -d:danger --threads:on "/p/tmp/prisoners.nim" time ./prisoners Succs: 311894 Fails: 688106 Total: 100 Success Rate: 31.1894%. Succs: 0Fails: 100 Total: 100 Success Rate: 0.0%. real0m8.288s user0m15.779s sys 0m0.008s Run nim c -d:release -d:danger "/p/tmp/prisoners.nim" time ./prisoners Succs: 312323 Fails: 687677 Total: 100 Success Rate: 31.2323%. Succs: 0Fails: 100 Total: 100 Success Rate: 0.0%. real0m11.459s user0m11.452s Run Threads took 8s while non threads took 11s. Threads are faster. I only have two cores on this linux box so speed it was not that huge. Some thoughts: This code does call toSeq inside for loops for optimal speed there might be a way to allocate it only once and reuse it per thread. You are using random numbers ... randomness might be causing different runs take different times. You are using a global random which might not work great when accessed from different threads.
Re: Threadpool slower than single-core
I think your problem might come from: * trying to do too little work per thread - so thread stuff eats up all the time. * trying to write same cache line from multiple threads. * too much blocking
Re: Idiomatic sequence functions
Its [0 ..< 5] You want slicing: [https://narimiran.github.io/nim-basics/#_indexing_and_slicing](https://narimiran.github.io/nim-basics/#_indexing_and_slicing) See here: [https://play.nim-lang.org/#ix=2bFa](https://play.nim-lang.org/#ix=2bFa)
Re: Parallel example for computing pi efficiently is actually slow
It uses threads to do very little amount of work: 4 * math.pow(-1, k) / (2*k + 1) ... creating a thread is a very heavy weight operation, while doing little math is really easy. So most of the time is spent doing thread bookkeeping. Your computation needs to justify running it in a thread ... which this does not as its just an example for parallel not an efficient implementation.
Re: Nim problems. 1 internal, 1 mine
-Werror Is not useful for nim generated code. Warnings are for humans not compiler output. Nim compiler will do a ton of unsafe things in C because they are actually safe in nim. No one is going to spend time fixing auto generated warnings... thats not what warnings are for! See: [https://forum.nim-lang.org/t/5785](https://forum.nim-lang.org/t/5785) "about 1 GB/s slower" \- Its our favorite pastime to beat C code at speed. No seriously not sarcastic! Post minimal version of your code please and we will make it fast... Did you compile -d:realse or -d:danger? You probably can't pass ref object`s to C and it should probably be `ptr object? I don't think nim is copying your objects, but it might be your code. Post it!
Re: Change server name in Jester
[https://serverfault.com/questions/925892/does-it-makes-sense-from-a-security-perspective-to-remove-the-server-http-header](https://serverfault.com/questions/925892/does-it-makes-sense-from-a-security-perspective-to-remove-the-server-http-header) > Though in practice, attackers don't really check the Server: header. They > just try every security exploit they know of, whether your server gives any > indication of being vulnerable or not. Removing the Server: header is a > security by obscurity action, and an almost entirely ineffective one. But if > it makes you feel better, or you're being told to do it by your boss or an > auditor, go for it. Just don't expect it to result in any significant > improvement to your security posture.
Re: Change server name in Jester
If you use httpbeast, its part of the serverInfo constant defined here: [https://github.com/dom96/httpbeast/blob/master/src/httpbeast.nim#L50](https://github.com/dom96/httpbeast/blob/master/src/httpbeast.nim#L50) and used here: [https://github.com/dom96/httpbeast/blob/master/src/httpbeast.nim#L333](https://github.com/dom96/httpbeast/blob/master/src/httpbeast.nim#L333) You could always fork httpbeast and replace that line. "As a security measure it is advisable to hide the server name." \- Never head about that. I can see how it can help in theory, but ... feels like grasping at straws.
Re: SslError: ssl3_write_pending:bad write retry
You need to do some digging. What version of ssl do you have installed? Do you have multiple ones? Is it libressl or openssl. Nim claims to support all versions, but it's not quite true... Openssl team and dev practices make compatibility really hard.
Re: SslError: ssl3_write_pending:bad write retry
Oh and are you using some library that might have it's own openssl needs like curl, postgress, MySQL, crypto... ?
Re: Status status update ;) libp2p, etc
Thank you Status.
Re: How to refer to a dynamically determined array
I would use not use array for this but pointer and pointer arithmetic. I also did this for leaning purposes, and learned that pointers are easier.
Re: FOSDEM 2020 - Brussels February 1st & 2nd
Are we going to meet up some place on Feb 1?
Re: FOSDEM 2020 - Brussels February 1st & 2nd
I am coming, hold the door for me!
Nim will silently auto convert a float64 to a float32 and loose precision... is that good? Thoughts?
I get why float32 can auto convert to float64... there is no loss in precision. But its strange to me that reverse is also true. Nim will auto convert a float64 to a float32 and loose precision!!! Silently! This is not true for ints. Here it states so in the manual: [https://nim-lang.org/docs/manual.html#type-relations-convertible-relation](https://nim-lang.org/docs/manual.html#type-relations-convertible-relation) var a: float64 = 20e-70 b: float32 = a c: float64 = b echo a echo b echo c Run Output: 2e-69 0.0 0.0 Run You can see here we had float64 of 20e-70 go through an intermediate float32 that rounded it, so that the next float64 was 0. My fear that its easy to have a random float32 in your code that is basically a rounding function. And you will never know! Thoughts? Why was it done like this? Do you guys think this is good? Does it matter? Can't change now because too much code depends on it?
Re: [C++ coroutines] in GCC
I was excited about this till I read this: [https://news.ycombinator.com/item?id=22090942](https://news.ycombinator.com/item?id=22090942) If the author is to be believed its just a transformation that is applied to the code. Basically the same transformation that we do with async/await already. Now if this was like go-style coroutines I would be a lot more excited.
Re: Impossible situation trying to get minimal glfw example working±±±
Users were running into this issue when they were trying to use fidget because it uses glfw. I decided to make a static version of glfw that does not require a finding dlls. Here it is: [https://github.com/treeform/staticglfw](https://github.com/treeform/staticglfw) . If you use this lib instead you and your users would not need to install any dlls.
Re: Who would I implement simd to do fast md5 checksums ?
How I would go about it: * Figure out which version/instruction set of SIMD you want. If you are making it for games steam survey can help: [https://dl3.pushbulletusercontent.com/5DQdDCVmL67PvSH3bY4uzzWIf6ZxwLHW/image.png](https://dl3.pushbulletusercontent.com/5DQdDCVmL67PvSH3bY4uzzWIf6ZxwLHW/image.png) if you run your own server you can just see what it supports. Most people write different paths for each SIMD set they want to support. * Find a C example of what you want. Like this one for example for SSE: [https://github.com/crossbowerbt/md5/blob/master/md5_sse.c](https://github.com/crossbowerbt/md5/blob/master/md5_sse.c) or AVX2: [https://gist.github.com/mniip/220ba4aa1907c7887a34](https://gist.github.com/mniip/220ba4aa1907c7887a34) * Decide if you want to wrap the C library or reimplement it in nim. Both are valid. * Have fun! Always Benchmark! Note: your compiler might already do SIMD and you might not be able to beat it by writing your own what basically is assembly. Always Benchmark!! Note: if you use SIMD just for that one thing they take a while to "startup" as current in the CPU has to be shifted to power a new area in the CPU. Having a couple of random SIMD instructions in your otherwise non-SIMD program might actually make it way slower. Always Benchmark!!!
Re: Ported a Python game to Nim
Wow that looks really good!
Re: [vscode] Anyone willing to share his tasks.json needed to build nim files?
I just right click and "Run selected Nim file" or F6. From then on I do press "up" and "enter" in the console that opens. Why do you need tasks? What advantages do tasks have? Never used them.
Re: Nim to JavaScript compile: function ref
Some thing like this probably? type UnderlayCallback = proc(canvas: Element, area: Rect, g: SomeGType) Run
Re: Goto based exception handling
Hey so I ran more benchmarks. Impressive!type| Ubuntu GCC| Mac LLVM| Windows VC++ ---|---|---|--- C++| 8043.0| 6185.0| 8908.2 goto| 8936.0| 6336.2| 8685.0 setjmp| 10214.4| 7242.0| 10492.6 Ubuntu GCC Intel(R) Xeon(R) CPU @ 2.30GHz gcc version 7.4.0 C++ RunningStat( number of probes: 5 max: 8373.0 min: 7835.0 sum: 40215.0 mean: 8043.0 std deviation: 204.5238372415303 ) goto RunningStat( number of probes: 5 max: 8955.0 min: 8930.0 sum: 44680.0 mean: 8936.0 std deviation: 9.570788891204304 ) setjmp RunningStat( number of probes: 5 max: 10319.0 min: 10178.0 sum: 51072.0 mean: 10214.4 std deviation: 53.23758071137343 ) Run Mac LLVM 2.6 GHz Intel Core i7 Apple LLVM version 10.0.1 C++ RunningStat( number of probes: 5 max: 6393.0 min: 6030.0 sum: 30925.0 mean: 6185.0 std deviation: 127.5476381592383 ) goto RunningStat( number of probes: 5 max: 6486.0 min: 6230.0 sum: 31681.0 mean: 6336.2 std deviation: 95.63764949014589 ) setjmp RunningStat( number of probes: 5 max: 7439.0 min: 6989.0 sum: 36210.0 mean: 7242.0 std deviation: 145.2391131892507 ) Run Windows VC++ Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz Microsoft (R) C/C++ Optimizing Compiler Version 19.23.28107 for x64 C++ RunningStat( number of probes: 5 max: 9667.0 min: 8447.0 sum: 44541.0 mean: 8908.2001 std deviation: 430.4074348800213 ) goto RunningStat( number of probes: 5 max: 9261.0 min: 8481.0 sum: 43425.0 mean: 8685.0 std deviation: 290.22542962325 ) setjmp RunningStat( number of probes: 5 max: 10625.0 min: 10419.0 sum: 52463.0 mean: 10492.6 std deviation: 73.94754897898915 ) Run
Re: Game unlock gui written with gintro
Nice!
Re: Sqlite: unfinalized statements error
stbalbach, I been doing SQL for 15 years. I still use the command-line utility to test queries before moving them into code.
Re: Write Nim by using only 'v'
You sir, are a God among men.
Re: Simple excel/xlsx reader, support some basic operators.
Nice! It's libraries like this make a language "batteries included". Good job.
Re: which XML parser is recommended?
It looks like xmlparser uses parsexml. I think it boils down which API is more convenient for your use case. Probably xmlparser. If you have a choice use JSON.
Re: Tables or seq
I don't think any one can help with this. Performance issues are usually very surprising. Its almost never as simple as use seq instead of table. You need to profile your code. Find the hot paths and try to optimize them a way. Here are some tips on writing fast code: * Have an open mind - performance issues usually happens in the least places you expect. Don’t jump at the code with “oh that looks slow”. It probably isn't the problem. * Profile your code. Measure! Measure! Measure! Put little this function took N seconds if you don’t want to invest in learning a profiler. * Maybe even write little benchmark scripts that just test important parts of your program - sort of like unit tests. * Maybe an earlier version of your program ran fast, and something has made it slow recently, you can try looking at the changes. Some functions will be way more time than other functions. That is your hot path. You should only focus on things that are slow. Only after you have identified your hot path you can fix it. Only after you measure you can get into figuring out the problem: * Are your for loops slow? Sometimes a better algorithm can just be faster. If you are looping over objects many times … maybe a better access pattern would help such as a hash table? Be wary of repeating work over and over again. Be wary of linear scans and nested for loops. * Can a simple cache help? Everything in computer runs on caches there are caches everywhere: RAM, Hard Drive, HTTP, DBs… why shouldn't your code be any different? * Is an external part that is slow? Querying a DB, reading files, or making http requests? * Are object allocations and deallocations slow? Instead of creating a ton of ptr objects try creating an array of “non ptr” regular objects so that memory can be contagious. * Are you converting a ton of string numbers to real numbers and back to strings? Always measure before and after the change. Even after you made a change, and think its faster, it might not be. Measure! Measure! Measure! After fixing your hot path and it becomes fast, now another piece of code would be the slowest one. Try fixing it next.
Re: Object Variants and redefinition of labels or reusbility of field names
I would just create 26 different types and make conversions between them? There is no need to stuff everything into a single type... I do this with Chroma: [https://github.com/treeform/chroma](https://github.com/treeform/chroma)
Re: How to check if a proc has no return type?
You can use the compiles special function to do a ton of this work: [https://play.nim-lang.org/#ix=25sG](https://play.nim-lang.org/#ix=25sG) proc echo2(s: string): string = "" template returnsVoid(f: untyped): bool = compiles: let v = f echo returnsVoid(echo(":)")) echo returnsVoid(echo2(":)")) Run false true Run
Re: Introducing --gc:arc
Thank you for this Christmas present.
Re: How to set a specific file as main file in VS Code ?
Same. I have both run.sh and run.bat for windows or posix dev.
Re: How to use private variables when you put all types in one module
I don't think private variables on structs are worth it in general. I almost make everything public by default. I don't export low level functions though...