Well, I'm not been active here or in #nim on freenode lately, but I've been using Nim a lot at work.
I'm on a new project (rather significant one), and I decided to do a majority of the new software required by it in Nim.
Tried to do one component in C++, as it required a lot of posix stuff, and Nim's is not complete.... but eh... After about 900 lines of working C/C++ code I rewrote it all in Nim (line by line translation, much of it was just syntax cleanup).
The parts not there, I left those in C and called those parts from Nim, or I just made do with what was there with casting. So far so good.
I just got tired of fighting C/C++'s lack of modularity, namespace leakage. C++11 and newer make up for quite a few deficiencies, but meh... Nim is just so much better to program in... (stack traces, proper modules, metaprogramming, etc).
I had been using Mako (python) quite a bit for ansible templates, but a couple months ago I switched them all over to Nim's source code filtering. Everything I was doing in Mako, I can do with Nim's source code filtering, and I don't have to put up with Python's dynamism that catches stuff very late in the game. (for python code in the template file).
There is a bit of a risk using Nim at work, but there is also risk in not using it. When I look at Swift, I don't see what it has to has offer (apart from a very good REPL) that I don't have in Nim, but in a curly brace style. (Python got me use to the indentation style, which I hated at first, but now I prefer it). Rust, go, D, while better in many regards than C++11 (and newer) fall short in a lot of areas when it comes to programmability for me.
Posix *(well, I guess these are not strictly posix)* issues I ran into:
And maybe a few other items... Of course those are all able to be worked around, especially since it so easy to mix C with nim.
Overall Nim has been a joy and I've been very productive with it at work. I hope to be using it long term at work, especially if I can get others to start using it.
I looked at Crystal some, but I prefer Nim over it. If anything for the syntax, but there are other considerations as well.
That's great to hear. Thank you for sharing your experiences, it's very exciting to see Nim being used in a professional setting!
Posix (well, I guess these are not strictly posix) issues I ran into
Please create a PR for these issues if you can, I would love to include these procedures/constants in the posix module for others to use.
Ok, I'll need to move the definitions/code to pure nim first and get them working that way. Some of these may not be available on all posix systems. Right now I'm just targeting Linux for the code that uses those, but I'll be targeting MacOS X as well.
Oh, I really like it how one can use nim compiled for one platfrom to compile code for other platforms, by specifying the correct OS and making sure the correct cross compiling C compiler is in your path first. Doing this I was able to from Linux successfully build Linux, Windows, and MacOS X executables. That is very cool.
Alright, this is what I got working for the posix stuff:
{.passL: "-lutil".}
var SIGWINCH* {.importc, header: "<signal.h>".}: cint
var TIOCGWINSZ* {.importc, header: "<termios.h>".}: cuint
var TIOCSWINSZ* {.importc, header: "<termios.h>".}: cuint
proc openpty (amaster, aslave : ptr int, mustBeNil : pointer, termp, winp : ptr Termios) : cint {.importc, noDecl, header: "<pty.h>".}
proc forkpty (amaster: ptr int, mustBeNil : pointer, termp, winp : ptr Termios) : cint {.importc, noDecl, header: "<pty.h>".}
I need to the put what will make {.passL: "-lutil".} happen in the importc pragmas for openpty and forkpty, but I'm not sure how to do that. dynlib did not do it.
With the above I was able to port the remaining C functions to Nim.
As far as SigVal not having sival_int an only having sival_ptr, here was my workaround:
# for inserting:
var si_value:SigVal
si_value.sival_ptr = cast[pointer](myvar)
let rc = pid.sigqueue (SIGUSR2, si_value)
# for extracting:
proc handler (signal:cint, si: var SigInfo, context:pointer) {.noconv.} =
let myvar = cast[mytype](si.si_value.sival_ptr)
Where mytype objects are pointer sized or smaller, in my case I'm using an enum type. I guess because of that, I don't really see the need to support sival_int directly in Nim.
Should something like this be included in the PR?
Here is what is says currently:
SigVal* {.importc: "union sigval",
header: "<signal.h>", final, pure.} = object ## struct sigval
sival_ptr*: pointer ## pointer signal value;
## integer signal value not defined!
On a different note, why were these renamed?
Due to case insensitivity they worked without the camelcase. The reason I initially thought they were missing was I could not find them in the documentation.
readlink was not renamed to readLink, setgid to setGid, etc, so I don't really see a point in renaming the aforementioned.
So, when I do a PR, I'll need to add the proper docstrings, for the new ones above as well.
Well, strictly speaking, these are not Posix.
From the Linux man page:
ATTRIBUTES
For an explanation of the terms used in this section, see attributes(7).
┌─────────────────────┬───────────────┬────────────────────────┐
│Interface │ Attribute │ Value │
├─────────────────────┼───────────────┼────────────────────────┤
│forkpty(), openpty() │ Thread safety │ MT-Safe locale │
├─────────────────────┼───────────────┼────────────────────────┤
│login_tty() │ Thread safety │ MT-Unsafe race:ttyname │
└─────────────────────┴───────────────┴────────────────────────┘
CONFORMING TO
These are BSD functions, present in glibc. They are not standardized in POSIX.
So, not sure if the posix module is the correct place to add these, even though they are present in glibc on linux.
I tried musl as well, with it the {.passL: "-lutil".} is no longer needed.
On a different note, why were these renamed?
IMHO it's all the others which could be renamed to adhere to NEP-1.
So, not sure if the posix module is the correct place to add these, even though they are present in glibc on linux.
We also have a linux.nim module for Linux specific stuff.
In regard to where these should go.
We also have a linux.nim module for Linux specific stuff.
Well, these came from BSD. I will check if these are are available on Darwin as well, as I will also be targeting MacOS X.
CONFORMING TO
These are BSD functions, present in glibc. They are not standardized in POSIX
What I'm getting at is that there is lot of commonality in regard to what is available on both BSDs and Linux, that is not strictly posix.
IMHO it's all the others which could be renamed to adhere to NEP-1.
OK