Two Years of GNU Guile Scheme 2.0
Two years ago Guile Scheme, the official extension language of the GNU project, released version 2.0, a major upgrade to the implementation. As part of the two year anniversary, the maintainers organized a challenge to hack a small project using Guile in 30 days as part of a birthday software potluck. The two coolest dishes appear to be OpenGL support using the FFI, and XCB bindings built using the XML specification for XCB: "guile-xcb is a language implemented in the Guile VM that parses the XML
files used by the xcb project to specify the X protocol and compiles
them into Guile modules containing all the methods and data needed to
send requests to the X server and receive replies/events back. If new X
extensions are added to the xcb library, guile-xcb can compile and add
them with no additional work.
"
See the release announcement for details on the other dishes.
Another cool thing about GNU guile is that the most recent version supports SRFI-105, "curly-infix-expressions", as developed by the Readable Lisp S-expressions Project. Curly-infix expressions let you write stuff like {a + b} instead of (+ a b), which is a big improvement in readability.
- David A. Wheeler (see my Secure Programming HOWTO)
I've wanted to get into Lisp, but it's frustrating that my everyday GNU environment is split between Guile and Emacs Lisp. I wish that the project, talked about for years, to rewrite Emacs and base it on Guile would take off. It would save Guile, in a sense, because in spite of Scheme's status as the official GNU extension language it tends to be overlooked, and Emacs would benefit greatly from the bindings already developed for Guile.
I love Scheme. I even wrote my own scheme interpreter way back and used it as the embedded control language in QuickLogic's P&R tools. However, only software geeks like Scheme, making it a terrible language for tool control for anything but software dev tools. TCL beat the heck out of Scheme in terms of popularity for this purpose. Python beat the heck out of Scheme as well. Perl got adopted by the text mashing crowd. Also, Guile, at least in the 1.0 version had issues. For example, it really wanted to have main in it's code, while your entire application was something it called. TCL has a better architecture for embedding. Anyway, this is nice, but I don't personally see a significant future for Scheme.
Celebrate failure, and then learn from it - Nolan Bushnell
RPN has always scared people. It's why HP calculators don't dominate the market.
I guess Guile Scheme...
(puts on sunglasses)
does go with everything.
Only in my happiest, wildest, wettest dreams.
So what you're saying is, you're in the "Hokey recursion-relations and ancient parentheses are no match for a good regex at your side" crowd?
It's not just you, but your conclusion is correct: You just aren't used to it. Once you get used to it, Scheme (or any other modern Lisp) is a very easy language to write clean, effective code in.
Curly-infix-expressions (as well as sweet-expressions, which are a superset) are just additional abbreviations. In curly-infix, the surrounding "{...}" indicate that it's a list, but that parameters are written in a different order than they are actually stored. So {a + b + c} is just (+ a b c). We're now wrapping up sweet-expression notation, which is a superset that uses syntactically-relevant indentation (like Python). Check out http://readable.sourceforge.net/ for more info, and in particular, please join the mailing list!!
- David A. Wheeler (see my Secure Programming HOWTO)
Once you get used to it, Scheme (or any other modern Lisp) is a very easy language to write clean, effective code in.
Scheme is great but the problem is I'm a crap programmer. So a language that helps with the code I write is not as important as a language that helps because of all the code that I DON'T have to write.
Basically I prefer to pick a language where there are already tons of existing good libraries/modules/code I can _easily_ use to do what I want. Stuff written by better programmers than me. That way the effective quality of my program goes up - since much of the functionality/code is actually written by someone else.
The other great thing is I don't normally have to support, document and fix that 3rd party code that I didn't write. ;)
Languages like scheme are great if most of the stuff you need to get done is stuff that is unlike anything else someone else has written. But for most of us that's not true.
> Scheme is great but the problem is I'm a crap programmer.
Actually the first sign of a great programmer is realizing they are not great ! :-)
THE key point that everyone forgets: We were ALL noobs at one point. You don't really master a language until you've been using it for years.
> prefer to pick a language where there are already tons of existing good libraries/modules/code I can _easily_ use to do what I want.
Yup, that's very pragmatic. However, I would add, EVERY programmer should know how to or have at least once in their lifetime written atoi() and the corresponding dual itoa() aka, printf.
From a business point of view you want to use a 3rd party library that just works.
From a learning point of view you should write everything yourself (once.)
> I don't normally have to support, document and fix that 3rd party code that I didn't write. ;)
Part of the process of becoming a great programmer is to not only WRITE your code but READ other people's code. The sides of the same coin help each other.
I _love_ the consistency and simplicity of LISP but hate its syntax. Thankfully there is a solution! Readable S-expressions is for LISP programmers who love C style braces but hate LISP parenthesis.
http://www.dwheeler.com/readable/
(Ugly) S-expression
compare with Sweet-expression 0.2
and
http://www.dwheeler.com/readable/retort-lisp-can-be-readable.html
--
The progression of a Lisp programmer:
* The newbie realizes that the difference between code and data is trivial.
* The expert realizes that all code is data.
* And the true master realizes that all data is code.
-- Sriram Krishnan
There's no problem. You can use spaces or tabs, but you HAVE to be consistent when you use one or the other. So if you indent a line with a tab, all sibling and child lines MUST start with a tab... multiple spaces don't count. You can even mix, but you still have to be consistent, so if you use tab space space, all later siblings and child lines must start with tab space space.
- David A. Wheeler (see my Secure Programming HOWTO)
Addendum: All Lisp and C programmers should watch the video:
Readable Lisp S-expressions: Curly-infix-, Neoteric-, and Sweet-expressions
http://readable.sourceforge.net/
However, I would add, EVERY programmer should know how to or have at least once in their lifetime written atoi() and the corresponding dual itoa() aka, printf.
There's also the version for people who think they're smart: do the same for floating point numbers. (Experts only: use only the minimum number of digits when converting to a string.)
"Little does he know, but there is no 'I' in 'Idiot'!"
Huh what lisp functional programming whaa...?! LISP is as imperative as it gets. The key feature of LISP is that code is data. That way you can run complex things at compile time -- things that write code for you, generate tables, implement domain specific languages, etc. The functional features are an afterthought and not really in any way key to LISP's power. They are a commonplace in most languages these days. I mean, come on, once you have function pointers in C, you can directly emulate all of LISP's "functional" features save for ones that need to generate code at compilation time (or runtime, too). It's not like qsort(...., int (*cmp)(const void *, const void*)) is not possible in C, you know. Lambda is very nice syntactic sugar, but not impossible to live without. Same goes for continuations: it's possible all right to have continuations in C and C++, just that you have to make to continuation state explicit in a data structure. Heck, it's even possible to have full-fledged coroutines in C -- again, you have to code for it, and it doesn't look pretty, but it's not technically impossible. No stack switching hacks needed. Of course if you want to run arbitrary C, you need stack switching :)
The template metaprogramming in C++ is a completely unnecessary crutch. It's there only because nobody had the balls to have full-featured compile time code execution in C++. Once you have that, you can write things in a much easier to interpret way using simple imperative style. C++ is, at heart, an imperative language. The fact that you need a functional-style language added to it just in order to work around a reasonably simple deficiency is quite telling. C++ basically requires you to learn two languages that have nothing in common, that use completely different idioms, etc.
Just look at how much trouble there is making the C++ metaprograms actually execute decently in the compiler: now a C++ compiler is not merely a compiler, but also a functional programming runtime / virtual machine! Those things are hard to make to run well -- just look at how long it took Haskell people to get something semi-useful. Adding template functionality that allows metaprogramming to C++ suddenly doubled or tripled the effort required to implement a C++ front-end. Whoever thought it a good idea should be shot.
What would have been the problem to simply let C and C++ compilers run code that is declared as a macro, just like LISP does it? This would have solved everything one uses templates for. A C/C++ host-targeting compiler shouldn't have any problems in extracting the macros, compiling them and running them -- and then consuming their output.
Instead of doing the simple thing, and leveraging the skills of imperative mindset already needed to be an effective C/C++ developer, the C++ language designers have implemented a limited, hard to implement and hard to use functional programming crutch that effectively doubles the requirements placed on the end user. Never mind the poor sods who implement the C++ front end and have to take constant flak from folks who actually want to use the damn feature without having to endure hour-long compile times and multi-gigabyte compiler resident sets just to get through a 10-line metaprogram. Give me a fucking break. Most of boost's metaprogramming stuff is there to basically say: hey, if it really worked here's how it'd look. Then you try to actually use it, and you run into the silly compiler-imposed limitations quicker than it takes to read this sentence. Large scale template metaprogramming is, essentially, completely impossible. About the only thing it's good for in practice are eigen-style libraries. Everything else it promises is summarily non-delivered. It's not funny.
A successful API design takes a mixture of software design and pedagogy.
Scheme is normally considered a functional programming language. The 1989 paper "Conception, Evolution, and Application of Functional Programming Languages" by Paul Hudak defines functional programming languages as languages "in which computation is carried out entirely through the evaluation of expressions" (as opposed to setting mutable states, like variables, or allowing routines with side-effects). That paper specifically identifies Lisps (including Scheme) as languages that can be used as functional programming languages, as well as ML and Haskell. Like ML, Scheme provides mechanisms that let you "escape" outside the functional programming paradigm, but "well-written code" normally doesn't do that.
- David A. Wheeler (see my Secure Programming HOWTO)
Actually, the braces are implemented in the reader. In Common Lisp terminology, they can be implemented as a "reader macro", but this is a completely different step than the Lisp "macros" usually refer to. This means that you can use {...} with data or code, and you can even use them as inputs to macros (in the usual sense). Thus, you can combine Scheme's "define-syntax" with {...} without problems. The SRFI-105 spec has some examples you might want to look at.
- David A. Wheeler (see my Secure Programming HOWTO)
Actually I never liked that style. I can learn a language inside and out and know it's nuances, but that is useless if it turns out the only thing that language is used for is to tie together building blocks that are pre-built by someone else. With a lot of environments it seems it's more useful to know the frameworks and libraries that the project is using than to know the language itself.
Racket is the scheme implementation on the language shootout you linked. Only two dynamically typed languages are faster: javascript and Common Lisp (SBCL) (which is faster than javascript). This makes scheme pretty good and SBCL is lisp after all. I don't know about LuaJIT
Huh what lisp functional programming whaa...?! LISP is as imperative as it gets.
Indeed. I think Scheme is closer to the functional ideal. It was designed to simplify the functional style programming while still giving you access to imperative features. One reason is proper tail recursive calls which are part of Scheme standards, which is not something Lisps always give you.
Lambda is very nice syntactic sugar, but not impossible to live without. Same goes for continuations: it's possible all right to have continuations in C and C++, just that you have to make to continuation state explicit in a data structure. Heck, it's even possible to have full-fledged coroutines in C -- again, you have to code for it, and it doesn't look pretty, but it's not technically impossible.
Everything is pretty much syntactic sugar for this or that. So why don't we all just code in C and be done with it?
This is because C, C++, Perl, Java, C#, etc, even Python are implementing many of the same paradigms. They all descend from C. Lisp and Scheme are completely different from those. Lisps are the oldest high level programming languages. They have been around since 50-60s. No wonder they look different. Nonetheless, Scheme has one of the simplex syntax rules ever. It's just dead simple and unambiguous. For example, there is no operator precedence. You can write a Scheme interpreter in 100-200 lines of code in a high level language (and this is without using any sort of parser library or external parser program).
What I'm merely saying is that functional programming is more a matter of what the developer does, rather than what the language offers. Sure as heck I detest anything where the code is far flung from what is meant, so no, I do not advocate using plain C :)
A successful API design takes a mixture of software design and pedagogy.
How many of those are using Guile 2 yet? Zero as far as I can tell.
To be fair, Guile 2 is a huge upgrade from Guile 1. Internal are completely different. Such transitions will take a long time. It's fair to assume that some will never switch from Guile 1. Not every application needs an uber advanced and fast extension language like Guile 2 (and it is very fast IMO, as far as scripting languages go).
Clojure is a LISP that can use Java libraries.
I don't know if that helps but there finally is a LISP with a good modern set of libraries.
It is popular. You can find stuff all over the web.
And there are books: http://www.amazon.com/s/ref=nb_sb_noss_1?url=search-alias%3Daps&field-keywords=clojure
That's because those frameworks and libraries are millions of lines of code and features you no longer have to write.
Imagine writing your own xml parsers, configuration file handlers, log handlers, high performance ACID databases, web servers, networking libraries, GUI libraries, "OpenGL", etc. Or even operating systems. Even if Scheme is ten times more concise, it'll take a lot of time to write it all yourself.
If learning to use the libraries/frameworks would take longer than to do what you want from scratch, don't use them. But if they are well documented (as good libraries are), then learning to use them would take a lot less time than writing the equivalent functionality from scratch. If you not going to need that functionality then you don't need to learn it - it's not part of the language.
And how many nuances does Scheme have? I thought the main point of stuff like Scheme is it's a simple language. Not like perl or C++. So even with Scheme you're going to be spending a lot more time learning the frameworks and libraries that you can use with Scheme than learning Scheme itself. Unless you're really trying to write most things from scratch. Or writing "Hello World".
You can in theory build a perfect house atom by atom. I prefer to use as much prefab as possible.
If I'm going to write a desktop app I don't want to have to rewrite something like Tk or Qt or OpenGL. Nor figure out how to write interfaces/wrappers to each of them from scratch.
The main impediment to adoption I think was barely missing the Debian Squeeze and the last set of distro releases... but it made it into Wheezy and I think is in every other major distro's latest/upcoming release.
The perils of distro release cycles...
HAL 7000, fewer features than the HAL 9000, but just as homicidal!
Careful, I emphasized *Scheme* and not *Common Lisp*. All Schemes are *required* to be properly tail recursive, per spec, which combined with garbage collection completely deals with the pure-functional-style memory pressures properly. It's true that nobody in practice writes large (Common) Lisp projects in functional style, but Common Lisp doesn't guarantee proper tail recursion (and implementations don't typically provide it), so that should be unsurprising that you can't really scale that up in Common Lisp.
- David A. Wheeler (see my Secure Programming HOWTO)