Live data from Hacker News

Nim 1.6.2

nim-lang.org

111–120 of 162 posts

Re: Nim 1.6.2

#111
post #106

Earlier quoted context omitted.

> Not OP, but they are referring to `import std/strformat` (from homepage). > That just imported things into the global namespace. That's what tripped me up: there's definitely no such thing as importing into GLOBAL namespace. That's an import into a top-level (true) namespace of a MODULE. In Python, if you put something into the dict returned from `globals()`, you are indeed importing into global namespace, but I've…

Cool thanks for the info. Nim having selective imports solves any annoyances I would have. But you mentioned all the reasons it was ok in Nim. But the answer is always that the compiler knows. That isn’t why I personally dislike this type of import. I dislike it as a user. I find it super annoying not knowing where an identifier is coming from. I love having ‘fmt.Printf()’ instead of ‘Printf()’. Trivial example I kno…

There's a reason why wildcard/selective[1] imports are favored in Nim. It's because of the uniform function call syntax[2]. In short, this:

    split("a string", " ")
is exactly the same thing as this:

    "a string".split(" ")
`split` here is a normal function, not any kind of method. This means that you can chain normal functions as if they were methods on objects:

    "a string".split(" ").join("\n")
now, if you imported modules instead of functions themselves, how would that look like?

    sequtils.join(strutils.split("a string", " ") "\n")
or, if you wanted to keep uniform call syntax, you'd have to invent some new syntax:

    "a string".split(" ").join("\n")
Which also doesn't look very appealing.

So, there are trade-offs here, and you obviously might not like the choices made by Nim, which is fine! But, there are reasons for the design decisions made by the language implementers, and they are almost never predicated on a single feature: all the features of a language interact with each other, sometimes in very strange and unpredictable ways. So it makes sense to consider the features your interested in the proper context :)

[1] `import modname` and `from modname import fun1, fun2`

[2] https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax

Re: Nim 1.6.2

#112

Earlier quoted context omitted.

There are two kinds of case-insensitivity in identifiers. In either cases identifier cases (and in this case, also underscores) are normalized, but case-agnostic languages would allow any mix of them while case-pedantic languages would disallow any pair of identifiers normalizing into the same name (they may still give helpful errors based on that normalized name though). I don't think case-agnostic languages provide…

Nim provides the benefit of both: when interfacing with C libraries a case-agnostic language helps. Yet, checks on function definition and types has the same benefit of case-pedantic language, without forcing a specific style on the developer.

It is okay to have a feature (NOT necessarily this feature) that translates other conventions to a single consistent convention; for example a language may convert a name "foo_bar" into "fooBar" when used in C bindings, preferably with an escape hatch. However case-agnostic languages do not try to do that, they give zero indication for what convention to use (cf. function names in PHP, which is a horrible mess). No single convention is better than others, but a single consistent convention does matter.

Re: Nim 1.6.2

#113

Nim is everything Python and Go should be/want to be, as far as language features and semantics go (haha). It has their easy-to-learn properties, but has a better type system, the generics system and macros are arguably more useful, and more usable than what is offered in either language. It deserves far more attention than it currently gets.

I like Nim, and probably will learn it at some point. But no, Nim is not everything "python should/want to be". The name case insensitivity and the implicit imports on the global namespaces are perfect examples of stuff that are better in Python.

I don't think Nim has anything that I'd call a "global namespace". By default importing a module will include its exported symbols into the local module, but that doesn't impact anything globally.

In my opinion, this is the correct default, at least for Nim. Operator overloading and UFCS (https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax) don't really work if I have to prefix everything with a module name, and the static nature of Nim means that I'll get a compiler error if there's any ambiguity. There are downsides as well, but language design is all about tradeoffs, and I think Nim got this one right.

Regarding the case insensitivity, I was initially put off by this as well, but in 2 years of using Nim as my primary language, I have never, ever, encountered a real-life issue with it. I've never seen a Nim code base that uses mixed casing, and never encountered or heard of a bug caused by this behaviour. However, it has allowed my own code bases to stay 100% consistent, regardless of the code style of my dependencies, even when those dependencies written in other languages. Contrast this with Python where the `logging` module uses different casing than everything else, so you're forced to use an inconsistent style if you want to consume it. This type of thing is a non-issue in Nim. I think a case sensitive Nim would still be a fine language, but in my experience the pros of being mostly insensitive outweigh the cons.

In the end you may still disagree with both of these decisions, which is fine. Just understand that it's a nuanced discussion, and there's some solid reasoning behind their choices.

Re: Nim 1.6.2

#114

Earlier quoted context omitted.

It's the normal compilation flag for performant code. The word "danger" is scary, but it's simply disabling debugging code: debug assertions, full stacktraces, extra safety checks.

I suppose the makers of Nim named that flag for a reason - giving up memory safety by disabling bounds/overflow checks should be never be the default for networked software in a production setting, so benchmarking in that mode would paint an unrealistic picture. What you want are comparable compiler flags across languages, say "optimized for performance, yet retaining safety" and "go as fast as possible and disable a…

"disable all brakes" is misleading. All the basic memory safety stays, static typing is still there, non-debug assertions are still checked.

Removing debugging features is reasonable for such benchmarks, especially if comparing with languages that don't have them.

Re: Nim 1.6.2

#115

Earlier quoted context omitted.

Consider either Rust or Go of you want something easier than C++, but that still has a large community and lots of learning resources.

Go yes. Rust? I wouldn’t say that Rust is easier although I may be biased with my long C/C++ background. The ownership model is a pretty complex thing to learn. I guess maybe if you Box a lot? It does have an easier on-ramp story for getting started/adding dependencies and that may be important for getting started.

> The ownership model is a pretty complex thing to learn

It is, but if you want to write C or C++ that doesn't crash, or just silently work incorrectly then you have to internalise these rules anyway. And having a compiler that gives you a helpful error message when you get it wrong is much easier than getting a segfault at runtime that may not even occur in a proximate part of the code. Let me put it this way: in 5 years of using Rust I am yet to need a debugger, and only need even println debugging rarely.

Re: Nim 1.6.2

#116

Earlier quoted context omitted.

Go yes. Rust? I wouldn’t say that Rust is easier although I may be biased with my long C/C++ background. The ownership model is a pretty complex thing to learn. I guess maybe if you Box a lot? It does have an easier on-ramp story for getting started/adding dependencies and that may be important for getting started.

> The ownership model is a pretty complex thing to learn It is, but if you want to write C or C++ that doesn't crash, or just silently work incorrectly then you have to internalise these rules anyway. And having a compiler that gives you a helpful error message when you get it wrong is much easier than getting a segfault at runtime that may not even occur in a proximate part of the code. Let me put it this way: in 5…

That’s not strictly true IMO. There are things that are trivially expressible in C++ that require a lot of complexity on the Rust side to prove to the compiler the code is safe.

I don’t disagree with you on the safety aspects* and 100% real production code should really be starting in Rust. From a learning perspective though… not as sold yet. There’s a lot of things nicer (the stdlib is 100x better and more ergonomic and more pythonic in terms of “batteries included”). There’s a different set of edges though and none of the ownership concepts you learn really transfer anywhere else so you’re learning Rust’isms but not general systems programming things (just like goroutines teach you Go’isms and not what high performance thread safety means).

* The debugger claim feels specious because segfaults aren’t the only source of bugs that need debugging. How do you deal with an unexpected panic or logic bugs?

Re: Nim 1.6.2

#117
I love Nim's syntax, but is there a specific reason why e.g. the SFML binding cannot imitate C++ RAII approach of handling resources? There is .close everywhere.

Re: Nim 1.6.2

#118

Nim is everything Python and Go should be/want to be, as far as language features and semantics go (haha). It has their easy-to-learn properties, but has a better type system, the generics system and macros are arguably more useful, and more usable than what is offered in either language. It deserves far more attention than it currently gets.

I like Nim, and probably will learn it at some point. But no, Nim is not everything "python should/want to be". The name case insensitivity and the implicit imports on the global namespaces are perfect examples of stuff that are better in Python.

If you have 'myvar' and 'myVar' in some code there are three things you could do.

1) The compiler gives you an error, this would be my preferred solution though I'm not aware of any language that does that.

2) These end up referring to the same variable with no error. Nim's solution.

3) These are actually different variables with no error. The common solution.

Again, I would prefer (1) but I think that (2) is a safer way of handling the situation than (3).

Re: Nim 1.6.2

#120

Earlier quoted context omitted.

Consider either Rust or Go of you want something easier than C++, but that still has a large community and lots of learning resources.

Go yes. Rust? I wouldn’t say that Rust is easier although I may be biased with my long C/C++ background. The ownership model is a pretty complex thing to learn. I guess maybe if you Box a lot? It does have an easier on-ramp story for getting started/adding dependencies and that may be important for getting started.

> I wouldn’t say that Rust is easier

Rust is easier than C/C++, but not at first. After you learn the semantics of it, is very smooth sailing (at least until you get into the most exotic needs like build your own async runtime).

Post reply on HN