HNHacker News
TopNewBestAskShowJobs

jboy

346 karma · joined August 10, 2010

Co-founder of ObjectAI.com

Co-creator of Pymod: https://github.com/jboy/nim-pymod

submissionscomments
jboy··on Using D and std.ndslice as a Numpy Replacement
It looks like you need to copy your D array to a newly-allocated Numpy ndarray before you can pass it to Python. So there's no binary PyArrayObject interoperability between D & Python (right?). Copying large N-D arrays all the time sounds slow...

(That Matplotlib example uses the function `d_to_python_numpy_ndarray` in the PyD project, which I found defined here: https://github.com/ariovistus/pyd/blob/master/infrastructure... . It clearly allocates a new Numpy array: https://github.com/ariovistus/pyd/blob/master/infrastructure... )

Also, I couldn't find any examples of invoking D functions from Python. In fact, I could only find mentions on the D mailing list of people reporting that they couldn't get it to work: http://forum.dlang.org/post/rdhrvzhhwxgfyxzjevfu@forum.dlang...

By compiling (transpiling) to C, Nim really does have an unfair advantage in the interoperability challenge...

jboy··on Using D and std.ndslice as a Numpy Replacement
Credit to the D developers for providing a concise, carefully-designed library for N-D array processing. The chained method invocations demonstrate D's UFCS (Uniform Function Call Syntax) nicely. And it's a definite bonus that you can use underscore like a comma separator in long integer literals (eg, `100_000`).

But if you use Python + Numpy/Scipy/Matplotlib and you're looking for a modern, compiled language for execution speedups or greater flexibility than what Numpy broadcasting operations provide by default, I would recommend Nim. It's as fast as C++ or D, it has Pythonic syntax, and it already includes many of D's best features (including type inference, UFCS, and underscores in integer literals).

And best of all, you don't need to rewrite all your existing Python+Numpy code into a new language to start using Nim.

The Pymod library we've created allows you to write Nim functions, compile them as standard CPython extension modules, and simply drop them into your existing Python code: https://github.com/jboy/nim-pymod

The Pymod library even includes a type `ptr PyArrayObject` that provides native Nim access to Numpy ndarrays via the Numpy C-API [ https://github.com/jboy/nim-pymod#pyarrayobject-type ]. So you can bounce back and forth between your Python code and your Nim code for the cost of a Python extension module function call. All of Numpy, Scipy & Matplotlib are still available to you in Python, in addition to statically-typed C++-like iterators in Nim+Pymod [ https://github.com/jboy/nim-pymod#pyarrayiter-types , https://github.com/jboy/nim-pymod#pyarrayiter-loop-idioms ]. The Nim for-loops will be compiled to C code that the C compiler can then auto-vectorize.

jboy··on Pybind11 – Seamless operability between C++11 and Python
In general in Nim (see footnote for fine print), `obj.someFunc` == `obj.someFunc()` == `someFunc(obj)` [0]. It's not a method bound to an object, as in `obj.method` in Python. So whenever there is some `obj.` in front of the function name, that's an argument being passed to a function call.

[0] http://nim-lang.org/docs/manual.html#procedures-method-call-...

You can pass functions as first-class values (which Nim calls "procedural types" [1]) by supplying the function name without any arguments or parentheses, eg, `someFunc` on its own.

[1] http://nim-lang.org/docs/manual.html#types-procedural-type

The base case occurs when the function takes no parameters: In this case, `someFunc` is a procedural type; `someFunc()` is a function invocation.

Footnote for interested readers: closures [2]; setter properties [3]; multi-methods that use dynamic dispatch [4].

[2] http://nim-lang.org/docs/manual.html#procedures-closures , [3] http://nim-lang.org/docs/manual.html#procedures-properties , [4] http://nim-lang.org/docs/manual.html#multi-methods

jboy··on Pybind11 – Seamless operability between C++11 and Python
See, this is why I compare it to Python's OSR syntax.

People react with these strong responses ("plainly bat-shit crazy"). People focus on inconveniences due to the limitations of limited tools ("I don't want to press spacebar FOUR TIMES at the start of EVERY line of code!"). People come up with elaborate worst-case hypotheticals ("What if you want to share your code with someone using a pastebin service that removes leading whitespace?") that just don't happen in practice.

In practice, it's just all upside and no downside. Now I don't need to remember whether it's `openHTTPConnection()`, `openHTTPconnection()`, `open_http_connection()`, `openHttpConnection()`, etc. If I can say it, I know how to type it.

Any ambiguous overloads (same name, same parameter types -- which again, really doesn't occur by accident in practice) will be reported & resolved at compile-time. There's no more mystery in this than there is in any function overloading scenario.

And in practice, it seems to cause the opposite of holy wars: People realize how pointless all those identifier case-wars are in the first place.

There's really not much more that I can say. "In my experience, there's no downside to this feature, only upside."

jboy··on Pybind11 – Seamless operability between C++11 and Python
If your functions take any parameters, Nim will use the parameter types to distinguish between them, just like C++ does when you overload functions.

OTOH, if your hypothetical is that programmer X writes `to_me()` while a different programmer Y writes `tome()`, and the two functions just happen to be identical in all parameter types... well, that can already happen anyway where two programmers each independently write a function with the same name.

Nim has a simple, clear specification of how identifiers will be compared: http://nim-lang.org/docs/strutils.html#normalize,string

There's no secret magic happening.

jboy··on Pybind11 – Seamless operability between C++11 and Python
Nim has made 4 syntax choices that might seem bizarre to a C++ programmer: 1. blocks by indentation instead of braces (aka "Off-Side Rule" syntax [0]); 2. Uniform Function Call Syntax [1][2]; 3. case-insensitivity for identifiers; and 4. dropping empty parens from a function call.

[0] https://en.wikipedia.org/wiki/Off-side_rule , [1] https://en.wikipedia.org/wiki/Uniform_Function_Call_Syntax , [2] http://nim-lang.org/docs/manual.html#procedures-method-call-...

Choice #2, Uniform Function Call Syntax (UFCS), allows you to write `a.someFunc(b)` or `someFunc(a, b)` interchangeably.

Choice #3 is case-insensitivity for identifiers: You can write `a.to_lower()`, `a.toLower()` or `a.tolower()` interchangeably.

Choice #4 is the ability to drop empty parens from the end of a function call: `a.len()` can be written as `a.len`. Combined with UFCS, this allows you to write `len(a)`, `a.len()` or `a.len` interchangeably.

I'd already been programming Python for years, so I wasn't surprised by choice #1 -- in fact, I was pleased. After initially being highly skeptical of Python's OSR syntax when I first encountered it, I've since come around completely. The most common complaint against Python's OSR syntax is that it allows both tabs & spaces, interchangeably, which has bitten just about everyone who has ever used Python in a team. Nim avoids this problem by allowing only spaces to be used for indentation, not tabs: http://nim-lang.org/docs/manual.html#lexical-analysis-indent...

My eyebrows certainly went up about #2, #3 and #4 when I first encountered them. But you know what? Much like Python's OSR syntax, I've now come around completely. Now I actually prefer #2, #3 and #4 the way Nim does them. When I'm back in Python, C++ or C, I wish they behaved the same way as Nim!

Think about it: How many stylistic debates have there been about whether an operation in C++ should be a function or a method? How many times have you pondered whether an object attribute should be a member or a method? It's just a distracting detail with no benefit. And now you don't need to care! Apparently Bjarne Stroustrup is a convert to UFCS too: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n417...

Nim is, above all, a pragmatic language. I think that in another 5 or so years, Nim's syntax choices #2, #3 and #4 will seem just as sensible as #1 seems to Python programmers today.

jboy··on Pybind11 – Seamless operability between C++11 and Python
If you like to program in C++ and Python, the Nim language might appeal to you: C++-like features (generic types, operator overloading, function overloading, inline functions, optional O-O, optional data hiding, C pointers, bitwise-compatibility with C, your choice of manual memory management or GC) and C++-like run-time speed, combined with Python-like syntax and compile-time Lisp-like macros.

I spent most of a decade mastering pre-11 C++, learning to apply the recommended tricks & idioms (like the copy-swap idiom for strong exception safety guarantees), learning to sidestep the gotchas. Meyers books, Sutter books, GotW, "Modern C++", etc. Then, when C++11 came out, the language became even more complicated, not less. That was a breaking point for me.

As a long-time programmer (and fan) of both C++ and Python, Nim offers the best balance that I've yet found between C++'s ethos of thoughtful, precise control and Python's user-friendliness.

(And if you ever happen to need seamless Nim-Python compatibility, including native Nim support for Numpy arrays with C++-style iterators, my Pymod project may be of assistance: https://github.com/jboy/nim-pymod )

jboy··on Python C API, PyPy and the road into the future
> CPython for-loops are slow. PyPy for-loops are not slow.

I fear you might have missed the point of that paragraph. The point was that multiple reasons contributed to the need for Numpy, so now it exists and is widely used by those who are serious about their scientific computing. The vast majority of those reasons are still valid, even though PyPy speeds up some general-purpose programming tasks in Python.

"A loop that just counts" is not anywhere near a substitute for Numpy. Nor does a 25x speed increase in a particular operation (from CPython to PyPy) hold a candle to the number-crunching speedups provided by algorithm-optimized, code-optimized (often to the point of targeting specific vector instruction sets like SSEx) special-purpose numeric libraries.

jboy··on Python C API, PyPy and the road into the future
I elaborated on my thoughts about the Cython language in this sibling comment: https://news.ycombinator.com/edit?id=10578834

I agree with you that Cython is a mature, very respectable project, and it evidently has more widespread adoption at this time.

I'm betting on Nim because I think it has a larger positive gradient, even though its y-coordinate is lower right now.

jboy··on Python C API, PyPy and the road into the future
There is some documentation on the various Nim backends here: http://nim-lang.org/docs/backends.html & http://nim-lang.org/docs/nimc.html#compiler-usage-generated-...

That second link describes the `nimcache` directory into which the generated C code is written. If you poke around in that directory (starting with the generated C version of your Nim code, which will have the same filename but a `.c` suffix instead of a `.nim` suffix) then you can see that the generated C code is really quite readable.

jboy··on Python C API, PyPy and the road into the future
The preferred workflow that you've described seems to be a (more considered) form of the standard Cython workflow that I see described:

(1) Write Python. (2) Compile with Cython. (3) Run compiled Cython, profile & review. (4) Consider what Cython annotations to make to code; make code changes. (5) Goto 2.

The emphasis is always on iteration & incremental additions.

Of course I practice iterative & incremental development, and of course I'll prototype a quick proof-of-concept implementation first (often in Python+Numpy) before profiling & algorithmic optimization. But the Cython workflow seems to me to add more iteration (of incremental Cython syntax additions) than is really necessary. When I'm working to implement some algorithm, I don't really want to iteratively learn how Cython or CPython implement various Python functions; I'd rather write my "proper version" code just once, properly the first time.

So why not take it to the logical extreme and write it all in Cython-lang from the start? If we're writing for-keeps code in a language with Pythonic syntax & static types, I find Nim-lang a more expressive, more full-featured language (with features such as generics & type-safe Lisp-like macros, in particular; I note that Cython does support pointers & operator overloading) than Cython-lang in general-purpose uses, without being very different at all in simple uses.

For example, there is an example `primes` function in the Cython tutorial: http://docs.cython.org/src/tutorial/cython_tutorial.html#pri...

Here is an equivalent implementation in Nim. As you can see, it's really almost identical in syntax:

  proc primes(kmax: int): seq[int] =
    var kmax = kmax
    var n, k, i: int
    var p: array[1000, int]
    result = @[]
    if kmax > 1000:
      kmax = 1000
    k = 0
    n = 2
    while k < kmax:
      i = 0
      while i < k and n mod p[i] != 0:
        i = i + 1
      if i == k:
        p[k] = n
        k = k + 1
        result.add(n)
      n = n + 1
    return result
All of this said, I understand that a great deal of this decision comes down to personal preference: Would you rather start with Python & then iteratively diverge? Would you rather start & stay in Nim? And I can also see the benefit of both approaches in different circumstances. :)
jboy··on Python C API, PyPy and the road into the future
Sure, this is a question that people ask quite frequently. I most recently answered it here: https://news.ycombinator.com/item?id=10569768

"""Actually, Pymod was designed to be almost an anti-Cython. :)

My issue with Cython is that it's a limited sub-language within Python, where you add Cython elements incrementally & iteratively (diverging from Python in the process) until the code runs "fast enough". I'd rather work directly in a full-featured, internally-self-consistent language from the start. Nim has a clean Pythonic syntax, with all the best parts of C++ (including its runtime speed).

Hence, Pymod takes the form of an `exportpy` annotation (a user-defined Nim pragma) onto existing Nim functions, which are then auto-compiled into a Python extension module. So there's no gradual divergence of my Python code (as it becomes more "Cythonized"); rather, the high-performance code is written directly in pure Nim. :)

"""

There are a few more details in that thread comparing the wrapping of existing C libraries in Cython vs Pymod. (It doesn't seem right to copy-paste an entire thread...)

jboy··on Python C API, PyPy and the road into the future
This post highlights an interesting dichotomy in the Python scientific computing community. Everyone knows that PyPy runs faster than CPython for many common tasks [1].

[1] PyPy is on average 7x faster than CPython: http://speed.pypy.org/

But those in the Python community who are serious about scientific computing (or image processing, like my startup) are already using Numpy & Scipy, which provide hand-coded C implementations of most matrix-related operations. Everyone knows that Python for-loops are "slow" [2], and storing a large 2-D matrix as a list-of-list-of-Python-int-object would require a huge amount of memory & indirection. So, Numpy offers an N-dimensional array type, implemented in C: C arrays of densely-packed C primitive types, with for-loops in C to iterate over the matrix elements. Then Scipy builds a lot of Matlab-like functionality as modules on top of this fundamental Numpy array type.

[2] Python for-loops are slow: https://jakevdp.github.io/blog/2014/05/09/why-python-is-slow...

So the most expensive operations in a Python number-crunching program are likely already implemented using Numpy & Scipy operations, which run in compiled C (and additionally, often make use of Blas/Atlas/LAPACK/etc, for even greater speedups in sustained number-crunching).

But unfortunately, Numpy & PyPy do not naturally work together. Being written in C, Numpy makes substantial use of the CPython C-API -- and in fact, Numpy provides its own C-API [3]! The official Numpy package doesn't work with PyPy; the PyPy project very thoughtfully provides its own PyPy-compatible Numpy package [4].

[3] Numpy C-API: http://docs.scipy.org/doc/numpy-1.10.0/reference/c-api.html

[4] PyPy-compatible Numpy package: http://pypy.org/download.html#installing-numpy

Furthermore, Numpy is fantastic, but it can't offer all possible permutations of matrix operations. In particular, there are certain image-processing operations that are awkward (and thus, computationally-inefficient) to express using Numpy operations. So you might ultimately need to go to the Numpy C-API anyway.

This is why we created (and, just a few days ago, open-sourced) Pymod: https://github.com/jboy/nim-pymod

Pymod is a Nim+Python project that auto-generates all the Python C-API boilerplate & auto-compiles a Python C extension module that wraps the functions in a Nim module. Pymod enables us to write our Numpy array-processing code in Nim, then compile it (for C++-like speeds) as a well-behaved Python module. Nim made this very easy, because it compiles to C.

After considering our Python-integration options (CPython C-API, `ctypes` and `cffi`), we decided to go with the CPython C-API & Numpy C-API. We explained this decision in greater detail in the "Implementation details" section of the Pymod README [5]; the executive summary is that `ctypes` seems better suited to wrapping C types in Python, rather than exposing existing Python types in C, while the CPython C-API code could be generated & compiled with the C code that Nim was going to produce anyway.

[5] Pymod implementation details: https://github.com/jboy/nim-pymod#implementation-details

That said, we would be delighted for Pymod-produced Python modules to be able to run under PyPy. We've been strongly considering implementing a `cffi` back-end for Pymod, but this won't necessarily solve the Numpy issue. It would be even better if PyPy could support all the CPython C-API extension modules in the world in one fell swoop.

jboy··on Pythran: A Python subset to C++ compiler that takes advantage of SIMD
Oh absolutely, Nim should definitely get the vast majority of the credit.

It's not just because Nim compiles to C; it's also due to Nim's powerful macro system, which: (1) allows me to define my own first-class pragmas such as `exportpy`; (2) supplies my pragma with a detailed & expressive AST of the Nim function onto which my pragma was annotated; (3) enables my pragma to auto-generate the C-API boilerplate code, and write it to disk as a newly-created C source file, all within the Nim compilation pass. Nim is a fantastic language, perfectly suited to this scenario.

I merely spotted an opportunity. :)

jboy··on Pythran: A Python subset to C++ compiler that takes advantage of SIMD
Interesting! Thanks for the link.

After browsing that page, I observe that even when Cython is wrapping an external C library, there's still a notable difference between the way Cython does things & the way Pymod does things.

The explanation on that Cython page begins: "To get started, the first step is to redefine the C API in a .pxd file, say, cqueue.pxd". So to wrap an external C library using Cython, you still need to define an entirely new header-like definition file in Cython's intermediate language.

In contrast, Pymod only requires an `exportpy` pragma annotation at the end of an existing Nim procedure function header -- you don't need to create any intermediate definition files. And the `exportpy` pragma is inert unless you invoke the "pmgen.py" script (a Python script in Pymod that determines the Python C-API system configuration & automates all the compilation), so your Nim code is still completely valid Nim code after you apply the `exportpy` annotation.

jboy··on Pythran: A Python subset to C++ compiler that takes advantage of SIMD
Actually, Pymod was designed to be almost an anti-Cython. :)

My issue with Cython is that it's a limited sub-language within Python, where you add Cython elements incrementally & iteratively (diverging from Python in the process) until the code runs "fast enough". I'd rather work directly in a full-featured, internally-self-consistent language from the start. Nim has a clean Pythonic syntax, with all the best parts of C++ (including its runtime speed).

Hence, Pymod takes the form of an `exportpy` annotation (a user-defined Nim pragma) onto existing Nim functions, which are then auto-compiled into a Python extension module.

So there's no gradual divergence of my Python code (as it becomes more "Cythonized"); rather, the high-performance code is written directly in pure Nim. :)

jboy··on Pythran: A Python subset to C++ compiler that takes advantage of SIMD
As a longtime programmer of Python, C & C++ (and a longtime appreciator of your FQA Lite, by the way), my preference until recently was also to use CPython & fall back on extension modules for speed.

But I grew weary of writing all the Python C-API boilerplate -- especially checking parameter types and managing reference counts properly.

So I created (and recently open-sourced) Pymod, a Nim+Python project that auto-generates all the Python C-API boilerplate & auto-compiles a Python C extension module, to wrap the functions in a Nim module: https://github.com/jboy/nim-pymod

As a pragmatic Python programmer, Pymod may be of interest to you too...

(As someone who learned C++ in 1999 and spent most of 200x working in C++, I also grew weary of staying on top of C++0x's new features & new gotchas. So about a year ago, I switched from C++ to Nim-lang and haven't looked back. To me, Nim combines all the best features of Python & C++, while avoiding most of the worst: C++ speed, C++ static types, C++ generics, C++ operator overloading; combined with a clean Pythonic syntax & Lispy macros.)

jboy··on The Big Bang project aims to create a typed language with the feel of scripting
I don't know, I'm sorry.

(The majority of my professional & personal programming has been along the Shell-Python-C-C++ axis. My preference for static types increases approximately logarithmically with the size of the program; historically, I preferred Python for most quick scripting needs, but for larger programs, I was glad of static types, so I would switch to C++.)

Now, Nim has replaced C++ for me completely (and also expanded downwards into the upper end of Python's territory). The work I'm currently doing in Nim is well into the "I prefer static types" area of the spectrum.

Maybe some of the Nim core devs would have more experience with this situation.

IIRC, several of the Nim core devs are familiar with Haskell, and consider it to be one of the reference languages guiding aspects of the Nim language design.

jboy··on The Big Bang project aims to create a typed language with the feel of scripting
In Nim, you can use the type `auto` for proc parameters & return types: http://nim-lang.org/docs/manual.html#types-auto-type

When you use the `auto` type, the compiler will infer the type automatically from the context of the proc invocation or from the proc body. The inferred types can be different for the different parameters. So you can have a proc declaration that looks like:

  proc inferTypes(a, b: auto)  # `a` & `b` can accept different argument types
Within a proc, you can also create bindings & variables without needing to specify a type:

  let iBinding = 1
  var fVariable = 1.2
The following typeless code will compile & run without any complaints or problems:

  import strutils  # `%` operator

  proc inferTypes(a, b: auto) =
    echo "$1 $2" % [$a, $b]

  proc main() =
    inferTypes(25, 30)
    inferTypes(1, "hello")
    inferTypes(4.4, 7)
    inferTypes("cat", 9.5)

  main()
When the above code is compiled & run, it will produce the following output:

  25 30
  1 hello
  4.4 7
  cat 9.5
jboy··on Nim for scientific computing: Back to the future
I assume you're the article author? If so, I know who you are on the Nim forums, so I'll certainly keep you informed. :)

In terms of ecosystems, I think that there is deployed Python code in the world that will never be re-written in Nim. I would prefer that Nim can be used to write drop-in extension modules for this Python code, rather than not at all.

I also think that there are situations where Python is a better fit for a problem than Nim. For example, handling JSON files in Nim (or any statically-typed language) will always be awkward (you have the choice between a double-dispatch Visitor Pattern or accessor methods that cast), but in Python, handling JSON is the easiest thing in the world. Likewise for any heterogeneous container.

By the way: Great article about Nim, as always. :)

jboy··on Nim for scientific computing: Back to the future
Great! I see that you created "pyexperiment" [ https://github.com/duerrp/pyexperiment ], so it's safe to assume you know your way around Python & Numpy.

Is there a good way to get in contact with you?

jboy··on Nim for scientific computing: Back to the future
Great! Email sent to the address in your profile.
jboy··on Nim for scientific computing: Back to the future
Yes, I have, and Julia does look nice. It clearly has some very good libraries for scientific computing, and its syntax looks (to me) like an interesting combination of Python (which I like) and Matlab (which I don't like).

Aside from an entirely-subjective preference that caused me to fall in love with Nim at first sight, there are practical reasons for choosing Nim over Julia.

The overarching reason is that there is much more Python code in the world than Nim or Julia put together, and I think it will remain this way for a long time. (My startup previously worked almost completely in Python, for example, aside from some C or C++ extension modules and the usual Bash scripts for sysadmin.) Python also has some solid webserver frameworks, and is great for a variety of general-purpose tasks.

So, I wanted a solution that would enable us to incrementally rewrite code as necessary, without needing to rewrite everything from Python all at once. Also, I have no desire to rewrite our webserver code from Python. Flask & Django are just fine.

As I understand it (and please correct me if I'm wrong), Julia doesn't compile to C. So I can't compile snippets of Julia code and call them from my Python main-loop.

In contrast, not only is this possible in Nim, but Nim's macro system & well-developed AST spec make it very easy to traverse my Nim procs during compilation, to auto-generate per-proc wrapper code in C.

jboy··on Nim for scientific computing: Back to the future
We haven't just thought about it, we intend to do it! :)

We're just waiting until we're happy enough with our Numpy array API that we'd be confident in calling it "mostly stable".

The (real) Numpy's C API is a perfect example of an API in which gradual accretion of new functions & functionality has given rise to a monstrous (both huge & horrible) API. The naming scheme & parameter patterns are inconsistent; sometimes the names are ambiguous (ie, unclear because they are overly general) or confusing (ie, the function does something other than what you'd expect from the name); and there are several very-similar functions, where it's not always clear which one you should use.

I do understand why the Numpy C API has evolved this way: Once you introduce a function in an API, you can't remove it / rename it / change its parameters, or you will break backwards compatibility with your earlier releases and cause headaches for many of your users. (And of course, there are constraints upon an API written in C, that do not affect an API exposed in Python or Nim.)

So we're really trying to dogfood our own API as much as possible before we inflict it upon the public. :)

jboy··on Nim for scientific computing: Back to the future
My issue with Cython is that (at least as I've understood it from the tutorials I've read) it's a sub-language within Python, where you add Cython elements iteratively+incrementally (diverging from Python in the process) until the code runs "fast enough".

I'd rather work directly in a full-featured, internally-self-consistent language (and Nim is a very nice language) from the start. Hence -- for me, at least: Nim. :)

jboy··on Nim for scientific computing: Back to the future
For the last 9 months I've been working (part-time) on a project that does exactly that. The startup where I work makes extensive use of this project to speed up our Python.

The basic infrastructure was in place after ~2 months. Since then, our team has been using it extensively, and I've been filling out the functionality & evolving the API (for example, testing different array iteration & access interfaces, to see what feels awkward vs convenient, balancing the trade-off between Nim-ness vs Numpy-ness vs Pythonic-ness, etc.).

You write your Nim procs, then annotate them with a special annotation (that's valid Nim, but inert most of the time). When you want to auto-generate Python wrappers around your Nim procs, there's a Python script you run that creates & compiles Python C-API code that exposes the Nim procs in Python as a shared library. This auto-generated code also translates Nim exceptions (including back-traces) to Python exceptions, calls the Nim GC before you return to Python runtime, etc. The auto-generated code also includes auto-generated Python docstrings, extracted from the Nim procs.

There's a Nim type that provides a nice Nim interface to Numpy arrays, so you can pass Numpy arrays into your Nim procs and access them natively. We've also recently added support for a few cute features, like the tuple return types & default parameter values. :)

The API is not yet solidified, so I'd call the project "alpha" or "beta", but it definitely works! The intention is to open-source it soon (once we're happy with the API).

Would you be interested in using something like this? What features would you need? Even better, are you a Python+Nim coder who could contribute?

Feel free to reply here or contact me via email (contact info in profile).

jboy··on A beauty contest winner making Japan look at itself
Here in Sydney, Australia, the term "halvie" seems to be relatively common amongst those who discuss such things. It's not considered derogatory or offensive; at worst, slightly unsubtle or socially inept (like any labelling of a person by their race). Friends use the term lightly or playfully.

Australia is a predominantly-white country that is geographically closer to Asia than to any other white or Western countries. We have a long history of Chinese immigration.

Sydney, especially inner-city Sydney and the areas around the four major universities, have large proportions of predominantly-Asian international students, many of whom later settle here. White-Asian interracial dating is very common in Sydney. Especially at the universities amongst students in the Science, Engineering (including Computer Science, of course) and Business schools. And so, there are an increasing number of "halvies" being born...

jboy··on Porting a NES Emulator from Go to Nim
If a company has a significant amount of existing code in Python, no sensible engineering manager will agree to a complete re-write of the existing code-base. It would divert resources from more-pressing functionality (new features, bugfixes, etc) and almost certainly introduce its own new bugs due to the complete re-write.

(See also this classic Joel Spolsky article, "Things You Should Never Do, Part I": http://www.joelonsoftware.com/articles/fog0000000069.html )

This would be the case whether you schedule the re-write in a single blocking development effort (in which case, all forward progress would stop during that time) or broken into batches over time (in which case, it will be much longer until the new system is ready, and the old system will be a moving target as it continues to be developed).

Instead, the chances of a Nim-integration being beneficial to the company (and thus, your chances of getting approval from your engineering manager) are MUCH higher if you can simply write NEW functionality in Nim (or occasionally re-write small, self-contained inner loops in Nim) and the new Nim code integrates smoothly into the existing Python as a Python module.

This is the approach I've taken at my company (with my engineering director's approval).

In theory, you could even use skunkworks-Nim in your large Python codebase, as long as your Nim code presents itself as a good-citizen Python module, much like the tales of skunkworks-Scala being used in large Java codebases.

jboy··on Porting a NES Emulator from Go to Nim
Hi yes, I'm a Nim community member who's working on that.

A simple version already exists and works (for Python primitive types and Numpy arrays, via the Python C-API), but it's embedded in my company's proprietary Python+Nim (mainly Python) codebase. I'm working in my spare time to extract the relevant code as a Nim library and release it as an open-source package on Github.

If you'd like to learn more about it, or you'd like to be notified when the first release is ready, please come and discuss it on the Nim forums! http://forum.nim-lang.org/

jboy··on Advanced programming languages (2009)
What sort of "graphics" are you looking for?

I generally use Numpy NDarrays and Scipy's NDimage functions for graphics & image processing in Python. Aside from the NDarray data-structure itself, there's almost no O-O; everything in Numpy is either a method of this one workhorse data-type, or module-level functions that operate upon this data-type.

NDarrays are great because they can represent all of: - images (using 2-D arrays for binary or greyscale images, and 3-D arrays for colour images); - the vectors & matrices used in 3-D computer graphics; - the masks used in spatial image filtering; - the "structuring elements" used in morphological image processing.

Once you get used to the syntax, NDarray indexing & slicing are very efficient in both keystrokes & CPU cycles to get/set the values of pixels or arbitrary rectangular regions.

NDarray methods & the related Numpy functions offer element-wise operations (like pixel-wise Boolean logical ops, or "square every element in the matrix" / "square-root every element in the matrix" as part of the Euclidean distance calculation) and operations that can run over any dimension of the image (including the colour dimension, which is useful for calculations like the N-dimensional sum in dot-products or Euclidean distance). And the for-loops are in C, so they're blindingly fast.

NDimage functions provide filters and morphological processing capabilities. Plus, Numpy integrates nicely with Matplotlib so you can display images and plot histograms.

← PreviousPage 2 of 3Next →