Re: Python transpiler
If you mean compiling _from_ python, there's [https://github.com/metacraft-labs/py2nim_deprecated](https://github.com/metacraft-labs/py2nim_deprecated)/ which has gained "deprecated" in its name since I last looked at it. It's not very complete though. If you compiling _to_ python, there's [https://github.com/juancarlospaco/nim-new-backend](https://github.com/juancarlospaco/nim-new-backend) which is also incomplete. The biggest question is _why_. If you want to use Python from nim, or the other way around, then nimpy and nimporter might be better choices than trying to fit everything into the same language runtime.
Re: "Nim for Python Programmers" wiki page
> Well technically you can replace all uses of inheritance with object variants > (I think). But in some cases it will get too verbose :) In the sense that all turing-complete languages are equivalent... With variants, you have to know and handle all the possible classes at every "method" implementation. With inheritance, the implementations can be done independently. Equivalent capability, of course, but vastly different from a management/maintenance perspective.
Re: Copy-on-write container
@snej @mratsim \- Thank you both very much. I've re-watched Andreas' talk and gone through the String CoW and mratsim's example. It looks like I'm covered, but there's one thing that I haven't managed to convince myself of, described below. Is this enough to guarantee that the compiler won't lend something "behind my back?"; by which I mean something like: proc action(a:cowType, b:cowType, c:cowType, d:cowType): modify(a); modify(b); modify(c); modify(d); var x = cowType("Hello world"); action(x,x,x,x) `=destroy`(x) Run Now, as far as refcounting goes for "liveness", it's enough to count 'x' once on entry to action() (or even zero, as it is lent). But for CoW purposes, we need to count all 4 uses, so that if 3 of them modify it, they each get their own copy (but the 4th modification doesn't - it can modify x in place because that's the last copy and it's a sink. At the very least, looks like cowType always has to be passed by value for this tracking to occur (even "modify"), and var shouldn't really be used. But I have still not been able to convince myself that there is no case in which the RC will be enough for liveness tracking but not enough for CoW tracking. Perhaps I just need to spend more time on it. Another question I came up with while sketching a solution: I'm trying to implement a (sort-of-) language/dsl, in which the CoW makes everything have value-semantics, although in-place array and table modifications are efficient. That, unfortunately, necessitates refcounting. However, many times one would only call "pure" functions which are guaranteed not to modify anything, directly or indirectly -- and if so, the reference is completely lent, and no refcounting is needed. Nim's effect system should be able to help with that: have a .tag[modify_refcount] on the proc funcs that actually modify refcount; and .tag[] on those that shouldn't, and the compiler would verify that those that shouldn't are indeed side-effect-free (w.r.t refcounting). But how would it be elided in practice? by passing them as "var"? Can a template/macro have access to the inferred tags, so it can act on this and perhaps save the incref/decref in this case? I'm hoping to dive into the compiler this weekend to figure out, but would still appreciate any help/pointers.
Re: Norm 2.0.0
Automatic tracking requires really explicit documentation about what it does. It won't be common, but it will happen that SELECT and UPDATE actually happen in different transactions (or in otherwise a non-ACID mode) -- in which case, just comparing content is not a good idea (you do rec.field='the value i want' to guarantee it is that way, and it was that way in the SELECT, but has since changed in the DB. The only reasonable "automatic" way is to track actual assignments and execute them _even_ the newly set value is the same as the previous one; either that or updating everything. Any other way to subset the update should be explicitly specified by the user..
Re: Copy-on-write container
So ... It's been a while, and an awful lot has happened on the arc/orc front; so hopefully it's OK to bump this up: * What's a good strategy for implementing copy-on-write with --gc:arc and/or --gc:orc? * Is it possible to inspect/access the refcounter, implicit or explicit, from --gc:arc and/or --gc:orc? @mratsim switched away from CoW, but it is put to great use in APL / J / K implementations; In general, they simulate a "value only" system by using only references and reference counts; Anything that is only referenced once is just modified in place when you want to modify it. So you get easy to debug value semantics, and (most of the time, with very little care required) reference performance. This is in contrast with e.g. Clojure's persistent vector implementation which clones a limb on _every_ modification and thus generates a lot of garbage; or with R (v3, haven't looked at the v4 changes) using inaccurate refcounts, which requires some care to not generate too much garbage. As --gc:arc and --gc:orc already maintain refcounts (some in memory, some in the AST), sane access to them would greatly simplify such CoW schemes - which otherwise duplicate all the refcounts (or otherwise has use ptrs instead ...) Any ideas / docs / pointer?
Re: NvP: s.add('x') 100M times
Possibly something to do with this being main() and not inside a function? Can't think of a reason why for this one, but many benchmarks change significantly (for the better) when put inside a function
Re: Norm 2.0.0
> 4\. Better safe than sorry. I've deliberately removed the migration > capabilities like add column, remove, rename table, etc. Turns out, > migrations are never trivial, and it's always better to just write SQL > manually than to try to automate it somehow. That's very true. However, even if there is no automatic migration, it is helpful to have a tracking of which schema is in the database and which one is expected by the code. As you generate a DDL statement that creates the tables (and in the future - maybe also indices, and/or triggers, and/or stored procs), perhaps you can use a sha1 of that statement to "name" the created/expected model, and then -- perhaps with a helper table that names the existing schema, you can verify whether the data model matches. Migration from one schema to a another should NOT be within the scope of the main ORM in my opinion -- however, it is useful if versions of the software can ship with "migrate-HASH1-to-HASH2" scripts, many of which will be trivial -- and the applicator of which CAN be included with the ORM. Just my thoughts and experience, mostly from using web2py (nowadays py4web) which made a lot of controversial choices, some good and some bad -- and most of those related to migration have a lot to teach by being bad
Re: Norm 2.0.0
That's a nice use of dup, I wasn't aware it could take multiple procs - and I think the name "flow" would be more standard for this use case if it is ever revised -- but I do not suggest changing a name - 99% of the cases probably involve exactly one proc for which the name "dup" is definitely fine, and also, backward compatibility >> naming preferences.
Re: New blog, with some Nim articles
> Do you think that "optimization wall" is understood by most people? "I tried to do X but I hit a wall" (meaning, an obstacle I couldn't get around and wasn't sure it was even possible to get around) is an often used expression in American English; I think it's understandable. see e.g. [https://www.macmillandictionary.com/dictionary/british/hit-a-the-wall](https://www.macmillandictionary.com/dictionary/british/hit-a-the-wall)
Re: Error: type mismatch: got but expression is of type: type Float32Sort
Would it be possible to make the error instead: > required type for s: type Float32Sort (defined at file1.nim:17:3) > but > expression 'Float32Sort_3735007' is of type: type Float32Sort (defined at > file2.nim:917:1) Or something like that? That would make it less confusing. Perhaps having it always is information overload and it should only be provided if the string representing the type name is the same? That's not a complete solution, because I except that this problem would happen mostly with template/macro instantiations from the same template/macro (and thus the exact same point of definition...). A complete solution, perhaps, would need a stack of the source locations of all template/macro expansions that lead to the type definition, and then eliminating the common prefixes and suffixes between the mismatched types to point to where the problem exactly is. (Have no idea if the compiler even keeps all this info, and if it does - whether the implementation complexity is worth it for this)
Semantic grep, a very cool idea (currently mostly for Python)
I just saw this, haven't had a chance to try yet, but it looks very nice. The idea is a "grep" style tool that understands language scoping and semantics well enough to be useful as a semantic search tool and a simple linter, currently implemented for C / Java / JavaScript / Python / Go . It also has a ruleset database of code errors/smells that should help find security issues and other errors although from what I can tell, it's mostly Python rules so far with only a few for other languages. It supposedly allows, for example, a grep for `os.system(...)` in Python to find direct uses after `import os`, or unqualified uses after `from os import system` and even stuff like `from os import system as execute; execute(args)` and `import os as x; x.system(args)`. Also allows matching on parameter values, backreferences and other stuff. I think it could be useful for Nim (as another backend, perhaps some ideas integrated directly into the compiler or nimgrep). Still thinking about what rules I would write and what searches I would use, and I think it's much LESS useful for Nim than it is for e.g. Python or JS because the Nim compiler & tooling do so much more than Python or JS - but still, I think it's a neat idea and wanted to share. Project: [https://github.com/returntocorp/semgrep](https://github.com/returntocorp/semgrep) Slides: [https://r2c.dev/HellaSecureSemgrep.pdf](https://r2c.dev/HellaSecureSemgrep.pdf) Rules: [https://github.com/returntocorp/semgrep-rules](https://github.com/returntocorp/semgrep-rules)
Re: Typography update - now it can render 99% the Google Fonts ttf.
Super cool! Do you have plans to support kerning, glyph composition, ltr/rtl/ttb/btt layout fonts? (Or are they already supported?)
Re: NOOB: Is there a way to do: dos.com + my.nim ==> my.exe (Just ONE file)
I assume it's an EXE file even if it is called .com; It is possible but complicated to do completely in memory (if dos.com has threads or uses DLLs). A relatively simple way, if it is acceptable, is to put a copy of dos.com into your executable (as a RES file, or with staticRead, or something like that), and then your Nim program can write a copy of "dos.com" and run that copy. This will require space you can write to, and might trigger some anti viruses - but that's the kind of thing that e.g. PyInstaller does to pack a Python project with all dlls and graphics files into one executable.
Re: Help understanding simple string pointer indexing example
Disclaimer: Based mostly on my C++ experience with this kind of problem, did not run into it with Nim and can't test this second. > If you're including other people code in your project you just have to trust > them in the same way you trust it to work. Linus Torvalds has said more than once that "security bugs are not special, they are just bugs that have security implications" (paraphrasing from memory), and I think he's right - the reason we (in general) care more about them is that rather than producing a wrong answer or no answer at all, they allow a determined malicious actor to willfully do disproportional damage. To put this in concrete terms, instead of `foo(x)`, assume it's `draw(x)` \- Library A deals with drawing on a canvas, and Library B deals with drawing money from a bank account; for whatever reason, Library A's `draw[T](x:T)` is a template that can draw anything that can be converted to a string. and Library B's previous version did NOT have a `draw(x:money)` (it only had a `transfer(x:money)` proc), but now it does. There is no malicious intent on the part of any library author (indeed, the library authors don't know each other or the user or the main program that uses those libraries), but a malicious user can cause money to be drawn from the account by triggering an action that needs to draw some money value on the screen. This example is a bit contrived and colorful (and based on one of Stroustroup's), but not so far fetched; You could have an `execute(x:T)` template that does a well defined, well secured thing -- and then another library adds `execute(x:string)` that shells out and executes a command line. Or -- much harder to catch -- the new proc has the same functionality as the old one it overrides, but implemented in a different way that overall creates a TOCTOU or race condition or otherwise harms integrity. I didn't have time to try these in Nim (maybe most cases already have a warning), I have encountered something similar (not security related, just plain old bug) with C++ templates, which is just one of the reasons I've avoided C++ for more than a decade. It should be possible to warn that "import B specializes template from A but they are not related" or something like that, I think - e.g. if both a concrete and a template definition match at a call site, then the template definition must be known at the concrete definition's site or something like that.
Re: Finally, I can do functional programming on tiny embedded systems
Is --gc:orc still a thing? It says in the docs it is hard to reason about (which is understandable), but is it possible to use with a time limit like the old --refc? Are there any other docs about it?
"If you need an embedded C compiler" - from the latest zig blog includes an suggestion for Nim
Quoting from [https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html](https://andrewkelley.me/post/zig-cc-powerful-drop-in-replacement-gcc-clang.html) : > For example, maybe you have a programming language that compiles to C. Zig is > an obvious choice for what C compiler to ship with your language. (The link for "programming language that compiles to C" is to nim-lang.org) The zig tarball is 45MB (!) but that supposedly includes a fully working clang that properly cross compiles to Windows, Mac, Linux, 32-bit, 64-bit, musl, glib, mingw64 and other goodies. Haven't played with this release yet, but everything Andrew Kelley has released so far was working as advertised, so this likely does to. Useful perhaps, as Andrew suggests, to include in a "batteries included" Nim distribution that can cross-compile from any arch to any arch.
Re: Nimble raiseOSError: cannot install a package
Great. Probably a good idea to add [solved] to the title of your original post, makes it easier for others facing the same problem to discover.
Re: help information sécurité
> For hardcore security jobs I still use Ada, for (rare) GUI jobs I still use > FreePascal, for pure crypto jobs like porting or optimizing crypto algos I > still use C along with formal modelling, proto verif. and formal (usually > static) analysis. Extremely interesting! Could you give a list of your C formal modelling toolkit / workflow ? And a hint about what kind of common things it flags in Nim generated C code? Also, since you mentioned using formally verified C for crypto work - is there anything helping with verifying constant time stuff? How useful is everything given that anything practical uses a non-verified compiler somewhere along the high-level -> machine code path?
Re: How Seq work with objects ?
As Stefan_Salewski wrote, > When you delete reference objects, the object itself where the references > pointed to has to be deleted too, at least when there is no other reference > to it to keep it alive. And that delete costs time too, generally alloc() and > dealloc() calls are expensive. This is almost surely the reason. You can verify that by making another copy of the ref "buff" before starting the deletion, so something still holds the references. Also, you're likely to find big differences if you measure gc:arc, gc:boehm or the old mark
Re: Recommended GUI library?
Tangential: I haven't done GUI work in a long long long time, but I discovered FLTK in 1998 (then pre-1.0), and came back to it again and again, last time in 2012, for the simple reason that it never flickered thanks to built-in double buffering - and every other toolkit, even in 2012, had cases where it did. I don't know if it's still a problem these days, but if it s - GUI toolkit developers, please pay attention to it.
Re: FOSDEM 2020 - Brussels February 1st & 2nd
Possibly they are waiting for you to review and ok it before putting it on the lecture webpage? It's still not on the website.
Re: Performance test agains Python
You are also testing cache effect times at least as much as you are testing the code you are running; Either take minimum-of-5 sequential runs, or an average of 10 loops or so (or both); Not sure about Win10, but for sure Windows used to report times in multiples of ~16ms at least as late as Win7, unless you took special care -- so as long as you are measuring times so small, that may also be a confounding factor.
Re: GC:ARC passing '...' to a sink parameter introduces an implicit copy; use 'move(...)' to prevent it
Maybe there should be a pragma {. expensive .} (or alternatively {. cheap .} which could be set on hooks and which would trigger a warning if they are implicitly invoked? Also: I was reading the destructor docs in [https://nim-lang.github.io/Nim/destructors.html#swap](https://nim-lang.github.io/Nim/destructors.html#swap) says > Objects that contain pointers that point to the same object are not supported > by Nim's model. Otherwise swapped objects would end up in an inconsistent > state. Is this really true? Seems to me it's just not supported by the "swap" builtin (and that should be fixed, because self-pointing structures do happen and are not always immediately evident from the source code - e.g. a circular linked list with one element).
Re: GC:ARC passing '...' to a sink parameter introduces an implicit copy; use 'move(...)' to prevent it
If so, please make the current aggressive warning an option - and provide copy() to suppress it. Not sure what the default should be, but one of the the reason I switched back from C++ back to C is because it's way too easy to introduce unwanted operations (copies and other) -- which is usually fine in high level code, but a big problem in performance sensitive code.
Re: Doubt! Proc and import
> That's way too negative, the binary will contain the required parts of the > Nim compiler and its VM and all you need to do is to provide lib/system/, > system.nim (and maybe strutils, etc) with your app and patch the line let std > = findNimStdLibCompileTime() to something appropriate. Was not intending to be negative, and this comment was in the context of compiling down to native code; you are of course correct (and that was my first paragraph - use the nim vm), > That limit can be changed at compile-time but it's a very useful thing for > sandboxing. In the few benchmarks that I did, the VM runs Nim code faster > than Python's VM runs Python code. Indeed, that's very useful for sandboxing; I remember when Python tried to introduce sandboxing, by way of putting such limits, but it never converged - there were issues with loops, string multiplications, e.g. `` 10e10 * 'hello world' `` or `` range(10e10) `` would blow up memory; they were fixed as they were found, but their approach of rewriting bytecode was doomed to fail (and did). Implementing these restrictions within the VM is much more practical. And I've never had a chance to use Nim VM for anything speed related, but the python speed comparison is very good news.
Re: Doubt! Proc and import
If you don't really care about speed - you could use the built in Nim compiler+virtiual machine as a script interpreter, (though IIRC there are limits by default that may surprise you and that can be removed, e.g. how many iterations a single loop can have is limited to 1,000,000 as this is meant to be used _while_ compiling). Otherwise ... Your users will need an installed, accessible compiler compatible with the one you used to build the main; that's easy if you do everything in JS (you already have the relevant JS runtime and likely compiler) but more complicated if you use other targets (C / Objective-C / C++) - is it VS2015, VS2019, mingw32, mingw64, gcc, llvm, nlvm, ...? If the users don't provide source code, but only need to pick which module to load from a given set you already provide, either (a) import all of them in the first place, and have some logic to call the right one, or (b) use dynamic loading and possibly hot-code-reload to pick the right one to use -- and save your users the headaches from needing to have a usable compile environment.
Re: DSLs and macros: custom function signature
If you insist (and I agree with Araq you probably shouldn't ... ), you should probably be aware of [https://nim-lang.org/docs/filters.html](https://nim-lang.org/docs/filters.html) which would allow you to do such a translation in a standard, compose-able manner -- which may boil down to just replacing "def" with "proc". I am not sure if it will work for your specific use case, but some macros/pragmas could be set for a context (once in the file, or a block, essentially - see e.g. [https://nim-lang.org/docs/manual.html#pragmas-push-and-pop-pragmas](https://nim-lang.org/docs/manual.html#pragmas-push-and-pop-pragmas)) , and there are other ways to apply a macro to a block of definitions rather than to a specific one through the `{.pragma.}` syntax - e.g. > dspcode: > proc foo(args:) ... > Where dspcode is a macro that does the magic onto it's subtree. What's left is just the proc<->def exchange.
Re: Weird Behaviour
> var a = number.len -2 #throws invalid Indentation error That's because it is equivalent to `number.len(-2)` and/or `len(number, -2)` ; followed by something that looks like a negative number is a negative number (and not a "subtract" operation).
Re: Code cleanup suggestions: ctors
Why are you using ptrs instead of refs? You could do "type person = object[id:int;name:string]; type male=distinct ref object of person; type female=distinct ref object of person;" to get an equivalent effect (while dropping ptrs for refs). However, I highly recommend instead having a "type person = tuple[id:int;name:string;isMale:bool]" which would take a tiny bit more space but would make your code considerably simpler. The argument against my proposal would be: If you encode the constraints into the type system, the compiler can validate a lot of things for you -- which is correct, and which I support when it does not result in code duplication; However the issue is that in this case it results in a lot of duplication (some of which can be reduced, but not all).
Re: Zig as C compiler for Nim. How to feed him the code
It's been a decade or so since I've used Windows, but IIRC at least one of cygwin/mingw32/mingw64 contained a linux cross compiler in the repository.
Re: Why whitespace?
>From several decades of experience, tabs eventually always cause the >(potential) problems, but only rarely deliver the (potential) benefits. For the people who can't live without them, Nim provides [https://nim-lang.org/docs/filters.html](https://nim-lang.org/docs/filters.html) ; an `#? expandTabs(tabwidth:int)` filter can easily be written. Personally, I think it's a bad idea and would recommend against including such a filter in the standard library.
Re: Why does the this code work?
You're right, thanks; There probably could be issues in convoluted cases (will try to construct one later for fun, e.g. `varargs[string | seq[string]]` , or with default conversions -- but you're right that this is unlikely to ever pop-up om regular use even if these cases can artificially be constructed.
Re: Why does the this code work?
> There is another case where the Nim compiler uses its knowledge of types to > help the programmer: this is the automatic dereferencing of references and > pointers. No, it's just a stylistic decision, one that some people find surprising as it is a special case. Python could have just as well automatically expanded a list into varargs - in fact, it has more information at the time of the call than Nim does, being dynamic. If you want to pass just one list argument to a vararg Nim proc, you need to call e.g. `printStuff(@[lines])`, because `printStuff(lines)` would ""unwrap"" it and provide a list of unknown length; whereas either `printStuff(lines,lines)` or `printStuff(@[lines,lines])` would result in an argument list of 2 arguments, regardless of the length of lines. This (apparent) inconsistency is the source of the confusion. Personally, I prefer the Python behaviour, but since we're past v1.0, I don't think it's worth discussing a breaking change even if everyone agrees with me (And not everyone does).
Re: Why does the this code work?
The surprise (as I understand it, and I remember it surprised me too reading the docs) is the automatic expansion of the arguments. The consistent way would be for `printStuff(lines)` above to provide 1 argument of type seq[string], in the same way each arg of `printStuff(lines, lines)` would do. As it is, a single "lines" argument results in an arbitrary length x, but two arguments result in x.len==2. e.g. in Python, you have the same functionality, but you have to prefix the arg with a `*` to say "I wish to expand this list into an argument list and not pass it as a single argument", which is consistent with the use of `*` in similar contexts, and with the passing of any other individual argument.
Re: Compile time FFI
Agree with Araq here; find a way to do it with (a possibly improved) staticExec - or alternatively, it could be solved with a bidirectional communication channel through pipes (or sockets or shared memory, though these aren't good ideas either) if Nim code with access to compiler types etc. needs to interact with external code. But invading the compiler's memory address space is a recipe for disaster. At first it will work, but down the line people will complain that the nim compiler is buggy and unstable, but it will later turn out that the crash is caused because of a memory corruption caused by importing a library 3-layers deep which uses the compile time FFI. But seriously, I think even staticExec+staticRead is more than enough. At some point, you have to rely on a build/make tool that can do more than your language do internally.
Re: Arraymancer - v0.4.0 (May 2018)
I have randomly wondered onto [https://github.com/flame/blis#key-features](https://github.com/flame/blis#key-features) today and haven't had a chance to play with it, but it sure looks interesting; Are you familiar with it? Obviously less relevant if you're going to do a pure Nim BLAS ...
Re: Naming conventions - need leading underscore
> Hungarian notation encodes the type in the name and is widely regarded as the > wrong idea. Why should it be any different with visibility. While i completely agree, it is my impression that it is really helpful for beginners to carry around the type information in their first few programs - as did old BASIC versions in which `SPEED` was a floating point variable, `SPEED%` was an integer and `SPEED$` was a string. But I also believe that beginners don't stay beginners for long, and Nim is not (at this point in time, and probably not ever going to be) a programming language for absolute beginners - so the consideration should be those that are useful for experienced programmers - as I believe they had been all along (thanks, Araq!)
Re: Introducing --gc:arc
Just to make sure I'm not confused - there are no changes to the source code needed, though "sink" and "lent" annotations do provide optimization? And it's independent of the bacon/dingle "owned" system (and is it going to stay or is it deprecated and going away?) In what way does "async" need to be ported to arc? Is it just a performance thing, a cycle thing, or is it a deeper issue?
Re: Pandas Equivalent for Nim?
Arrow provides a common data storage format, but not much more; It is not a replacement for pandas. It is nice if you have a lot of multiple languages cooperating and a lot of serialization/deserialization happening - though personally, in every use case I had, HDF was a much better choice and just as well supported if not more.
Re: recvmsg on AsyncSocket
> I'm curious what you're trying to achieve at a high level though, maybe there > is another way that doesn't require FDs being sent across processes? @AMIGrAve already answered, but I'd like to add: This is the most efficient way to do hand-off between processes if you can do, whether it is a listening socket or a connected one. If all is symmetric, (e.g. multiprocess nginx), then you can have multiple processes listening on the same port; Another common way to deal with this is the old "accept-and-fork", which works very well for long lived connections where overall processing dominates the forking time -- but not with e.g. preforking or long-lived backends. Unfortunately, the most common way to deal with it -- especially if the backend is itself a long-lived process -- is for the original accepting process to proxy to the actual backend. This is wasteful in cpu , memory, kernel resources, and also requires the proxying process to remain up and responsive (adding latency and reducing reliability). While this is a necessary evil if backends are on a different machine, it is a complete waste if all is running on the same machine - and with 32-64 core servers relatively common these days (especially with containers), it is often the case that you can use the more effiicient route. The other way to avoid sending FDs is shared memory - which is just a bit less efficient than transferring the FD (basically, just another memory copy and almost uncontended synchronization), but still has the latency/reliability drawback, and is significantly more complicated to get right. It's available on Linux and most Unix variants, but not on Windows AFAIK.
Re: Pragmas Above Procs
The one that's a thread is the one that has a table parameter There are two not-entirely-orthogonal questions here: 1\. What's more important to emphasize? That's the thing we work on is thread code, oh, and it's a proc rather than a variable? Or that we're going to define a proc. Oh, and it's intended to run in its own thread?) Well, that obviously depends on your specific circumstances, and in the proc() case I might agree that the attributes (side effects, thread, async, ...) are as important as this being a proc, though no more important. In the case of variables, though - I totally disagree; the name is the most important thing (given that Nim chose suffix everything unlike C) -- see e.g. [https://github.com/captainbland/nim-validation](https://github.com/captainbland/nim-validation) for example (and there was a DAL/ORM with similar good use, but I can't find it now). I had used prefix annotations in C# when using WCF and stuff, and even people who like C# (I don't) said it sucked. So, unless you think you should have annotations before for procs and after for vars, I think after wins. 2\. What are you used to? Well, this is totally subjective; I'm used to both, and have no preference for procs (but the preference I stated above for vars) and do have a preference for uniformity. And I offer again: If "thread" or "async" is the important character - use a macro to make a thread_proc or async_proc the same way func makes a "nosideeffect" proc; no need for language changes for that. The only language change that might make sense that I can think of (and perhaps everyone happy) is {.next_is thread}, which is like {.push thread} wiith automatic pop at the end of the scope; But I really think that this discussion should only be carried if you've _tried_ to get used to suffix for a while and couldn't -- not because it looks weird at first. Have you tried?
Re: Pragmas Above Procs
C# has prefix everything (types, annotations) because it inherits the C syntax Nim has suffix everything (types, pragmas). Python has it mixed because ... well, they didn't think about it at the same time, and added @ annotations as prefix and type annotations as suffix. But there's a sort-of-precedent in nim too, which might generalize: -`func` is `proc {.noSideEffecots.}` ; you could just make `aproc` or `asyncproc` into a `proc {.async.}` using a macro (maybe even a template), and get your prefix without having to modify the language.
Re: recvmsg on AsyncSocket
@mp035: While descriptors are local, they CAN be passed between processes as @AMIGrAve is trying to do. The details depend on the socket type, which must be an AF_LOCAL or AF_UNIX, IIRC; You can google "sending fd between processes" for answers; a random one I found with examples in C is [http://poincare.matf.bg.ac.rs/~ivana/courses/ps/sistemi_knjige/pomocno/apue/APUE/0201433079/ch17lev1sec4.html](http://poincare.matf.bg.ac.rs/~ivana/courses/ps/sistemi_knjige/pomocno/apue/APUE/0201433079/ch17lev1sec4.html) ; {{man recvmsg}} describes it as well. But I've only ever done this in straight C
Re: NaN tagging in Nim?
(edited previous reply)
Re: NaN tagging in Nim?
You could have tables-of-refs-to-objects, e.g. allInts:@seq[int], allFloat:@seq[float], and NaN tag the indices to those lists; it would require one more redirection to actually get the value, but would otherwise work well with any gc. Also, subnormals (neé denormals) are also useful for tagging. And unlike NaNs which could be a result of a computation (e.g. 0.0/0.0) which you must differentiate from your tagged values, if you set the FPU "flush to zero" mode, they will not be generated as a result of a computation; see e.g. [https://stackoverflow.com/questions/54531425/is-it-possible-in-floating-point-to-return-0-0-subtracting-two-different-values/54532647#54532647](https://stackoverflow.com/questions/54531425/is-it-possible-in-floating-point-to-return-0-0-subtracting-two-different-values/54532647#54532647)
Re: Can I "prune" directories with walkDirRect?
The python os.walk is exceptionally convenient and supports such a use case - the iterator returns 3 components: "path", "dirs" and "files"; the user has to enumerate "files" (or dirs) themselves, and join themm to the "path" for the list of files, but can also ignore dirs or modify it - the iterator will only recurse into those still listed into dirs when re-called, so: if you ignore dirs, you get a standard recursion; if you empty it out, you get no recursion down from this path; and if you filter it, you get selective recursion. It has a few more bells and whistles that cover just about all use cases I've encountered: [https://docs.python.org/2/library/os.html?highlight=walk#os.walk](https://docs.python.org/2/library/os.html?highlight=walk#os.walk) Worth adding to standard library, I think.
Re: Multi-threading and data sharing
gc:boehm / .gcsafe. would make the compiler shut up about accessing another thread's data, but one would still get the spawn interference warnings if detected, right?
Re: Copy-on-write container
So ... I was trying to read up on `=sink` and `=destroy`, and am a bit confused: There's [https://github.com/nim-lang/Nim/wiki/Destructors](https://github.com/nim-lang/Nim/wiki/Destructors) , which appears to be outdated, forwarding to [https://github.com/nim-lang/Nim/wiki/Destructors,-2nd-edition](https://github.com/nim-lang/Nim/wiki/Destructors,-2nd-edition) which refers to [https://github.com/nim-lang/Nim/blob/devel/doc/destructors.rst](https://github.com/nim-lang/Nim/blob/devel/doc/destructors.rst) which does not document which version it actually references. Also, the latest destructors doc refers to `lent` and `owned` references which are only documented there and not in the 1.0.0 language manual, and you mention the "old default `seq` implementation" which fails to call `=destroy`, implying that there's a new one? (but how do I choose which one is used?) I would like to implement a "functional" copy-on-write refcounted sequence (a-la APL / J / K / Ocaml without references), that is - the semantics of every value of this kind is equivalent to a value type, and thus can have no cycles -- much like refcounted strings. (so .. refcount is precise) Araq, hopefully this is not too much to ask - but, what would you recommend as an implementation strategy? My idea would be own-managed ptrs to memory, and using the `=`,``=sink``,``=destroy``, `[]=` operators to manage the references. It seems like `sink`, `owned` and `lent` may help with removing unneeded refcnt operations in some places, but since they are not in the 1.0.0 manual I am at loss about whether they can be relied on to be there, and/or which gc model they assume/require. Thanks in advance.
Re: Copy-on-write container
Thanks! I'm still going to try to CoW, using a similar style to C++, though using the standard GC, that would essentially mean the refcounting will happen twice all the time ... I'll look for a way to piggyback on Nim's refcounter when I have the time.
Re: Copy-on-write container
I might need a copy-on-write implementation, and was wondering if this is still a good way. Am I right in thinking that this will only work with the refcount gc, and not with the new (owned/bd) or alternative (mark & sweep, boehm, regions) gcs?
Re: Language Design Question: Backend C vs LLVM IR
But there's also [https://github.com/arnetheduck/nlvm](https://github.com/arnetheduck/nlvm) \- so you'll likely get to choose the one you prefer.
Re: What is the best way to run a nim program as daemon?
Wholeheartedly recommend not reinventing the daemon wheel - self-daemonizing programs and self log-rotating problems never do things quite the way one needs. use systemd, if that's what on your system, or (I recommend) a djb-inspired system: daemontools, s6, nosh , etc - they are ultra simple and roc solid.
Re: Some nim builtin libs not doing enough error checking?
This pattern (of e.g. checking dirExists before doing things in the directory) is known as LBYL (Look Before You Leap), and often leads to security problems known as TOCTOU (Time-of-check/Time-of-use) if the answer changes between the test time and the use time - depending, of course, on program logic; exploiting these is often not deterministic but possible if you can afford a few thousand attempts. I to prefer no exceptions of any sort in these cases, but I do like to have some signal if interested; C's "errno" is a useful, if error prone, compromise - but it doesn't quite fit with Nim; and unfortunately, I have no other solution to offer.
Re: Extract sprite data from old DOS game resource file?
This is not code; This is data of some sort.
Re: still no success binding DLL's callback function
FLTK's widgets are full on pointers, and coordinates in FLTK-1.3 are at least 32-bit (they were 16-bit in FLTK-1.0 and FLTK-1.1); You might have problems from the int16<>ptr mismatch, as well as the int16<->int32 mismatch if you ever use coordianates > 32768.
Re: release: a current-runable, error-in-the-future msgbox for wNim
> You should follow the language's conventions, not the libraries. Off topic for this thread, sorry, but ... I can't square this with Nim's liberal grouping of camelCaseWhichIHate and camel_case_which_I_hate. So far, I only use Nim on linux, interfacing with existing libraries all using lower_case_underscore_naming_convention. I don't disagree that a convention might be a good idea. But if so, then .. why have Nim's identifier rules, which though simple and useful once you get used to them, are confusing to new users, often ridiculed by non users, and essentially guarantee that this discussion will never end?
Re: should `computedGoto` be always implied ? (ie make computedGoto noop)
You are probably right, I've been away from this level of implementation for the last decade, but I was under the impression that if the branch target is fully known enough cycles in advance (as could be in this case if the jump table is in L1, if loading of ebp was pushed further back, and which IIRC LuaJIT2 does do) there is, in fact, no prediction involved. I'm likely wrong, though, and extrapolated the state of the art farther than where it actually is.
Re: should `computedGoto` be always implied ? (ie make computedGoto noop)
I can't find it right now, and I might be mistaken, but IIRC Mike Pall (of LuaJIT fame) managed to make this call/ret trickery obsolete in the LuaJIT2 interpreter, by pipelining the decoding of the next instruction to overlay with the fetching of the next address, along the lines described in [https://nominolo.blogspot.com/2012/07/implementing-fast-interpreters.html](https://nominolo.blogspot.com/2012/07/implementing-fast-interpreters.html). In my opinion, if you have to resort to machine code (which the context threading solution does), then you might as well spend a little more to overlay the operations; it will be obsolete within 10 years either way thanks to architecture differences. Their solution does carry more easily to more architectures, I'll give them that, but the question is "how fast can you go", not "how fast can you go for only 400 implementation lines".
Re: How to write a Windows service?
The (non-)selected Stack Overflow response recommends using NSSM (The "Non Sucking Service Manager"), and I do to - it can run any executable as a service, collect and rotate its stdout/stderr, and makes it easy to register, inspect etc. I'm not sure how it passes e.g. suspend requests, but for 99% of use cases, it seems to make running and using services much much simpler.
Re: `import foo {.private.}` to allows access to private fields (eg: package-level visibility)
I've edited my comment above while you posted yours ... With respect to "sticks out enough", I totally agree at the early adopter stage Nim is still in, but totally disagree for the time it reaches more widespread audience (and of course total world domination) - to many programmers, especially from a C++ / Java background, slapping a "private" or "public" onto things until the compiler is happy is a way of life.
Re: runnableExample considered harmful / good feature to deprecate before 1.0?
> What's currently been missed in this discussion here IMO is that > runnableExamples are not just documentation, they are also tests That's a very important point. Perhaps there's merit to having runnableExamples: and runnableTests: , the former copied to docs and the latter not? (or, perhaps start hidden behind a "show runnable test" button in HTML?); perhaps an arg to runnableExamples?
Re: `import foo {.private.}` to allows access to private fields (eg: package-level visibility)
It's a good idea to have an escape hatch, but like all "break the glass" devices it should stick out as the wrong thing to do unless absolutely necessary; not sure how to achieve that, though.
Re: Interesting idea implemented in Zig
> at least for error detection you can also have none of X strings Yes, the result of a minimal perfect hash is always "it is either this specific string, or none of them; you'll have to compare to this specific string to tell". The result of a non-minimal perfect hash is "its none of these strings; or it's this specific string (compare to verify) or none of them". Error detection is part of the standard use case. The "list of strings is known" is a common use case, e.g. for keywords in a stream parser, or an an IFF atom (... yes, I'm old), or Windows messages, etc. Obviously it's not for every use ... Am I understanding correctly that you want to implement BTrees for read-only compiled "case" statements or read only mapping types?
Interesting idea implemented in Zig
[https://andrewkelley.me/post/string-matching-comptime-perfect-hashing-zig.html](https://andrewkelley.me/post/string-matching-comptime-perfect-hashing-zig.html) This post from about Zig, a language with slightly different goals than Nim, but is probably interesting in the context of Nim as well. Perfect string hashing is useful for matching one-of-x strings, when the list of strings is known in advance; at runtime, it requires a small number of constant operations (good implementations get 1 or 2), usually a single short (often single byte) lookup, and then you have a candidate which is either the right one, or the string you hashed isn't in the list. There are various methods to find a perfect hash; one is guaranteed to exist although the algorithms to find it are often non trivial. Most implementations eventually resort to picking a random seed, using it to compute a standard hash, and just retry until finding one with no collisions on the list given. In this context, this paragraph has an interesting suggestion: > Another way this can be improved, to reduce compile times, is to have the > perfectHash function accept the RNG seed as a parameter. If the seed worked > first try, great. Otherwise the function would find the seed that does work, > and emit a compile error instructing the programmer to switch the seed > argument to the good one, saving time in future compilations. But he also mentions other strategies (e.g. by length or by a single byte or pair of bytes that differ) - and the good thing is, its compile time. When I have the time (any day now for the past 3 years :( oh well) I'll try to implement something like that - but I thought others would be interested in the mean time,
Re:
I assume OP is referring to the "leftpad" case, in which pulling one one-line package out of NPM caused hundreds of other NPM packages (and thousands of projects that built right off NPM) to stop working. This is a problem with NPM, not with package management in general - CPAN, CRAN, CTAN, Anaconda, PyPI and others have been active for years and even decades with no such mishaps. Packages in any registry, however "real", can disappear because of security or legal reasons. Nimble is way ahead of the game, in that hosting your own copy is a "git clone" away, and this should (in my opinion) be the recommended way to use it.
Re: [RFC] Cyclic imports and symbol dependencies
I am baffled by the need to have circular imports; I think I've been looking for an example in which they are actually needed (rather than "it saves 3 lines and a couple of minutes of reorganization") since Turbo Pascal added them in version 5.5 ; Indeed, dom's suggestion of having a types module has always solved any example I found without requiring circular imports.
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: Nim Dogfooding
If I had a vote, it would be for keeping the forum mostly as is. It is functional. It is easy to use. It is fast. It runs nim code. It does not support nested threads. Neither do many other popular forums, and in my opinion it results in much more focused discussions, especially in smaller communities like Nim currently is (and no, this is not an impediment to growth at this point) It is a fine example for a web+db application written in Nim, for anyone who wants to study such a thing. Also, like HN, it is my impression that the lack of notification contributes to a lively focused discussion.
Re: Been away for 9 months. What changed? Need some help to get back on track.
Most programming today is incredibly bureaucratic. Nim makes programming fun again and does away with a lot of the beaurucracy, the way Python and Lua do; But unlike Python, you don't have to give up static typing, fast runtime, ease of distribution. For now, compared to Python, you give up some aspects of the REPL, and the ecosystem (many packages, a lot of documentation) but I think both of these have improved tremendously.