Re: Installing Nim to non-standard directory
> you clone/download to a location and build in place. That's what I thought. That's a problem for enterprise software.
Re: Installing Nim to non-standard directory
Koch is the official tool to build and "koch boot" is the command. Details here: [https://github.com/nim-lang/Nim#compiling](https://github.com/nim-lang/Nim#compiling) You don't install _to_ somewhere, you clone /download to a location and build in place.
Re: Installing on Windows issues
What's the actual path set in settings? Both the current user and the global path? And what's the Nim directory location? What's the output from finish.exe?
Re: Total noob, statically allocated circular buffer on microcontroller question
Hey! [This](https://github.com/notTito/nim-100days/blob/master/structures/ringbuffer_concurrent.nim) could be what you want.
Installing Nim to non-standard directory
I don't see "install.sh" anymore. I think I need to run "niminst", but "koch tools" does not build it. How do I build niminst? Or better: How do I install Nim to a non-standard directory from a source build? "nim-install my-directory" I'm sure there is a doc-page I've missed.
Re: Installing Nim to non-standard directory
I found "tools/niminst/niminst". (Not sure when/how I built that.) But how do I use it? * [https://nim-lang.org/docs/niminst.html](https://nim-lang.org/docs/niminst.html)
Re: Statistics for standard library usage
Adding a short opinion regarding what should be in the standard library for v1.0. Keep in mind my background is mostly python, however, I'm still a newb with Nim. One of Python's selling points is the large standard library that is distributed. But one of it's flaws, however, is that it only has two levels of libraries: * Standard Libraries * All external libraries (PyPi) That means if needed library is not in standard, it is _very_ non-obvious which competing library is a good one. One has to hunt-around the similar libraries and try to get a "general impression" and hope you are right. Looking at repo update traffic helps, etc. My recommendation for nim: Standard Library: These are libraries installed with the compiler itself. Always available. * Keep it large * but if a lib is not ready to be "frozen" to v1.0, keep it out; you can always easily add it in later. But change becomes problematic once it is distributed with the compiler. * Do not allow libraries dependent on external software projects. So, remove "db_postgres" and "db_mysql", for example. These can, potentially, change too fast for a standard lib. Dependencies on external protocols (such as http) are okay, however, as they change more slowly. Nimble Libraries: * Eventually add a website and server system to gather stats; it should use the JSON distribution (not replace it.) * Helps create consensus. * Possibly add forums for packages * Add **voluntary** collection system to nimble that sends a "I just installed this" to that server to help with stats. ...and, something not seen elsewhere, a possible third category... Nimble Canonical: This is a list of libraries "highly recommended" by the nim-lang developers. * Could be a single "nim-canon" distribution package on some OSes. Otherwise, requires nimble. * This is where libraries pending "standard lib" are placed. * perhaps all repo'd at something like github.com/nim-canonical * Part of the point is to focus developer attention Just ideas... BTW, I've toyed with the idea of arbitrarily creating the nimble website; as I would have found it useful myself. But I don't want to step on anyone's toes.
Re: Total noob, statically allocated circular buffer on microcontroller question
That's perfect. Thank you.
Re: Total noob, statically allocated circular buffer on microcontroller question
Thank you for the reply. My concern was that the method has the N generic parameter in it. Does the compiler just figure that out and so the usage is as simple as something like: #--- circBuffer.nim import ringbuffer var myBuf*: RingBuffer[N: 8, T: uint8] proc someProcess*() = #some stuff myBuf.add(0x03) #--- main.nim import circBuffer proc main = while true: circBuffer.someProcess() circBuffer.myBuf.add(0x04) Stefan, I think I can access all the registers. I'm in the early stages. I did start off with that repo, but have modified it quite a bit. There was a problem with the header file for the device and it was making zero initialized pointers to registers, I think. The bss section had a bunch of symbols that were meant to be the same as #defined pointers to memory locations. I haven't committed it or anything yet as I'm not very far along. Basically I got it to compile, read the assembly to see that it was doing what I wanted, particularly in regards to an interrupt routine, and then loaded it onto the board and made sure nothing exploded. There's not even a blinking light yet. The assembly looks good except that the entry into my main routine has several steps. It goes from a main routine, which calls a NimMain() routine, which then calls my main, main_818410831058, which loops in place. That seems unnecessary to me, but not a huge deal I guess. I am using the MSPGCC compiler, which I think is intentionally neutered as they want you to buy their compiler. The assembly looks good though. Accessing the P2IV register looks correct in the assembly. I don't know how to force Nim to tell the C compiler to make a jump table, which is what I would do. There are compiler intrinsics for that sort of thing, so I could use the FFI. The number of options is limited and a case statement would only have to handle powers of 2. As for garbage collection... at my workplace we don't use any dynamic memory allocation. Everything is statically allocated. We don't make products that are classified as "safety critical" but they are high reliability devices and there is liability if a device doesn't work when it's supposed to. Static allocation makes sense for many of the embedded systems that I work on at least. Everything is bare metal. It seems like the concerns in the embedded world are quite different from those of the PC world. That's alright though. I'll slog away at it with some help from kind people like you and then there will be more information out there for the masses. I might even try and resurrect my blog haha. Also, allocating memory on a heap is non-deterministic I think in terms of time. That makes it harder to reason about systems in which I literally have to count cycles sometimes to meet execution deadlines. Also, I was talking to a coworker about the nature of special function registers. In C, the macros for registers in the header files expand to dereferences of pointers to volatile memory. Nim has the volatileLoad and volatileStore functions instead. I'm not sure how I feel about that. I think I like it better actually. Time will tell. Maybe I just don't know about it, but the option of using the language features that use the heap like seq but in a statically allocated memory way would be nice. It would just prevent the memory allocated for the seq from being resized.
Re: [RFC] Adding @ prefix (or similar) to import
Oh, probably. I thought that by "attach" you mean: type Shape {.inheritable.} = ref object ... area: proc(Shape): float type Square = ref object of Shape ... proc newShape(...): Shape = ... area = areaShape proc newSquare(...): Square = ... area = areaSquare It does have some advantages (although not so many if one doesn't fancy object extension, like in Scala, let's say).
Re: Statistics for standard library usage
I agree that a big standard library is useful, and that there are areas that could be expanded (e.g I think the stdlib should include a `heap` implementation). But it only works if there are contributors interested in maintaining the modules. For some of the current modules, that's not the case. Take a look at `xmldom` and `xmldomparser`. They are used in `0.2%` and `0.5%` of projects, they haven't been touched in a long time (`xmldomparser` hasn't had a commit in over 2 years), they use outdated naming conventions and so on. Since obviously nobody cares about these modules, why are they included in the standard library? Another advantage of Nimble packages is that they are updated independently. Updating the stdlib is an all-or-nothing kind of thing. Either you deal with all the breaking changes in the compiler and stdlib at once, or you don't update at all. This usually means that stdlib modules are very limited in what kind of breaking changes can be done - this is why we have `parseopt`/`parseopt2`, `re`/`nre` and so on. Because of this, bad design choices in standard libraries has a tendency to stay around for ever (examples of this can be found in any popular language).
Re: [RFC] Adding @ prefix (or similar) to import
I think you over-interpret my proposal. My proposal is mostly a "scoping extension", the existing overloading mechanisms continue to work.
Re: Statistics for standard library usage
> I am against reducing standard library. Fully agreed! To the contrary, I would prefer to expand it.
Re: VS Code linting broken?
@nucky9: same versions of VS-Code and Nim here. @honhon: checked for leftover/crashed nimsuggest instances, none found. Vs-Code's Nim plugin starts multiple nimsuggest instances, one for every folder (Nim package) in the workspace. The problem remains even after a fresh install of Nim and VS-Code. Narrowed it down: code checking only works for the first folder in the workspace. So my on-the-fly "fix" is to drag the folder to the top position in the explorer panel...
Re: Is there any problem with the code in atomic.nim for tcc?
async lib is single thread.
Re: Perfecting Nim
> @[] and "" don't have to actually differ from nil, it could be an > implementation detail. Pretty much like option[ref T not nil] can be > implemented as ref T. Yep. And that's how it will be done.
Re: [RFC] Adding @ prefix (or similar) to import
@Araq Well, I don't think it's possible to use generics in this solution. As far as I know, Rust's trait objects are implemented in a similar manner and they lack generic methods (that's one of the reasons why it's often advised to use generic traits rather than generic methods within non-generic traits). As for data/method separation... sadly, you won't be able to split these into more than one module. However, it would be entirely possible to write a macro (quite a simple one at that!) to automate what you said. It would probably look like this: class Shape: ... proc hash = ... proc area: float = ... class Square of Shape: ... proc hash {.override.} = ... proc area: float {.override.} = ... proc side: float = ... let squareShape: Shape = Square(...) echo squareShape.area # here, the square variant is called because area _field_ is set to square's one echo squareShape.side # compile-time error, of course
Re: cannot call a proc without brackets
@mashingan No, it's not about number of arguments. See that: proc fun(x,y: int) = echo x+y proc gun(x,y: int): int = x+y fun 1, 2 # works fine let x = gun 1, 2 # doesn't compile let x = gun 1: 2 # compiles (!), although it looks weird Just like GULPF said, it's possible to use multiple arguments but only for statements. So yes, in practice it's probably better to use it in single-argument cases as Nim is becoming more and more expression-oriented (luckily!).
Re: Statistics for standard library usage
@GULPF That's very interesting, actually! I never thought I'm SO mainstream using so many macros.
Re: Perfecting Nim
@didlybom But strings and sequences ARE already treated a little differently than plain reference object types, aren't they? The most trivial example being: strings have their literals and sequences (and arrays) have `openArray` but neither string nor sequence has object constructor. So what now? Well, just treat them more or less like primitives. If neither string nor sequence have `nil` as a proper value then they will certainly not behave like reference types. What is interesting: @[] and "" don't have to actually differ from `nil`, it could be an implementation detail. Pretty much like `option[ref T not nil]` can be implemented as `ref T`.
Re: Is there any problem with the code in atomic.nim for tcc?
Yes, it works for thread, async.
Re: Total noob, statically allocated circular buffer on microcontroller question
> running Nim code on a medium size MSP430 32K Flash, 4K RAM. The > MSP430F5510-STK board from Olimex. Interesting. Can you access all the registers already? Do you use GC? Your project based on [https://github.com/lonetech/nim-msp430](https://github.com/lonetech/nim-msp430) ? Circular buffer should be your smallest problem I guess Note, Dom's book has no microcontroller chapter, it is more intended for PC programming.
Re: Total noob, statically allocated circular buffer on microcontroller question
type RingBuffer*[N: static[int],T] = ref object #N=size, T=type buf: array[N,T] head, tail: int proc add*[N, static[int],T](self: var RingBuffer[N,T], data: T) = # some stuff and I don't think you need ref object for your use case.
Re: Is there any problem with the code in atomic.nim for tcc?
Threads using TinyC never works for me on Windows, iirc.
Re: Is there any problem with the code in atomic.nim for tcc?
Unlikely but I never got TinyC to work on Windows.
Total noob, statically allocated circular buffer on microcontroller question
Hello, I am a young embedded software engineer, small microcontrollers almost exclusively, C exclusively. I'm very excited about what I see in Nim, but I am having trouble translating some concepts that I could do in my sleep in embedded C or assembly. I wonder if I'm just trying to shoehorn in what I'm comfortable with in C. I want to create a statically allocated ring buffer using a template/generic/whatever so that I can instantiate it in the file in question and then use a handle to it for add and remove operations and have full/empty status covered in the add/remove routines. I realize a ring buffer is simple, but as a first library type of exercise I would like to be able to use the implementation over and over again by including the file in other projects. I guess this means it would need two parameters if it was a generic like so maybe: type RingBuffer*[N,T] = ref object #N=size, T=type buf: array[N,T] head, tail: int I think ref force allocates something on the heap at runtime and I'm fine with that if static allocation isn't possible but at least it can't be resizable. I'm particularly confused about how to do an add method though. Here's where I'm stuck: proc add*[T](self: var RingBuffer[N,T], data: T) = # some stuff I am totally confused as to how to do this. I haven't seen any examples like this either. I've seen the one involving linked lists and plenty of examples using seqs. Further, I would like the head and tail index variables to be the smallest width they can be and still point to anywhere in the array. I think that can be done at compile time, maybe with a process? It would be even better if the smallest power of 2 was selected automatically, provided Nim and/or the C compiler were smart enough to use bitwise and for bounds checking. Thank you very much in advance for your help. I typically learn by reading everything I can find on a subject but there just isn't an exhaustive list of material out there for Nim yet. * * * Maybe I'm just too tired to think and the answer is obvious! I need to get that book... A few examples that target the use cases of embedded software would really help. I think embedded could be a breakthrough arena for Nim. I was particularly excited about Nim when I started thinking of how great it would be if the Nim compiler could target FreeRTOS or something similar using a flag like \--os=freertos. That would be a game changer. Of course I'm aware you can wrap libraries, but to have it built into the language would rock. Maybe when I get the hang of this I'll try to tackle that. I'm running Nim code on a medium size MSP430 32K Flash, 4K RAM. The MSP430F5510-STK board from Olimex.
Is there any problem with the code in atomic.nim for tcc?
The _cas code in `atomic.nim` for `tcc` of windows is disabled. elif defined(tcc) and not defined(windows): when defined(amd64): {.emit:""" static int __tcc_cas(int *ptr, int oldVal, int newVal) { unsigned char ret; __asm__ __volatile__ ( " lock\n" " cmpxchgq %2,%1\n" " sete %0\n" : "=q" (ret), "=m" (*ptr) : "r" (newVal), "m" (*ptr), "a" (oldVal) : "memory"); if (ret) return 0; else return 1; } """.} else: assert sizeof(int) == 4 {.emit:""" static int __tcc_cas(int *ptr, int oldVal, int newVal) { unsigned char ret; __asm__ __volatile__ ( " lock\n" " cmpxchgl %2,%1\n" " sete %0\n" : "=q" (ret), "=m" (*ptr) : "r" (newVal), "m" (*ptr), "a" (oldVal) : "memory"); if (ret) return 0; else return 1; } """.} proc tcc_cas(p: ptr int; oldValue, newValue: int): bool {.importc: "__tcc_cas", nodecl.} The code seems fine, is there any potential problem with the code in windows?
Re: Installing on Windows issues
Just grab the zip and extract them to some directory. [https://nim-lang.org/download/nim-0.18.0_x64.zip](https://nim-lang.org/download/nim-0.18.0_x64.zip)
Installing on Windows issues
I'm not a window guy and I've found installing Nim easy on Linux and Mac however I tried to install Nim on a windows test machine and found it difficult. Its still now working. I tried both the download on the website and choosenim. The nim installer seems to think the path is set but it definitely isn't. I'm not really looking for a solution to my specific problem at this point. I just think it should be easier for windows users to install and there should be some kind of trouble shooting faq. Choosenim was designated as a trojan by the windows defender.
Re: VS Code linting broken?
Maybe restart vscode or check that there are not any nimsuggest servers still running/crashed.
Re: idiomatic name for object setup
Thanks! I'll change the libraries to match up with these guidelines on the next release.
Re: Guessing the module -- works, but is there a even better way?
`compiles` takes an expression argument, not a string argument. I myself don't know a way to do this other than to do something like: import macros, times, tables macro m(o: typed): untyped = let oti = getTypeInst(o) let s2 = oti.toStrLit.strVal let s2ident = newIdentNode(s2) echo s2 result = quote do: when declared(tables.`s2ident`): static: echo "tables.", `s2` elif declared(times.`s2ident`): static: echo "times.", `s2` var x: times.DateTime m(x)
Re: idiomatic name for object setup
I guess the NEP needs a link to this document: [https://nim-lang.org/docs/apis.html](https://nim-lang.org/docs/apis.html) **TL;DR:** You should define a ` newFruit` procedure which performs the "setup". That answers #1 and #3. (Note that for non-ref object the convention is `initFruit`) As for #2, I'm not aware of any idiomatic name. I always name it whatever I wish, if I were to pick something it would be `self` though.
Guessing the module -- works, but is there a even better way?
[EDIT] Well, does not even work correctly, expected result would be "times.DateTime". "When compiles()" give the same. import times, macros macro m(o: typed): untyped = #let ot = getType(o) let oti = getTypeInst(o) #let s1 = $ot.toStrLit let s2 = $oti.toStrLit #echo s1 echo s2 if compiles("var h:" & "tables." & s2): echo "tables." & s2 elif compiles("var h:" & "times." & s2): echo "times." & s2 var x: times.DateTime m(x) DateTime tables.DateTime Why I may need the module? Well, some months ago someone asked if we can use GtkBuilder with gintro. Answer is yes of course, but to make it typesafe we would have to create a macro which tests type of result from Builder.getObject(). In most cases module will be gtk, but not always. For example, if we pass a var of type Button, we would have to check if result returned by Builder.getObject() is GtkButton. ([https://developer.gnome.org/gtk3/stable/ch01s03.html](https://developer.gnome.org/gtk3/stable/ch01s03.html))