Assembly-generating macros in common lisp - macros

I'm interested in seeing how low-level a programmer can go in pure Common Lisp (or, failing that, in implementation-specific extensions). Google hasn't been able to find me much information about this, so I'd like to hear what the experts have to say. This post mentioned a feature of SBCL to define what the author called "virtual operators", but searching for "common lisp virtual operators" didn't yield much. The author also mentioned how hard it was to find documentation about it. Do similar systems exist for other implementations, is there any basis for it in the standard (though considering that such a feature would mostly be used for writing ISA-specific code, portability shouldn't really be high on the priorities for users of it), and where can documentation for features such as this be found?
It would be great to find a way to extend the "programmable programming language" concept to low-level code as well (especially for areas where efficiency is highly important and other libraries written in C or assembly may not be available).

This is very implementation specific and not portable at all.
Yes, SBCL uses VOPs, but other implementations have completely different compilation targets.
If you intend to go low-level in a somewhat portable way, you have two avenues:
Optimize using declarations, inlining, manual unrolling etc., checking your progress with disassemble
Implement a static blob externally, then interface it with an FFI

Related

Why isn't there a good scheme/lisp on llvm?

There is Gambit Scheme, MIT Scheme, PLT Scheme, Chicken Scheme, Bigloo, Larceny, ...; then there are all the lisps.
Yet, there's not (to my knowledge) a single popular scheme/lisp on LLVM, even though LLVM provides lots of nice things like:
easier to generate code than x86
easy to make C FFI calls
...
So why is it that there isn't a good scheme/lisp on LLVM?
LLVM provides a lot, but it's still only a small part of the runtime a functional language needs. And C FFI calls are uncomplicated because LLVM leaves memory management to be handled by someone else. Interacting the Garbage Collector is what makes FFI calls difficult in languages such as Scheme.
You might be interested in HLVM, but it's still more than experimental at this point.
For CL: Clasp is a Common Lisp implementation on LLVM, and mocl implements a subset of Common Lisp on LLVM.
For Scheme: there's a self-hosting Scheme->LLVM demo and a prototype LLVM backend for Bigloo Scheme.
For Clojure: there's Rhine, which is a Clojure-inspired lisp.
There's a very small and apparently unoptimised Scheme compiler here:
http://www.ida.liu.se/~tobnu/scheme2llvm/
Taking your question literally,
Writing compilers is hard.
A poor implementation like the one linked above can block new implementations. People going to the LLVM page see that there's a Scheme already, and don't bother writing one.
There's a limited number of people who write and use Scheme (I'm one, not a hater, btw).
There are lots of existing Scheme intepreters and compilers and there's not a screaming need to have a new one.
There's not an immediate, clear benefit to writing a new interpreter using LLVM. Would it be faster, easier, more flexible, better in some way than the other dozens of Scheme implementations?
The LLVM project went with another language (C) to demo their technology, and haven't seen a need to implement a lot of others.
I think that it could be a lot of fun for someone to build an LLVM-based Scheme compiler. The Scheme compilers in SICP and PAIP are both good examples.
Maybe I'm completely misunderstanding the question or context, but I believe that you could use ECL, which is a Common Lisp that compiles down to C, and use the Clang compiler to target LLVM (instead of GCC).
I'm not sure what (if any) benefit this would give you, but it would give you a Lisp running on LLVM =].
One thing to keep in mind is that many of these implementations have C FFIs and native-code compilers that significantly predate LLVM.
CL-LLVM provides Common Lisp bindings for LLVM. It takes the FFI approach, rather than attempting to output LLVM assembly or bitcode directly.
This library is available via Quicklisp.
mocl is a compiler for a relatively static subset of Common Lisp. It compiles via LLVM/Clang.
there's not (to my knowledge) a single
popular scheme/lisp on LLVM
Currently, llvm-gcc is the nearest thing to a popular implementation of any language on LLVM. In particular, there are no mature LLVM-based language implementations with garbage collection yet. I am sure LLVM will be used as the foundation for lots of exciting next-generation language implementations but that will take a lot of time and effort and it is early days for LLVM in this context.
My own HLVM project is one of the only LLVM-based implementations with garbage collection and its GC is multicore-capable but loosely bound: I used a shadow stack for an "uncooperative environment" rather than hacking the C++ code in LLVM to integrate real stack walking.
There is a Scheme2LLVM, apparently based on SICP:
The code is quite similar to the code in the book SICP (Structure and Interpretation of Computer Programs), chapter five, with the difference that it implements the extra functionality that SICP assumes that the explicit control evaluator (virtual machine) already have. Much functionality of the compiler is implemented in a subset of scheme, llvm-defines, which are compiled to llvm functions.
I don't know if it's "good".
GHC is experimenting with a scheme backend and getting really exciting preliminary results over their native code compiler. Granted, that's haskell. But they've recently pushed new changes into LLVM making tail calls easier IIRC. This could be good for some scheme implementation.

Which dialect of Lisp should I learn? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 7 years ago.
Improve this question
I know there are a few different dialects of Lisp. Having decided that learning Lisp would be a new intellectual experience, I would like to know which Lisp dialect to learn, and why.
Is there one which is more popular than the others? Is any one of them more "complete", as in, better documented and supported? What are the pros and cons of this dialect?
You want to look for a balance between simplicity and cleanliness, attractive features, and a platform that will allow you to write interesting and useful software (to yourself) as well as serve as a learning tool. (This last will keep you going and learning for a lot longer.) Here are some possibilities:
Scheme. Probably the cleanest of all dialects. This is no doubt why The Little Schemer was translated from LISP into Scheme. The fifth Scheme standard specification, R5RS, is a wonderful education in and of itself; it may be the nicest language and library specification I've ever read, as well as the shortest that's reasonably comprehensive. The PLT Scheme (now Racket) platform includes a fairly decent interpreter and compiler, is good for scripting, and also has some visual tools that make it excellent for learning.
Common Lisp. Probably the most portable and comprehensive variant, this is most likely what you want if you want to be writing things such as commercial software. The standard defines extensive libraries, and many more are available beyond that, it has CLOS, which will probably teach you more about OO than any OO language could, and some of the compilers are very good. Disadvantages include some warts that Scheme doesn't have (such as having a separate namespace for variables that refer to functions), not being as clean and simple (as is the case with anything that has had to have the extensions and make the compromises necessary for large applications in the real world), not having hygienic macros, and emphasizing recursion much less than Scheme.
Clojure. This runs on the JVM, which may give it a leg up right there for Java developers. It's got a few warts (e.g., you must explicitly ask for tail call optimization, though this may change one day if TCO is added to the JVM). The macros, while not hygienic, do have some features to help you avoid variable capture, so you can capture variables if you really want to, while running less risk of accidentally doing so than in CL. You've got easy access to all the Java libraries; that's probably a good thing for "real world" code, and fairly pointless in terms of learning. It's got a set of libraries for persistent data structures and support for STM, which make it very interesting from a concurrent point of view; this makes it probably your best bet if you're interested in learning more about new methods of dealing with concurrent and parallel programming. It appears as if Clojure is as usable for large, production applications as Java, in the sense that it's going to have the ability to do the "ugly stuff" you do in production apps that you'd rather not do and don't do when you're learning.
Emacs Lisp. In terms of a LISP, this is not one of the better examples out there. One of its biggest faults is dynamic scoping, but there are many others. However, if you're an Emacs user, this may be the most powerful tool you can learn to improve your use of the editor. How much you'd really learn from learning Emacs Lisp, beyond how to extend Emacs, is for me an open question however; I don't know how often interesting techniques such as high-order functions are really used in Emacs Lisp.
2018 Update
It's been almost a decade since I wrote this post and the Lisp family of languages now appears to be gaining significant traction in the general programmer consciousness. Much of this appears to be related to Clojure which has not only become a properly separate dialect of Lisp in its own right, introducing many of its own good ideas, but also now has a near-identical version targeting JavaScript and has inspired many other Lisps targeting other platforms. For example, Hy targets the CPython AST and bytecode, aiming first for interoperability with Python, but using Clojure ideas "when in doubt." (Though from the latest commits, the latter may be changing a bit.)
The big change this brings in your decision-making process is that you should also be looking at whatever Lisps or Lisp-like languages are available for and interoperate with languages or platforms you already use, be it Perl, Ruby, Erlang, Go or even C++ on microcontrollers.
I would say Scheme, solely because of the Little Schemer, which is one of the most mind-blowingly fun yet extremely hard books I've ever tried to read.
I can recommend Common Lisp on SBCL. This combination is fast, powerful, mature and well-documented.
Also Clojure is a gaining a lot of mindshare these days, and for good reason. Great data structures, profoundly good concurrency support (puts Scheme and CL to shame in this regard), and a great community. It's also relatively simple, CL is as at least as complicated as C++.
This isn't to say I don't enjoy CL or Scheme. I learned Scheme with SICP. And CL brought me to Clojure. It all depends on your goals I suppose. If you want to learn a Lisp that is immensely practical go for Clojure. Otherwise CL or Scheme are both great.
I learned Scheme in school. It was a great learning experience and I will never forget the fundamentals of functional programming. It probably doesn't matter which version of LISP you pick up, as long as you understand the core of its usefulness - stateless lambda calculus.
Here's an interesting article on Why MIT switched from Scheme to Python in its introductory programming course.
I prefer CL, since I like object-oriented programming, and CLOS is the nicest object system around.
I would say all of them, at least at first. Eventually you will probably develop a preference for Scheme or Common Lisp, but they both have enough differences that it's best to get a handle on everything that's out there.
Scheme has continuations for example, and it's good to learn about those in Scheme, even though they can be implemented in Common Lisp.
Learning the difference between lexical and dynamic scope is important, and if you learn both Common Lisp and elisp you'll come across the implications of both.
LFE (Lisp Flavored Erlang) would be nice. You can have the lisp syntax on top of the Erlang VM.
Was a kind of "loaded" question to begin with but OP probably didn't know about it. Generally, Common and Scheme lispers are like PC and Apple computer "people", they don't mix. Which one is best is probably not as relevant as which one "works" for you. Really, there is not that much difference. Likely a preference for one over the other maybe influenced by which one you learn first. (To me, an empty list should be "nothing", known in CL as NIL, and that makes me a Common Lisper.) I like the integration of SBCL with Slime using EMACS, but SBCL is not for everyone. For one thing, SBCL is very strict. If you just want to "have fun" the GNU clisp is easy and available for virtually every platform.

In Which Cases Is Better To Use Clojure? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
I develop in Lisp and in Scheme, but I was reading about Clojure and then I want to know, in which cases is better to use it than using Lisp or Scheme? Thanks
This question is impossible to answer. You should use Clojure nearly 100% of the time over CL and Scheme, is what I would say. But that doesn't mean you should listen to me. Others can make a good argument that the opposite is the case.
For me, the syntax and function names in Clojure aesthetically pleasing. Certain Java libraries are invaluable for what I do for data munging and web programming and GUI stuff. Functional programming is challenging and enjoyable. Clojure's flaws are unimportant and outweighed by its benefits in my eyes. Certain intolerable flaws in other Lisps are "fixed" in Clojure, because it's new and it can ignore backwards compatibility. It has a novel and arguably powerful approach to concurrency. The Clojure community is vibrant and welcoming and awesome. All of this says as much about me and what I value as it does about Clojure or other Lisps.
There are libraries for CL and Scheme that don't exist in Clojure or Java. There are people who dislike how Clojure uses too much syntax like [] and {} and want to use parens everywhere. If you want CLOS-style OOP or lots of mutable data structures, another Lisp is arguably better. The JVM is heavyweight, maybe too heavyweight and too much baggage for some people. A lot of Java leaks into Clojure (by design) and this offends some people's sensibilities. The STM and immutable data structures have overheads that make certain things (e.g. number crunching) slower or less elegant. Clojure is new and still rough in certain areas, still rapidly changing and evolving in others. Clojure has yet to pass the test of time, whereas other Lisps already have. Clojure is not a "standard" and some people find a language defined by an implementation to be unappealing. And so on. None of these things matter to me, but they may to you.
This is almost entirely subjective. Which language you should use depends on what you already know, what you are willing to learn, what libraries you want to use, what editors and tools you're comfortable with, what language flaws you're willing to live with and work around and what flaws you can't tolerate, and what helps you get your work done faster, more cheaply, more enjoyably, or achieve whatever your goals are.
Basically, whatever makes you feel warm and fuzzy. Learn them all and then make an informed choice based on your own tastes, and use whichever one you like the best. They're all good.
"Clojure runs on the JVM" means you get the whole cornucopia of Java libraries available. You can make pretty GUIs in Swing, use Apache's Web client or server code, connect a ready-built Sudoku solver... whatever you like.
Another big plus of Clojure is its very polished concurrency support, with about 3 different flavors. If you have a compute-intensive, parallelizable task, Clojure can make it easy. Well, easier.
Update: Another argument. Clojure is pretty strongly functional, so it's a plus if you want to force yourself to think and write functionally.
Clojure should be used when
you need to work with existing java code.
you work with people who are allergic to lisp ("boss, i would like to use a java concurrency library called clojue vs. I would like to re-write this in scheme" [1]
you will be programming for a multi-processor system.
Scheme would be better when:
you need to prove your code is correct. Clojures (call out to java) hinders but does not prevent this.
you are working with people who are allergic to java.
you are developing for a platform with no (new enough) JVM
[1] yes this is a bad bad bad reason. such is the world we live in...
When? As much as possible.
Why? Immutable Data Structures - they really are that good. There are plenty of other reasons too.
ABCL (Armed Bear Common Lisp) and a several of Scheme implementations (KAWA, SISC, ...) are also running on the JVM.
Generally Common Lisp is available in different 'flavors' - ABCL is one of them. Other compile to C, to native code, have extensive development environments or specialized extensions like logic languages or databases.
Clojure OTOH is a new Lisp dialect with emphasis on lazy functional programming and concurrent programming. Its author (Rich Hickey) is a very experienced software developer (he has also written Java and .net interfaces for Common Lisp) and did an excellent job with Clojure. Even though there is some hype around the language, it is worth checking out - it is definitely one of the better Lisp dialects developed in recent years (compared to say Newlisp or Arc).
There are lot's of reasons, some mentioned above. My take is:
The pre-existing libraries. This is such a benefit. I just can't praise this feature enough.
The language is more adapted to the
hardware currently available
(multi-core) and the development
paradigms in use today. It is so much easier to reason about concurrency. The functional aspects are nicer too. You can do functional programming in Lisp, obviously, but it is very easy to break the paradigm unknowingly, unwittingly, and unintentionally.
Cross platform. I run identical
programs on Linux, Windows, and the
Mac. There are lot's of native Lisps
that run across platforms, but
support for all features on all
platforms is a bit spotty and you
constantly have to be on the alert
for things that are missing on one
platform or the other. Likewise,the
libraries you need are not always
consistently supported across
platforms. ABCL and some of the
JVM Scheme implementations have this
consistent support as well, but I
still prefer Clojure because of
point 2.
The nature of the language
community. Let's face it, a lot of
the time the Common Lisp community
is just nasty to deal with. That is
not the case with Clojure at all.
It's easy to get useful help without
the condescension and meanness that
often comes with an answer from the
Common Lisp community. As I have
learned for myself several times,
there is no question so stupid that
you won't get a polite and helpful
reply from the Clojure community.
If I had to find one thing to complain about, it would be IDE support. Maybe it's a question of learning new habits, but it is still easier for me to handle the mechanics of Java development than Clojure. I have tried, and use, Clojure Box, enclojure on NetBeas, La Clojure on Intellij IDEA, and Counterclockwise on Eclipse. They all work fine if you are working primarily from the REPL, but for compilation and execution of class files, they all still feel a bit clumsy.
A subset of Clojure can also compile to javascript
Clojure runs on the JVM (and on the CLR), so there is that.
Clojure's design is concerned with accommodating several styles of concurrent programming safely, deliberately making it difficult to mistakenly write the dangerous, rickety, and often broken concurrency-tolerant code in other languages. If your problem domain involves concurrent programming, Clojure's array of integrated tools for managing concurrency may be a better fit than the implementation-specific or lowest-common-denominator libraries available in other Lisps and Schemes.
One of the greatest things about Clojure is the plethora of libraries you can use with it. You have the power of Java with the expressiveness of Lisp, and that is a badass combination. Clojure is more suited for real world development, because it was made for real world development. With Clojure, you have awesome libraries, awesome modern features, and an amazing community of helpful, like-minded people.
I would have to say that Clojure is a better language, all the way around. That is a highly argumentative statement to make, so I will point out here that this is just my honest opinion.
Clojure rocks.
I'm always trying to learn new languages, so I'm interested in learning Clojure. But, aren't SBCL and some other Common Lisp implementations much, much faster than Clojure? Wouldn't you need considerably more than 4 processors (and a reasonably parallelizable task) to make up for the performance difference between a Clojure app and even a single-threaded SBCL version of the same app?
As a general rule of thumb, I tend to favor Clojure over other languages in cases where either of these fit the bill:
(1). The domain model tends to look very recursive and/or graph-like.
(2). There's an opportunity to leverage a multi-core JVM environment (e.g., Elastic Beanstalk)
(3). There's a fuzzy barrier between data and code (think RPN calculator where nodes can be operators or numbers)
These might sound a bit contrived, but a lot of my work involves dealing with graphs and trees of information, whether it's looking at social networks, some kind of constrained-based optimization, or semantic relationship building. I find that my other favorite language, Ruby, cannot give me the mix of expressiveness and raw computing power compared to Clojure, particularly when it comes to quantitative, recursive, concurrent-type problem solving.

Suggestions for Adding Plugin Capability?

Is there a general procedure for programming extensibility capability into your code?
I am wondering what the general procedure is for adding extension-type capability to a system you are writing so that functionality can be extended through some kind of plugin API rather than having to modify the core code of a system.
Do such things tend to be dependent on the language the system was written in, or is there a general method for allowing for this?
I've used event-based APIs for plugins in the past. You can insert hooks for plugins by dispatching events and providing access to the application state.
For example, if you were writing a blogging application, you might want to raise an event just before a new post is saved to the database, and provide the post HTML to the plugin to alter as needed.
This is generally something that you'll have to expose yourself, so yes, it will be dependent on the language your system is written in (though often it's possible to write wrappers for other languages as well).
If, for example, you had a program written in C, for Windows, plugins would be written for your program as DLLs. At runtime, you would manually load these DLLs, and expose some interface to them. For example, the DLLs might expose a gimme_the_interface() function which could accept a structure filled with function pointers. These function pointers would allow the DLL to make calls, register callbacks, etc.
If you were in C++, you would use the DLL system, except you would probably pass an object pointer instead of a struct, and the object would implement an interface which provided functionality (accomplishing the same thing as the struct, but less ugly). For Java, you would load class files on-demand instead of DLLs, but the basic idea would be the same.
In all cases, you'll need to define a standard interface between your code and the plugins, so that you can initialize the plugins, and so the plugins can interact with you.
P.S. If you'd like to see a good example of a C++ plugin system, check out the foobar2000 SDK. I haven't used it in quite a while, but it used to be really well done. I assume it still is.
I'm tempted to point you to the Design Patterns book for this generic question :p
Seriously, I think the answer is no. You can't write extensible code by default, it will be both hard to write/extend and awfully inefficient (Mozilla started with the idea of being very extensible, used XPCOM everywhere, and now they realized it was a mistake and started to remove it where it doesn't make sense).
what makes sense to do is to identify the pieces of your system that can be meaningfully extended and support a proper API for these cases (e.g. language support plug-ins in an editor). You'd use the relevant patterns, but the specific implementation depends on your platform/language choice.
IMO, it also helps to use a dynamic language - makes it possible to tweak the core code at run time (when absolutely necessary). I appreciated that Mozilla's extensibility works that way when writing Firefox extensions.
I think there are two aspects to your question:
The design of the system to be extendable (the design patterns, inversion of control and other architectural aspects) (http://www.martinfowler.com/articles/injection.html). And, at least to me, yes these patterns/techniques are platform/language independent and can be seen as a "general procedure".
Now, their implementation is language and platform dependend (for example in C/C++ you have the dynamic library stuff, etc.)
Several 'frameworks' have been developed to give you a programming environment that provides you pluggability/extensibility but as some other people mention, don't get too crazy making everything pluggable.
In the Java world a good specification to look is OSGi (http://en.wikipedia.org/wiki/OSGi) with several implementations the best one IMHO being Equinox (http://www.eclipse.org/equinox/)
Find out what minimum requrements you want to put on a plugin writer. Then make one or more Interfaces that the writer must implement for your code to know when and where to execute the code.
Make an API the writer can use to access some of the functionality in your code.
You could also make a base class the writer must inherit. This will make wiring up the API easier. Then use some kind of reflection to scan a directory, and load the classes you find that matches your requirements.
Some people also make a scripting language for their system, or implements an interpreter for a subset of an existing language. This is also a possible route to go.
Bottom line is: When you get the code to load, only your imagination should be able to stop you.
Good luck.
If you are using a compiled language such as C or C++, it may be a good idea to look at plugin support via scripting languages. Both Python and Lua are excellent languages that are used to script a large number of applications (Civ4 and blender use Python, Supreme Commander uses Lua, etc).
If you are using C++, check out the boost python library. Otherwise, python ships with headers that can be used in C, and does a fairly good job documenting the C/python API. The documentation seemed less complete for Lua, but I may not have been looking hard enough. Either way, you can offer a fairly solid scripting platform without a terrible amount of work. It still isn't trivial, but it provides you with a very good base to work from.

Are there documented, organized collections of libraries for Common Lisp?

I am a college student at a school that teaches mainly in Java. One of the strong points of Java, which I quite enjoy, is the large collection of libraries. What makes these libraries especially useful is the extensive documentation and organization presented via JavaDoc. Are there any library collections for Common Lisp which also have these qualities, and is there a tool similar to JavaDoc which would assist in the building, maintaining, or expanding of these libraries?
Yes there are extensive, documented library collections at http://www.cl-user.net,
http://www.cliki.net and http://clocc.sourceforge.net. As well as advanced 'asdf' or 'mk-defsystem' base infrastructures to use them.
No, there is no comprehensive, consistently documented library collection. The inexistence of such a thing is Common Lisp's biggest problem right now. If you're interested in helping the Lisp community, this may well be the thing to attack first.
Also, while there are various JavaDoc equivalents, there is no widely accepted quasi-standard as for Java.
Now there is quicklisp and it made everything so much easier!
http://www.quicklisp.org/
Github contains a lot of lisp projects, not to mention Sourceforge
Try cliki or common-lisp.net.
As to javadoc...you know about docstrings? If not, find out. Also find out about all the other self-documenting features.
It sounds like you haven't read the spec. Always read the spec, whatever you are doing.
I recommend clbuild, which contains a collection of quality libraries compiled by a group of experienced, discerning lisp programmers (as well as script to download and install those libraries).
If you want guidelines for writing highlevel/api documentation, I suggest you follow the examples set by Edi Weitz and others (e.g., see Hunchentoot, Vecto).
For lower level implementation documentation, I think the built-in docstring mechanism together with Slime's source navigation and autodoc facilities comprise the best existing environment for code exploration.
Tinna is a Lisp documentation system that is comparable to JavaDoc.
There are many available libraries for Common Lisp and many of them are thoroughly documented. JavaDoc, in my own experience (or any such tool like Doxygen for C++), is not a valuable tool to document a library but more to document its implementation.
So documentation is not a matter of tools here, but of will of the lib's author to write a decent manual. In this area, Common Lisp is like any other language: there are beautiful pieces of engineering with wonderful documentation, quick and dirty code without the slightest sign of documentation, as well as all possible combinations of code and documentation qualities...
All in all, I personnally found that Common Lisp libraries have a pretty high overall quality.
If you are used to Java, you may give Clojure a chance and keep using the Java libraries you know.