News for hackers. Stuff that matters.
Re:Nim Programming Language v0.16.0 released by gravypod on Monday January 09, 2017 @10:25AM (#13356946)
I don't want to be that guy but I don't see this language as usable. Not because of technical reasons but because... I mean... look at it. I can't understand what's going on. It's way too complicated.

   type Vector* {.importcpp: "std::vector", header: "<vector>".}[T] = object

   template `[]=`*[T](v: var Vector[T], key: int, val: T) =
     {.emit: [v, "[", key, "] = ", val, ";"].}
What the hell does that mean?How the hell do I check this is correct at a glance?

I know "it's easy", "you'll get used to it", "after you learn the syntax it'll be great" but I mean... no one is going to buy that.

I get that it's supposed to be condenced but I don't necassarily buy that as being the end-all-be-all of language construction. I think that's actually quite harmful to programmers. If a single character means the same as 10 lines of a simpler language then you're more likely to hide a mistake in your code.

I'm not saying it's wrong either, I'm just saying a majority of programmers will be afraid of it. I rather like what swift is trying to do with condensing well-known operations but I don't think Nim and many other ML-inspired languages do it in an approchable way.

Re:Nim Programming Language v0.16.0 released by majewsky on Monday January 09, 2017 @10:35AM (#13357032)
It took me a moment to parse, but that snippet is actually pretty straight-forward when you know that Nim compiles down to C (or C++).

  type Vector* {.importcpp: "std::vector", header: "<vector>".}[T] = object
This obviously creates a type "Vector" whose underlying implementation is C++'s "std::vector". (I don't know how writeable it is, but it is* readable.)

  template `[]=`*[T](v: var Vector[T], key: int, val: T)
Function declaration syntax for operator overloads is hard to make readable (as in: familiar). In fact, this is about as readable as it can get (although I'm confused by the "*[T]").

  = {.emit: [v, "[", key, "] = ", val, ";"].}
As I said, when you know that the compiler generates C code, this makes a lot of sense. It's a compiler instruction to compose a string of C code.
Re:Nim Programming Language v0.16.0 released by vgbm on Monday January 09, 2017 @12:54PM (#13358165)
To supplement the other response, [T] declares a generic type, so [T] is a public method with the generic type T. I'd agree though that the is initially hard to parse, especially when taking C and C++ into account, where * means something entirely different.
Re:Nim Programming Language v0.16.0 released by evacchi on Monday January 09, 2017 @12:26PM (#13357940)
> (although I'm confused by the "[T]").

the `*` marker means that the proc/template is "public" (not local to the module)

Re:Nim Programming Language v0.16.0 released by pathsjs on Monday January 09, 2017 @10:36AM (#13357035)
Well, the example you are looking at is very complex, but also you are very unlikely to run into it early! For better examples, look at the homepage: you will see something much more approachable.

The reason this snippet is complex is that:

1. It deals with the Foreign Function Interface

2. It deals with the FFI with respect to C++, which is much more complex than the one towards C, essentially because C++ itself is complex

3. It uses a particular construct (emit) that is only needed when the standard FFI is not enough

So the example is really a showcase of a particularly complex case that you will likely not encounter, unless you start wrapping C++ libraries (which is not an easy task, unlike the C ones)

Re:Nim Programming Language v0.16.0 released by gravypod on Tuesday January 10, 2017 @03:22PM (#13368602)
That was the first code snippet on the website that I saw.
Re:Nim Programming Language v0.16.0 released by arc776 on Monday January 09, 2017 @10:53AM (#13357195)
To be fair, this is library FFI code so this is actually for interfacing with C++ rather than 'native' Nim. Probably not something you'd encounter unless you're making a library wrapper.

And if you are doing that, worth mentioning too that Nim has a utility c2nim that automatically translates headers for FFI access.

The first line imports the C++ std::vector type and allows you to use it in Nim. To me that seems pretty good as a one liner to import a complex type from another language.

The second line is using a template to wrap the FFI call so you can use indexing operations and generic variables with the vector.

The `[]=` is describing how to write to std::vector in nim using indexing, eg; "myVec[5]=123"

Re:Nim Programming Language v0.16.0 released by lobster_johnson on Monday January 09, 2017 @01:03PM (#13358260)
That example is complicated because it interfaces with C++ and defines a macro. Most Nim code looks nothing like that.

> I don't think Nim and many other ML-inspired languages

I don't think Nim is particularly ML-inspired. Nim's main point of influence is Turbo Pascal/Delphi and their deratives, which used to be obvious from all the "T" prefixes (TObject and so on, now largely or entirely gone from the language). Nim has things like ranges and enums, both of which come directly from Pascal.

Re:Nim Programming Language v0.16.0 released by amyjess on Monday January 09, 2017 @04:53PM (#13360160)
There's also a lot of Modula-3 in Nim, too. Which makes sense: Modula-3 is also a Pascal derivative, and there's a lot of Modula-3 in Python, which Nim borrows syntax from, too.
Re:Nim Programming Language v0.16.0 released by lobster_johnson on Monday January 09, 2017 @05:01PM (#13360231)
There's so much overlap between the Wirth languages that I am not surprised about that. What specifically comes from Modula-3, though?

I didn't know that Python was influenced by Modula. Any examples? Keyword arguments is the only that comes up on Google.

Re:Nim Programming Language v0.16.0 released by amyjess on Monday January 09, 2017 @05:28PM (#13360416)
> What specifically comes from Modula-3, though?

Off the top of my head, the equivalency of "foo.bar(baz)" and "bar(foo, baz)" was inspired by Modula-3's object model, though Nim extends it to everything and not just classes. Also, Wikipedia tells me the pointer system comes from Modula-3.

Nim's official FAQ also lists Modula-3 as the single biggest influence; I have a feeling that a lot of the Wirth-isms in Nim were borrowed from Modula-3 rather than from Pascal, even if they appeared in both languages.

> I didn't know that Python was influenced by Modula. Any examples? Keyword arguments is the only that comes up on Google.

Off the top of my head:

- The module system. The syntax of "import foo" and "from foo import bar" were borrowed from Modula-3 verbatim, and Guido got the idea to give Python a module system in the first place because Modula-3 convinced him modules were the future.

- The exception system. A lot of people don't notice the exception system because pretty much every language in the '90s also borrowed that from Modula-3 (the try-catch paradigm was invented by Modula-3), but Python hews even closer to the Modula-3 model by using the word "except" instead of "catch" and allowing for multiple except blocks attached to a single try block.

- The object system is a hybrid of Modula-3 and C++; the whole idea of passing "self" as the first parameter to a method instead of having an implicit "this" was a Modula-3 thing. The official Python documentation still references it: https://docs.python.org/3/tutorial/classes.html

Guido also talks about the Modula-3 influence in a few places:

https://docs.python.org/3/faq/general.html#why-was-python-cr...

http://www.artima.com/intv/pythonP.html

Re:Nim Programming Language v0.16.0 released by lobster_johnson on Monday January 09, 2017 @06:06PM (#13360730)
Hm, is this official, or are you deducing this from similarities?

I wish Andreas Rumpf were here to comment and hopefully correct me, but I believe he was formerly an ObjectPascal/Delphi programmer. The first version of the Nim compiler was written in Borland's ObjectPascal dialect (see http://nim-lang.org/docs/intern.html), which has some of the same features as Modula, but with a slightly more circuituous lineage, since it was originally based on Apple's Object Pascal, a dialect which Wirth was tangentially involved in designing. (Object Pascal predates Modula-3, too.) In that sense, some of the similarities are probably accidental or caused by cross-pollination (for example, Borland probably took the exception handling syntax from Modula). That's the problem of trying to infer lineage by looking at similarities alone.

The unified call syntax sounds like it might be lifted directly from Modula, though.

Thanks for the Python trivia, I didn't know that.

Re:Nim Programming Language v0.16.0 released by mrkgnao on Monday January 09, 2017 @10:44AM (#13357104)
Macros implemented with ... string interpolation? This looks like a suboptimal idea.

Edit: I spoke too soon. This looks like code generation, and I guess that you ultimately have to do stringy things at some point. But couldn't there be some kind of type-safe mechanism for this?

Re:Nim Programming Language v0.16.0 released by Tarean on Tuesday January 10, 2017 @08:37AM (#13364626)
There are basically three ways to do meta programming in nim. Simple replacement of tokens:

    const debug = true
    template log(msg: string) =
      if debug: stdout.writeLine(msg)

You could also use other concrete types, generics and type checked or unchecked expressions instead of string.

Macros are syntax tree transformations, similar to rust compiler plugins:

    import macros, strutils

    macro readCfgAndBuildSource(cfgFilename: string): typed =
      let inputString = slurp(cfgFilename.strVal)
      result = newStmtList()

      for line in inputString.splitLines:
        # Ignore empty lines
        if line.len < 1: continue
        var chunks = line.split(',')
        if chunks.len != 2:
          error("Input needs comma split values, got: " & line)
        let entry = quote do:
          const cfg`chunks[0]` = "`chunks[1]`"
        result.add(entry)
  
      if result.len < 1: error("Input file empty!")

    readCfgAndBuildSource("data.cfg")

This reads a file and creates constants from it at compile time.

Emit is a tad more complex. Nim is compiled to another language like c, c++ or llvm. Emit lets you emit code in the host language, mostly to wrap libraries. Don't think there is any way to make that typesafe.

Re:Nim Programming Language v0.16.0 released by evacchi on Monday January 09, 2017 @12:27PM (#13357951)
you can do both; you can opt-out of the type-safe mechanism and decide to just emit arbitrary code; it's a just one more tool in your belt
Re:Nim Programming Language v0.16.0 released by arc776 on Monday January 09, 2017 @10:48AM (#13357152)
Macros & templates are AST based.
Re:Nim Programming Language v0.16.0 released by pdexter on Monday January 09, 2017 @10:50AM (#13357171)
Nim is ML-inspired? How so?

Anyways, it looks like this is a code emitting example? I'm guessing the average user would never use that feature. I don't now nim but this is just an assumption. So I think we can let this one pass.