I hope these developments eventually turn into a proper Lisp that you can interface with native C code efficiently.
Racket is pretty cool too.
I hope these developments eventually turn into a proper Lisp that you can interface with native C code efficiently.
Racket is pretty cool too.
Clojure is a Lisp-1, and provides better data structures as Common Lisp as far as I am aware.
But the JVM benefit is a big one indeed.
I don't fully grasp the advantages of being a Lisp-1 or Lisp-2 :)
It has to do with variable scoping. Lisp-1 only accepts lexical scoping, while Lisp-2 also allows for dynamic scoping.
No.
Lisp-N has to do with the number of name spaces in the language. Lisp-1s only have ONE environment; the variables range over all values of the language, integers, functions, vectors, symbols, strings. In Lisp-N, there are N namespaces for each "kind" of value.
Common Lisp is called a "Lisp-2" because it separates functions from other values. (it's closer to Lisp-5 or even Lisp-7, forgot which, because it allows that many kinds of "names" without collission.
Also above you said Clojure "probably" has better data structures than Common Lisp. That is unsubstantiated.
I'm not much of a common lisp programmer (mostly sticking with scheme/racket and Clojure), but I don't think they've been ported to Common Lisp (yet), so the claim that Clojure has better data structures than Common Lisp, while somewhat a matter of preference, isn't entirely unsubstantiated.
The language provides a wealth of tools out of the box, but it's the job of the programmer to choose more appropriate tools for the problems at hand.
The following is the Common Lisp specification. 12+ implementations, half of them industrial strength, more than half commercial vendors, and everyone of them has to adhere to this spec:
http://www.franz.com/support/documentation/8.2/ansicl/ansicl...
If you mean can users extend the core CL data-types, no, but you have a wealth of tools to do that yourself; use generic functions to implement whatever interface you wish, then provide for specific implementations.
That's the problem. With Clojure you don't have to invent interfaces and then convince other libraries to use them. All the data structures are built upon well considered language level protocols that anyone can implement preventing pointless API proliferation.
Personally, I slightly prefer Clojure over SBCL.
It is my understanding that Common Lisp lacks the vector and hash maps that Clojure has.
Sorry if I got it wrong. I am more a ML guy than Lisp.
From the documentation I have not seen the simplified syntax Clojure uses for vectors, hashes and sets.
I imagine that the syntax is Clojure specific.
Also, Clojure supports (optional) dynamically scoped variables.
I guess it also helps to work with a dialect with more momentum. E.g. its easier to find support, on- and offline.
Since I haven't really used Closure or any other Lisp for more than a tutorial, I might be very wrong, though.
Here is one example, http://www.atego.com/products/aonix-perc/
If you intend to distribute your software (as opposed to running on your own servers), it would require all the customers to have a fancy JVM. Or buying an expensive license to be able to distribute the runtime with your software.
Why is it a bad thing that someone was willing to pay money to make Java fast. Do you want to say that there haven't been billions of dollars in both money and man-hours thrown at trying to make C/C++ fast? There's no free performance.
I guess there's someone who wants to pay for that.
But I don't think it's money well spent. The Java bytecode is not designed for or suited to fast execution and it's a bad intermediate representation for computer programs to be compiled into native code. The Java byte code was designed to be easy to interpret and was designed at a time when a memory access was faster to execute than an ALU instruction (on cheap h/w where Java was originally intended to be run on). Those days have passed and we should move on to better intermediate representations for computer programs. Like LLVM IR.
VMkit is a nice effort, though. I hope it will some day power fancy new languages that have dynamic features which are not well suited for AOT compilation.
These are native code compilers without any need of extra runtime exactly like C.
Just because most people only know Oracle(Sun)'s JVM, it does not mean it is the only way to execute Java code.
So maybe you mean static compilation, but then, why is it better for the stuff you're doing ?
For me, because I don't want to install the JVM, or force users of my stuff to install the JVM. I also don't care about JVM libs.
>What do you even mean by native code ? The JVM does produce native code, it just does it at runtime (JIT compilation).
I, for one, mean non-JIT, no virtual machine needed, native code.
>So maybe you mean static compilation, but then, why is it better for the stuff you're doing ?
Less startup overhead. Small binaries. Easily redistributable. No stuff I don't need.
By native code I mean binaries emitted by my compiler in a format that my operating system can link and load. I usually write the code in C with some CPU-specific assembly intrinsics for the critical stuff.
I tend to write computer graphics and physics simulation stuff which has to be quite fast. A lot of stuff I deal with is moving blobs of binary data from buffer to another (disk, memory, dma, gpu). Or computing a SIMD fused multiply-and-add for a few hundred megabytes of floating point data. Or invert and transpose a hundred thousand 4x4 matrices. Everything the JVM does is acting against me, so better just write native.
Sure there are games and physics and whatnot written with Java and other systems, but they are more commonly "low perf" stuff. 2d games and that kind of stuff. And even then they suffer from JIT & GC pauses and other undesirable effects. It always ruins my day when in the middle of a Minecraft session the GC kicks in while running away from a Creeper.
The JVM is very fast for these things. There remaining delta is the result of more investment into optimizations in GCC/LLVM than any limitation of the JVM model itself.
It'd be nice if somebody made a new systems language to succeed C or C++. Rust is looking less likely these days. Maybe Clay or Deca?
It's like the inverse of golang. golang is unimpressive, and totally impractical for systems programming, but is nice to use for general purpose programming.
Rust is impressive and could'ish be used for systems programming (I'm not sure how much uphill fighting is involved with the current memory management model, it seems ARC is the default which makes me intensely uncomfortable about its prospects for 'hard' systems programming) but it's not very pleasant at all. The syntax and semantics make me nauseous.
Rust can be fixed, golang cannot. Unlikely though.
I'm not sure it's more realistic to make a practical implementation of region-based memory management than it is to ameliorate the pains of day-to-day systems programming in C.
There is a lot of low-hanging fruit when it comes to systems programming if you're allowed to make a language from scratch and they've not really capitalized on much of that due to ambition.
GC, allocation, thread management, OS interfacing and compilation (JIT or AOT) together make up a VM. Removing the compilation part doesn't make the rest of your VM requirements disappear.
Having used a number of various VMs in the Common Lisp world (yes, including one implementation that went through C) I value the JVM greatly. It is an impressive engineering effort.
Also, I wrote code like yours (hand-written x86-64 SIMD assembly). I then used it from Clojure through JNA and was quite happy with the results.
Yes, you might need to free some heap memory with C and having malloc/free cause GC-like performance. That's why I have zero mallocs in the fast path. The bad part in GC is the unpredictability, which makes it unsuitable for games, simulation and multimedia stuff. But for most allocs I can get away with using the stack, which is essentially free (a possibility of a page fault exists).
> Also, I wrote code like yours (hand-written x86-64 SIMD assembly). I then used it from Clojure through JNA and was quite happy with the results.
Yes that works quite well as long as the foreign function is big enough.
What I have is a bunch of code written with C intrinsics, mostly small functions which I use a handful of for a big bunch of data. What I want is that inner loop to be efficient yet readable.
With C and intrinsics I get interprocedural optimization between the small functions. Everything gets inlined and all the values are stored in registers. There are a few hundred SSE math instructions without a single memory operation in between. I get the compiler to do register allocation for instruction scheduling for me, which it is great at (and I suck in) and leaves me with the instruction selection which it is not so great at.
Now had this been written with any higher level language, or even C across translation units (without link time optimization), my resulting code would be a lot worse. In particular, live values get spilled out of registers to memory when theres a foreign function call (as per abi requirements).
The non-fast path of my project could very well be written in any language as long as the beef would be written in C or similar. I would have to avoid allocating new heap objects to avoid GC unpredicatbility.