Permission Error when trying to compile a Nim program
Hey, there. I'm getting a permission error when I go to compile a program built in Nim. I can compile fine if I use sudo nim, but that makes me enter the password each time into Visual Studio Code, so I'd rather not have to do that. Any advice? Here's the error in full: solarlune@solarlune-linux ~/Documents/Projects/Nim/TestGame $ nim compile ./main.nim Hint: used config file '/etc/nim.cfg' [Conf] Hint: system [Processing] Hint: main [Processing] CC: main Error: execution of an external compiler program 'gcc -c -w -I/usr/lib/nim -o /home/solarlune/Documents/Projects/Nim/TestGame/nimcache/main.o /home/solarlune/Documents/Projects/Nim/TestGame/nimcache/main.c' failed with exit code: 1 cc1: error: /usr/local/include: Permission denied
Re: color text output in nimble
Thanks. My problem was using the wrong escape code. Here are some examples of showing [Suite] in bold blue. Python: python -c "print '033[1;34m[Suite]033[0m'" Nim: echo "e[1;34m[Suite]e[00mn" Bash: printf "e[1;34m[Suite]e[00mn"
Re: Sorting
Ok.
Re: Module logging: how to create the right Logger(s) in a library?
Araq, you are doubtlessly correct in that the right way to do it is a hook that receives structured data. Perhaps there is something worth putting in the standard library even in this case (e.g., an easy, consistent way to timestamp and mark severity - even if only as a concept). Nevertheless, it is essentially guaranteed that as Nim becomes more popular (and I hope it does), people will go to their old ways of textual logging; and it is probably better to have some uniform way of approaching that, rather than a plethora of incompatible ones. Is there some kind of generic "logger" interface that you would approve of? Even if it's a callback interface that just prints the time and the type of the passed object by default? (And not e.g. the text itself if the object is text, so as not to promote that use?)
Re: Strings and C.
That makes sense.
Re: How do you get an "IpAddress" from a hostname?
In case anyone cares, this how I eventually did it: let first = hostent.addrList[0] let a = uint8(first[0]) let b = uint8(first[1]) let c = uint8(first[2]) let d = uint8(first[3]) let ipstr = $a & "." & $b & "." & $c & "." & $d try: ip = parseIpAddress(ipstr) except: raise newException(Exception, "Bad URL: '" & hostport & "': failed to parse IP of address: " & ipstr) Rather ugly, but seems to work.
Re: Getting a NimSym from an nkIdent?
That works. Thank you! I think I'm starting to get the picture of how it works. Speaking of the VM, is there an approved way to instantiate and use it at runtime, or does it involve mucking about with the compiler source code?
Re: Sorting
Yeah we probably need to offer a sort that inlines the comparator. That said, I have seen the C compilers remove indirect calls if they can prove the jump destination (and for `sort` that is actually rather easy to determine).
Re: Optimizing file I/O
Your Python program runs once over the input, your Nim program twice. If I read it correctly.
Re: Getting a NimSym from an nkIdent?
The VM is not allowed to perform symbol lookups. If you pass `someProc` to a `typed` macro parameter you should be able to inspect the symbol(s) though.
Re: Nim Dogfooding
Email notification used to work but got broken when we moved to HTTPS iirc. Not sure what it takes to fix it. > But, well, does anyone maintain the repo? Issues and PRs opened in 2015 are > still there :/ I am afraid to just do the job which will never be merged. Yes, we do maintain it. The open PRs are usually not in a state we consider mergable. Don't be afraid to submit a PR.
Re: color text output in nimble
On Unix you can write escape sequences, it doesn't need NimScript support. On Windows escape sequences can be enabled for a terminal too, but it's not the default and the API call to enable it is not avaiable for Nimscript either.
Re: Optimizing file I/O
As you may have found out yourself already, when I was talking about replace() proc I had in mind this type of replace: var s = "This is a test" s[5 .. 6] = "was" echo s For finding the start and end position you may use find proc searching for ',' or whatever is desired.
Re: Strings and C.
It is generally a bad idea to send the whole seq to C function because there may reside additional data like seq length at start of memory chunk. Try to use address of first element of the sequence instead.
Re: Strings and C.
Thanks again cdome. I have another question with C but I want to avoid polluting the homepage with noobish topics. And strings are kind of sequence isn't it ? I want to pass a sequence to a C function but the result is unexpected. Two files for minimal example. proc print_array(tabl:seq, size:cint) {.header:"function.h" , importc.} var test = @[ -0.5f64, -0.5, 0.0, 0.0, 65.2, 0.0, 0.5, -0.5, 2564.5684 ] print_array(test, cint(test.len())) // no header guard for conciseness. #include void print_array(float arrTest[], int size) { int i; for (i= 0; i < size; i++) printf("test[%i]: %f \n", i, arrTest[i]); } output test[0]: 0.00 test[1]: 0.00 test[2]: 0.00 test[3]: 0.00 test[4]: 0.00 test[5]: -1.75 test[6]: 0.00 test[7]: -1.75 test[8]: 0.00 I trying many stupid things whithout success. Surely a lack of understanding about what I'm doing.
Re: Optimizing file I/O
The [blog entry about profiling etc.](https://nim-lang.org/blog/2017/10/02/documenting-profiling-and-debugging-nim-code.html#profiling-with-valgrind) might help. Here's the short version: If your'e on Windows: can't help you. Maybe try Linux Subsystem for Windows 10. If your'e on MacOs or Linux: install Valgrind Then use these shell commands: nim c -d:release valgrind --tool=callgrind -v ./ kcachegrind callgrind.out.# or maybe qcachegrind The (k/q)cachegrind GUI applications shows all procs with their relative share of used CPU time. For your code and a quite big input file (>10MB), it shows file operations actually use up a minority of CPU time. As @Stefan_Salewski said. The main problem is in the call level of the main proc.
Re: Fatal compilation error on Windows
Yeah, I suspected as much. In fact, I was compiling the project from the command line with the nim executable. I'll have to see if compiling from an IDE actually changes things.
Re: Optimizing file I/O
It should be clear that your code is not IO bound. You are using split(), which creates a seq of substrings for each call. Of course such operation is expensive, as for each call a new seq is allocated, and for each entry in the seq a string is allocated. If performance is really a concern, one may consider avoiding split proc -- maybe there are other procs available in stringutils, or you may invent one. Have you compiled with -d:release? I assume that Pythons split() is coded internally in C, so we should not assume that Nim's split() is much faster. Maybe Python has some smart internal optimization?
Optimizing file I/O
As a new user, I'd love to know about I/O optimization techniques for Nim. Hence, I have this simple function for [https://www.fluentcpp.com/2017/09/25/expressive-cpp17-coding-challenge/](https://www.fluentcpp.com/2017/09/25/expressive-cpp17-coding-challenge/). import os, strutils proc main() = var pageSize: int = 4096 input = open(paramStr(1), fmRead, pageSize) output = open(paramStr(4), fmWrite, pageSize) changeAt = 0 let toChange = $paramStr 2 changeWith = $paramStr 3 var i: int = 0 for column in input.readLine().split(','): if column == toChange: changeAt = i inc i let columns = i for row in input.lines(): i = 0 for entry in row.split(','): if i != changeAt: output.write entry else: output.write changeWith if i + 1 != columns: output.write(',') inc i output.writeLine("") main() While the program is not expressive, I intend to use this to explore the possible optimizations in I/O. My question why changing pageSize does not have any apparent effect on the program? And how can I find an optimal pageSize for the system? Also, any other tips would be appreciated. As a side note, the following (somewhat similar) python program is actually faster than the Nim program above: import sys with open(sys.argv[1]) as fin: head = fin.readline() col = head.split(',').index(sys.argv[2]) with open(sys.argv[4], 'w') as fout: fout.write(head) for i in (x.split(',') for x in fin.readlines()): i[col] = sys.argv[3] fout.write(','.join(i))