{"id":16870493,"url":"https://github.com/timotheecour/d_vs_nim","last_synced_at":"2025-03-18T19:46:49.054Z","repository":{"id":54509608,"uuid":"126516369","full_name":"timotheecour/D_vs_nim","owner":"timotheecour","description":"comparison of D vs nim","archived":false,"fork":false,"pushed_at":"2021-02-14T18:13:54.000Z","size":87,"stargazers_count":63,"open_issues_count":11,"forks_count":14,"subscribers_count":8,"default_branch":"master","last_synced_at":"2024-10-14T15:04:33.429Z","etag":null,"topics":["comparison","dlang","nim","nim-questions"],"latest_commit_sha":null,"homepage":null,"language":"Nim","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timotheecour.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-03-23T17:13:49.000Z","updated_at":"2024-07-31T14:23:06.000Z","dependencies_parsed_at":"2022-08-13T18:10:39.606Z","dependency_job_id":null,"html_url":"https://github.com/timotheecour/D_vs_nim","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timotheecour%2FD_vs_nim","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timotheecour%2FD_vs_nim/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timotheecour%2FD_vs_nim/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timotheecour%2FD_vs_nim/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timotheecour","download_url":"https://codeload.github.com/timotheecour/D_vs_nim/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":244293672,"owners_count":20429880,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["comparison","dlang","nim","nim-questions"],"created_at":"2024-10-13T15:04:31.909Z","updated_at":"2025-03-18T19:46:49.025Z","avatar_url":"https://github.com/timotheecour.png","language":"Nim","funding_links":[],"categories":[],"sub_categories":[],"readme":"# D vs nim\n***PR's welcome!***\nGoal: up to date and objective comparison of features between D and nim, and 1:1 map of features to help D users learn nim and vice versa.\n\nNOTE: tables render better (ie full width) with a chrome extension, see https://stackoverflow.com/a/49566642/1426932\n\nNOTE: occasionally, nim code below will use the braces syntax skin to fit in 1 line\n\nHelp welcome, eg by filling in the entries with `?` `TODO` and `CHECKME`, correcting wrong entries, or adding more (see also other files eg libraries.md).\n\n| category | D | nim | 1 for D, -1 for nim |\n| --- | --- | --- | --- |\n| **UFCS** |\n| UFCS supported everywhere | not everywhere, eg: mixin(expr), typeof(expr), local symbols | (called UFCS or MCS in nim) not for `cast`, not for templates/macros with untyped, see https://nim-lang.github.io/Nim/manual.html#templates-limitations-of-the-method-call-syntax |  |\n| **tuple** |\n| tuple unpacking | no | yes:`proc getTup(): auto = (4, \"foo\"); let (_, a) = getTup()` | -1 |\n| **CTFE** |\n| engine | AST interpreter. every expression encountered will allocate one or more AST nodes. Within a tight loop, the interpreter can easily generate over 100_000_000 nodes and eat a few gigabytes of RAM. That can exhaust memory quite quickly. Future work: https://dlang.org/blog/2017/04/10/the-new-ctfe-engine/ | uses a register VM (also the basis of Nimscript); faster | -1 |\n| FFI during CTFE | no | no | 0 |\n| embed directly C/C++ code | no | yes: `emit` | -1 |\n| can read/write/exec during CTFE | read only (string import) | yes; allows filesystem access via staticRead and staticExec;  | -1 |\n| other CTFE limitations | ? | Heap allocated compile-time variables are turned into immutable static/const at runtime. | ? |\n| **OOP** |\n| design | Java like | allows multi-method dynamic dispatch (defined outside, avoiding kitchen sink classes) | -1 |\n| **syntax** |\n| allows local imports | yes | no | 1 |\n| import order irrelevant | yes | ? | 1 |\n| package modules (allows backward compatible breaking of module into package) | yes: https://dlang.org/spec/module.html#package-module | yes but see https://github.com/timotheecour/D_vs_nim/issues/22 | 0 |\n| mutually recursive imports | yes | no, compile-time error. you can use forward declaration and/or \"mixin foosymbol\" to tell the compiler that a symbol will be visible at one point (CHECKME); see also: https://stackoverflow.com/questions/30235080/cannonical-way-to-do-circular-dependency-in-nim, https://github.com/nim-lang/Nim/issues/3961, https://forum.nim-lang.org/t/2114; workaround: The lack of cyclic dependencies in Nim is usually worked around by having a types module | 1 |\n| familiarity | C-like | C or Python-like | 0 |\n| interpolated strings | no | yes | -1 |\n| named parameter arguments | no | yes | -1 |\n| style | (subjective opinion) https://dlang.org/dstyle.html ; style guide for phobos takes too much vertical whitespace (eg braces on their own line) | [Nim Enhancement Proposal #1](https://nim-lang.org/docs/nep1.html) | 0 |\n| **types** |\n| mutually recursive types | yes | these types can only be declared within a single type section (else would require arbitrary symbol lookahead which slows down compilation.) | 1 |\n| nested types | yes | no; but see https://github.com/nim-lang/Nim/issues/7449  | 1 |\n| **semantics** |\n| rvalue references | no | ? | ? |\n| attribute inference | for template functions | ? | ? |\n| Distinction between traced and untraced pointers |  | yes | -1 |\n| forward declarations allowed? | yes | no; see https://github.com/nim-lang/Nim/issues/5287 | 1 |\n| User defined operators | partial: opCall opSlice, opAssign etc | yes | -1 |\n| User defined attributes | yes | ? | ? |\n| RAII | yes (modulo caveats https://github.com/timotheecour/D_vs_nim/issues/27) | no, see: [RAII](https://forum.nim-lang.org/t/362/1) | 1 |\n| prevention of null dereferencing | \u003cp\u003emanual null checks required\u003c/p\u003e \u003cp\u003e`null` pointers to class objects can exist. The only way to check for them is to remember to use `if (myObj is null)`. Lessening the impact of this, many built-in types, such as integers, fixed-size arrays, maps, and struct objects, can never throw `null` dereference errors, either by not being `null` or by treating `null` values as empty values ([source](https://w0rp.com/blog/post/null-and-d-programming-language/)).\u003c/p\u003e | \u003cp\u003emanual null checks required\u003c/p\u003e \u003cp\u003e`nil` references and pointers can exist. The standard way to check for them is to remember to use `if myObj == nil` or `if myObj.isNil`. Lessening the impact of this, many built-in types can never be `nil`, including `seq`s. Only `ptr` and `ref` types (and `cstring`s) can be `nil`.\u003c/p\u003e \u003cp\u003eNim also has an experimental `notnil` feature that enables a [`not nil` type annotation](https://nim-lang.org/docs/manual.html#types-not-nil-annotation), e.g. `ref SomeObject not nil`, to ensure that a variable can never hold `nil`. This feature was made experimental [in 2018](https://github.com/nim-lang/Nim/blob/devel/changelogs/changelog_0_19_0.md#changes-affecting-backwards-compatibility).\u003c/p\u003e | ? |\n| **debugging** |\n| **maturity** |\n| stability | few breaking changes in each release | few breaking changes in each release  | 0 |\n| community | larger |  | 1 |\n| **interop** |\n| C++ | Calpypso (ldc fork) allows direct C++ integration |  | 1 |\n| C++ |  | C/C++ code generation giving us much better interop than what D offers. Case in point: Converting to cstring doesn't require an allocation and copy; see also https://github.com/timotheecour/D_vs_nim/issues/12 | -1 |\n| can compile to js | | yes | -1 |\n| direct use | no | Nim emits C code and you can break in with emit pragma; C code doesn't have to be written outside nim file | -1 |\n| **standard library** |\n| ranges | D ranges (implements empty, front, popFront) | yield-based iterators ; maybe simpler to write but less efficient? not as flexible? (eg: can't do infinite ranges, bidirectional ranges) | ? |\n| variable length arrays | D allows `alloca` | see https://forum.nim-lang.org/t/499 (Variable length array) | ? |\n| slices form pointer + length | builtin, `T[]` | pending https://github.com/nim-lang/Nim/issues/5753 or https://github.com/nim-lang/Nim/issues/8256 | 1 |\n| strings are built from arrays | yes, `immutable(char)[]` | no, different type, so less generic API's | 1 |\n| lazy functional programming (eg map, filter) | yes, eg `std.algorithm` | no (pending https://github.com/nim-lang/Nim/issues/3837, https://github.com/nim-lang/Nim/issues/8188) | 1 |\n| **ecosystem** |\n| contributing | PR's languish forever | PR's get merged way faster in nim (see https://github.com/nim-lang/Nim/pulls vs https://github.com/dlang/dmd/pulls or phobos etc but not sure how to quantify objectively; see also https://github.com/nim-lang/Nim/pulse vs https://github.com/dlang/dmd/pulse). QUOTE: Nim is magnitudes of orders easier to contribute to. Not only the compiler code is easier to reason about (at least for me), but PRs are accepted a lot more willingly. I bet such openness of the core devs makes Nim evolution faster and I hope it's gonna stay that way no matter 1.0. | -1 |\n| repo split | dmd,druntime,phobos | single repo for compiler + stdlib making synchronization easier | -1 |\n| github history | highly intertwined (uses merges) | almost linear (guessing it rebases) | -1 |\n| issue tracker | bugzilla (issues.dlang.org) | github issues (https://github.com/nim-lang/Nim/issues) | -1 |\n| opened/closed bugs | 4588/14061 (https://dlang.org/bugstats.html)  | 1296/3437 https://github.com/nim-lang/Nim/issues | ? |\n| **packages** |\n| packages | dub: https://code.dlang.org/ | nimble: https://nimble.directory/packages.xml and https://github.com/nim-lang/packages | 0 |\n| number of packages (as of 2018/07/13) | 1346 (http://code.dlang.org/) | 704 (`nimble list` ) | 1 |\n| **tooling** |\n| format code | `dfmt --inplace` | `nimpretty`, not yet ready: https://github.com/nim-lang/Nim/issues/7420 | 1 |\n| code reduction for bugs | dustmite | pending https://github.com/nim-lang/Nim/issues/8276 | 1 |\n| REPL | https://github.com/dlang-community/drepl ; https://github.com/callumenator/dabble |  unofficially, you can use `nim secret` but it does not support a lot of things. The most promising is [nrpl](https://github.com/wheineman/nrpl) | ? |\n| **implementation** |\n| GC | single shared memory heap that is controlled by its GC, thread safe, fully conservative, stop-the-world | precise, thread-local heaps, a bit more deterministic and a lot faster, you can even timeframe it if you need consistent 60fps for example. Much better GC implementation for soft real-time applications because it can be paused or the max pause can be tuned. Default GC is not thread safe. GC implementation can be switched at compile-time between deferred reference counting with cycle detection (default), mark and sweep, boehm or no GC (memory regions). Untraced heap-allocated manually managed objects are available (nim distinguishes bw ref and ptr: traced references point to objects of a garbage collected heap, untraced references point to manually allocated objects or to objects somewhere else in memory) | -1 |\n| compile speed | faster (via dmd) CHECKME | | 1 |\n| is compiler bootstrapped? | frontend, not yet backend | yes, and bootstrapping sources can be regenerated from nim allowing compiler sources to use latest features | -1 |\n| error messages uses poisoning/gagging to avoid spurious errors | yes | ? | ? |\n| binary sizes produced |  | produces smaller binaries | -1 |\n| shared library support | linux:OK; OSX: ldc (not dmd); windows: not OK(CHECKME) ; | anything that can be linked from C | -1 |\n| **doc** |\n| builtin doc | ddoc (noisy and nonstandard) | reStructuredText eg `  ## removes `n` from `L`. Efficiency: O(1).` (eg: https://nim-lang.org/docs/lists.html) | -1 |\n| **metaprogramming** |\n| variadic generics | yes: void fun(T...)(T a) | no; [RFC: Variadic Generics](https://github.com/nim-lang/Nim/issues/1019); but `varargs[untyped]` allowed in macros; not same though, eg can't be used in template functions | 1 |\n| partial type template type deduction | yes | no, see https://github.com/nim-lang/Nim/issues/7529 | 1 |\n| supported generic parameters | type, alias, constant | type, alias, constant | 0 |\n| template constraint | `void fun(T)(T a) if(isFoo!T)` | concepts are simpler to use: `type isFoo = concept a (...); proc fun(a: isFoo)` | -1 |\n| macro | no | hygienic macro system instead of string mixin; string mixin are available through `parseStmt`. The macros modify directly the abstract syntax tree given by the parser, before the compiler pass. It is possible to implement new DSLs based on the macro system: for example webserver DSL [jester](https://github.com/dom96/jester/) | -1 |\n| **backend** |\n| available backends | custom (dmd), gcc (gdc), llvm (ldc) | C, C++, js; WIP llvm (https://github.com/arnetheduck/nlvm) | ? |\n\nSee also libraries.md\n\n## features requested in latest D survey (https://rawgit.com/wilzbach/state-of-d/master/report.html) that are already supported in Nim\n* From the D survey question \"What language features do you miss?\", these features are supported in Nim:\ntuples, named arguments, string interpolation, in-place struct initialization, UFCS for local symbols, writing files at compile-time\n* these are doable in library code:\nassert diagnostics, static break\n* these are sort of available:\nStatic inheritance\n\n## compilation time\n* https://forum.nim-lang.org/t/1372\n* tcc instead of clang (but not on OSX, see https://github.com/wheineman/nrpl/issues/16)\n\n## runtime performance\n\n| category/benchmark | D | nim | 1 for D, -1 for nim |\n| --- | --- | --- | --- |\n| functional: [Zero_functional](https://github.com/alehander42/zero-functional); Zero_functional fuses loop at compile-time when chaining zip.map.filter.reduce functional constructs | ? (missing D entry) | nim is currently number 1 or 2 against 9 other langs. The other number 2 or 1 lang being Rust. | ? |\n| webserver | ? | [Mofuw](https://github.com/2vg/mofuw) by @2vg is faster than tokio-minihttp, the current \\#1 on TechEmpower benchmark | ? |\n| parsing csv files | [csv-blog-d](https://dlang.org/blog/2017/05/24/faster-command-line-tools-in-d/) | [csv-blog-nim](https://nim-lang.org/blog/2017/05/25/faster-command-line-tools-in-nim.html); D and Nim had the same speed and same compilation time. fastest CSV parser (to parse GBs of machine learning datasets) is [XSV](https://github.com/BurntSushi/xsv) in Rust | 0 |\n\nSee also https://github.com/timotheecour/D_vs_nim/issues/11\n\n## similar code comparison\n\n| category | D | nim | \n| --- | --- | --- |\n| longest path | https://github.com/logicchains/LPATHBench/blob/master/d.d  | https://github.com/logicchains/LPATHBench/blob/master/nim.nim |\n| csv test | https://github.com/euantorano/faster-command-line-tools-in-nim/blob/master/D/csv_test.d | https://github.com/euantorano/faster-command-line-tools-in-nim/blob/master/Nim/csv_test.nim |\n| rosettacode examples | https://rosettacode.org/wiki/Category:D | https://rosettacode.org/wiki/Category:Nim |\n\n## differences (not clear if pro or con)\n* nim has head immutability unlike D: http://nim-by-example.github.io/types/objects/\n* Indentation based syntax, but supports syntax skins\n\n## map of corresponding features\n| category | D | nim | \n| --- | --- | --- |\n| **syntax:lexical** |\n| nesting block comments | `/+ +/` | `#[ ]#` |\n| documentation comments | `/** */` or `/++ +/` or `///` | `##` or `##[ ... ]##` |\n| WYSIWYG string | `` `foo\\nbar` ``, `r\"foo\\nbar\"`, etc. | `\"\"\"foo\\nbar\"\"\"`, `r\"foo\\nbar\"`, etc.(?) |\n| end of file (useful when debugging) | `__EOF__` | ? |\n| increment | `i++` | `i+=1` or `inc(i)` |\n| concatenation | `~` | `\u0026` |\n| empty statement | `{}` | `discard` |\n| null pointer | `null` | `nil` |\n| checking for null | `if (myObj is null)` | `if myObj == nil` or `if myObj.isNil` |\n| **syntax:parsing** |\n| alias | `alias T2=T;` | ?; template, see https://github.com/nim-lang/Nim/issues/7090 |\n| type alias | `alias T2=T;` | `type T2=T` |\n| string mixin | `mixin(\"1+1\")` | `stringMixinLikeInD(\"1+1\")` with: `macro stringMixinLikeInD(s: static[string]): untyped = parseStmt(s)` source: https://forum.nim-lang.org/t/1779/2#19060 |\n| UFCS | `foo(a, b)`, `a.foo(b)` | `foo(a, b)`, `a.foo(b)`, `a.foo b`, `foo a, b` |\n| expr without parenthesis | `auto a=fun;` calls `fun` | `var a=fun` returns `fun` |\n| UFCS expr without parenthesis | `auto a=b.fun;` calls `fun` | `var a=b.fun` calls `fun` (when b is arg, not module) |\n| static if .. else if .. else| `static if(foo1) bar1 else if(foo2) bar2 else bar3` | `when foo1: bar1 elif foo2:bar2 else:bar3`  |\n| conditional compilation | `version(OSX)` | `when defined(macosx)` |\n| compile time if | `static if` | `when` |\n| string import | `import(\"foo\");` requires `-J` for security | `staticRead(\"foo\")` |\n| public import | `public import foo;` | `import foo; export foo;` |\n| static import | `static import foo;` | `from foo import nil` |\n| package fully qualified access | `pkg.mod.symbol();` | `symbol()` (`pkg.mod.symbol` illegal) |\n| **syntax:exceptions** |\n| scope guards | `scope(exit) foo`, `scope(success) foo`, `scope(failure) foo`,  | `defer: foo`, ? , ? ; see also https://forum.nim-lang.org/t/141/1#23104 |\n| try throw catch finally | \u003ccode\u003etry{throw new Exception(\"bar\");}\u003cbr\u003ecatch(Exception e) {writeln(e);}\u003cbr\u003efinally {}\u003ccode\u003e  | \u003ccode\u003etry: raise newException(IOError, \"test exception\")\u003cbr\u003eexcept IOError: (let e = (ref IOError)(getCurrentException()); echo e[])\u003cbr\u003efinally: discard\u003ccode\u003e |\n| **syntax:array** |\n| static array literal | `int[2] a = [1,2];` | `var a = [1,2]` |\n| dynamic array literal | `auto a = [1,2];` | `var a = @[1,2]` |\n| dynamic array create | `auto a = new int[2];` | `var a = newSeq[int](2)` |\n| empty dynamic array | `auto a = [];` | `var a:seq[int] = @[]` |\n| indexing slice of a | `a[1..$], a[1..$-1], a[1..3]` | `a[1..^1], a[1..^2], a[1..\u003c3]` |\n| length | `a.length;` | `a.len` |\n| **types** |\n| initial value of type | `T.init` (known at CT) | ? |\n| type of | `typeof(expr)` | `expr.type` |\n| type name | `T.stringof` (builtin) | `T.name` (import typetraits) |\n| class | `class A : B` | `type A = ref object of B` |\n| struct | `struct A` | `type A = object` |\n| float: 32, 64 bit | float, double | float32, float(float64) |\n| pointer sized int, uint | ptrdiff_t, size_t | int, uint |\n| sized ints | byte, short, int, long | int8, int16, int32, int64 |\n| char types | char, wchar, dchar  | ?,?,? |\n| **functions** |\n| delegates | `int delegate(int, int)` | `proc (a, b: int): int {.closure.}` |\n| **decl** |\n| variable decl | `auto a=foo;` | `var a=foo` |\n| immutable decl | `immutable foo=bar;` | `let foo=bar` |\n| compile time decl | `enum foo=bar;` | `const foo=bar` |\n| shared static | `__gshared a = 0;` | `var a {.global.} = 0` ? |\n| static TLS | `static a = 0;` | `var a {.threadvar.} : int` |\n| ref return | `auto ref fun(ref A a){ return a.x;}` | `proc fun(a:var A):var a.x.type = return a.x` |\n| skip initialization | `T a = void;` | `var a {.noInit.}: T` |\n| **attributes** |\n| purity | `pure` | `{.noSideEffect.}` |\n| nothrow | `nothrow` | `{.raises: [].}` |\n| safe | `@safe` | ? |\n| GC free | `@nogc` | ? |\n| lockfree | ? | `{.locks:0.}` |\n| **language** |\n| unit tests | `unittest{stmt}` | https://nim-lang.org/docs/unittest.html |\n| constructor | `T(args)` | ad-hoc: `newT(args)`, but see https://github.com/nim-lang/Nim/issues/7474 |\n| **semantics** |\n| float.init | NaN | 0 |\n| file | `__FILE__` | instantiationInfo; limitation: doesn't work for function caller, cf https://github.com/nim-lang/Nim/issues/7406 |\n| **traits** |\n| does expr compile | `__traits(compiles, expr)` | `compiles(expr)` |\n| get fields | `T.tupleof` | `x.fields` |\n| **metaprogramming** |\n| static assert | `static assert(foo);` | `static: assert foo` |\n| **library** |\n| universal type conversion | a.to!T | no: https://github.com/nim-lang/Nim/issues/7430 |\n| option/maybe type | [`Nullable`](https://dlang.org/phobos/std_typecons.html#.Nullable) in `std.typecons` | [`Option`](https://nim-lang.org/docs/options.html) in the `options` module |\n| path append | a.buildPath(b) | a / b ; does right thing on windows; NOTE: if b is absolute, buildPath returns b unlike nim |\n| **cmd line** |\n| custom define | -version=foo | --define:foo or --define:foo=bar |\n| **resources** |\n| tutorials | https://tour.dlang.org/ | https://nim-lang.org/docs/tut1.html |\n| **tools** |\n| caching compiler | rdmd | nim (compiles dependencies; only compiles changed file by default); https://github.com/Jeff-Ciesielski/nimr (subset of functionality) |\n| find declaration | dscanner --declaration | nimgrep (but no declaration search, cf https://github.com/nim-lang/Nim/issues/7419) |\n| fix code | dfix | nimfix |\n| package manager | dub | nimble |\n| install specific compiler versions | digger | choosenim |\n\nSee also libraries.md\n\n## links\n* https://www.slant.co/versus/118/395/~d_vs_nim\n* https://forum.nim-lang.org/t/1779 Nim vs D\n* https://forum.dlang.org/post/mailman.1536.1428946094.3111.digitalmars-d@puremagic.com D vs nim\n* http://gradha.github.io/articles/2015/02/goodbye-nim-and-good-luck.html\n* https://www.quora.com/Of-the-emerging-systems-languages-Rust-D-Go-and-Nim-which-is-the-strongest-language-and-why\n* https://github.com/kostya/benchmarks\n* https://digitalmars.com/d/archives/digitalmars/D/D_and_Nim_251571.html\n* https://forum.nim-lang.org/t/1983#12391 A few questions about Nim\n\n## nim questions (besides entries marked above with `?`)\n* does it have dfmt equivalent?\n* instead of `newSeq` could we write `new!Seq` or new[Seq] or anything else that's generic and doesn't pollute namespace?\n\n* how to use dirty templates/macros that require an import? eg:\n```nim\ntemplate foo*() {.dirty.} { #[want: import os ]# let programName = getAppFilename() }\n```\n\n* how to compose arbitrary ranges/iterators in Nim?\n\n* how to define a slice of type T from ptr + length?\ncf https://github.com/nim-lang/Nim/issues/5437 feature-request pointer size pair, (openArray as value) #5437\n\n## nim questions (answered)\n* are there real immutable variables in nim ?\nA: https://www.reddit.com/r/nim/comments/2w32oi/immutability_in_nim/\n* how to specify immutable inside `for(foo in bar)` ?\nA: immutability depends on iterator and by default iterators return immutable values.\n```\nvar a = @[1, 2, 3, 4]\nfor item in a: item += 5  # compile-time error\nfor item in mitems(a):  item += 5  # ok\n```\n* how to search for symbols `fooBar` given that nim allows foobar fooBar foo_bar etc?\nA: nimgrep; also: Nim provides \"nimsuggest\" that can be used for vim, emacs, vscode, atom that autocompletes\n\n* how to use global variables? (cf http://gradha.github.io/articles/2015/02/goodbye-nim-and-good-luck.html)\nA: Non-const global vars are not allowed in proc tagged noSideEffects and care must be used if accessed from multiple threads but there is nothing special about them otherwise.\n\n* can we modify a slice of an immutable array declared by 'let'?\nA: Slicing doesn't return a var T for let arrays so you can't. Note that immutability for stack objects/array/types is deep but for ref/ptr types it is shallow, it means that the memory address pointed to cannot be modified but the content can.\n\n* is there a robust way to write complex nim functions as a one liner (eg, for use in 1 line docs, in REPL etc); ideally by replacing indentation with braces\nA: `(st1; st2; st3)`, or undocumented braces syntax skin:\n```nim\n#? braces\n\nproc main() {\n  echo \"Hello\"\n}\n\nwhen (isMainModule) {\n  main()\n}\n```\n\n## no longer valid points\nhttps://forum.nim-lang.org/t/1779/1#11314 =\u003e dmd backend license was changed recently\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimotheecour%2Fd_vs_nim","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimotheecour%2Fd_vs_nim","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimotheecour%2Fd_vs_nim/lists"}