22 comments

[ 340 ms ] story [ 2342 ms ] thread
I wonder how performance sensitive this code has to be? Clojure is a pretty bad choice for numerical work in general since function parameters are usually just Object and this leads to a lot of boxing. You can type hint them as primitives but it's pretty funky internally once you start doing that. If code can offload the numerically intensive bit to either Java or something native (as Neanderthal does) then it's more tractable, or of course if it doesn't actually require very high performance.

Still, awesome effort - it looks like a ton of work.

Presumably the Java library it uses for the numerical integrators works on unboxed data.
You are correct.
This library is for symbolic manipulation AFAIK.
Scmutils enables both symbolic and numerical computation, though as I recall much of the symbolic stuff (e.g., automatic differentiation) is done via generic functions rather than manipulating symbolic expressions.
All this is true. Similar issues arise in MIT Scheme as well. This can be partially alleviated by having specialized versions of VECTOR-SET! etc that avoid boxing floats. Presumably there are compiler optimizations focused on faster numerics as well. Anyway, for the purpose doing SICM-style problems (which are generally not computationally intensive), it's certainly fast enough.
> Clojure is a pretty bad choice for numerical work in general since function parameters are usually just Object and this leads to a lot of boxing

This is quite easily solved by just declaring your parameters with type hints, and testing the code with the provided warnings about reflection and boxed math.

This still leaves container data structures, the native arrays and vectors are boxed. To address this, you can to use Java arrays or 3rd party specialized containers like data.int-map instead.

There is good news and bad news. The ODE integrators (etc.) in Apache Commons Math are great and work with unboxed types. In SICM, however, you'll be dealing with clojure functions generated by the system to map states to their time derivatives, and those states will be stored in "up tuples" and not native java []double. So copying must happen at state-derivative evaluation time. The system attempts to win back some speed by at least avoiding interpreting the state function. For the kind of explorations the book enables, it seems good enough. Also, you can "take your equations of motion out" of the system with ->JavaScript, and run that code in the browser with a suitable JavaScript integrator and that works too.
That looks like a fantastic effort. Scmutils is an astounding language, and porting it is a Herculean task.
Congrats to author! Just a small addendum: I'm not a lawyer, but I'd advise author to check licenses. GPL3 project license and EPL license of libs used as dependencies aren't compatible.

There was a bit discussion about this and, if I got it correct, Clojure project could be licensed under GPL only when there aren't EPL licensed dependencies.

I don't see how there could be a problem unless the author is distributing a binary. If you give someone GPL code, they can do anything they want with it, as long as it's for their own use. It could potentially cause problems for other people that want to mix the two in improper ways for purposes of distribution, but that's not the author's problem.
https://www.eclipse.org/legal/eplfaq.php#GPLCOMPATIBLE

Based upon the position of the Free Software Foundation, you may not combine EPL 1.0 and GPL code in any scenario where linking exists between code made available under those licenses. The above applies to both GPL version 2 and GPL version 3.

Since Clojure itself and its core library are EPL, this means you basically cannot write GPL code with Clojure.

There are no restrictions on what you do with GPL software if you're not distributing it. Here's what the FSF has to say[1]:

"If I only make copies of a GPL-covered program and run them, without distributing or conveying them to others, what does the license require of me? (#NoDistributionRequirements)

Nothing. The GPL does not place any conditions on this activity."

The whole point of the GPL is to guarantee that the user can do anything they want with the software. The only limitations on GPL software are with respect to distribution.

So is the Eclipse FAQ wrong, or does the EPL forbid this private use of EPL'd code in a non-distribution scenario?

It sounds to me like the FAQ is wrong, since it quotes the FSF's position as the foundation of its argument.

edit: apparently a twist is that GPL is considered a pure copyright license, and so covers only distribution, but the EPL is broader. It starts with "ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT". So apparently this makes it a kind of contract and not just a copyright licese.

The lack of "apply hooks" put me off the the guile version, and running MIT scheme isn't much fun. I'd love to see the book updated with the new code, or even better, a full racket version.
(comment deleted)
I'll have to check this out. SICM is great.

I was playing with the Racket port[1] a while back. I am not sure how complete it is compared to this Clojure implementation.

[1] https://github.com/bennn/mechanics

Note that Alex Gian is porting SICM to Racket. Check the Racket mailing list for SICM posts.
zoinks! I did the port but somehow missed my HN moment. Someday I was thinking this might be worth a show HN, if I get some more web pages up exploring what can be done with the system.