Posted Dec 4, 2012 0:06 UTC (Tue) by Corkscrew (subscriber, #65853)
Parent article: GNU Guile 2.0.7 released
N00b question: under what circumstances would Guile be a useful language to learn?
Does the language have specific favoured use cases, in the same way that Javascript is "for" asynchronous processing or Lua is "for" embedded scripting? Or is it simply a soft point of entry into the mind-blowing world of Lisp?
Posted Dec 4, 2012 0:45 UTC (Tue) by krakensden (subscriber, #72039)
[Link]
It's targeted at embedding, like Lua- perhaps "embedded scripting for people who like metaprogramming".
GNU Guile 2.0.7 released
Posted Dec 4, 2012 8:55 UTC (Tue) by civodul (subscriber, #58311)
[Link]
Guile is not a language; it's primarily an implementation of the Scheme and Emacs Lisp languages, and also comes with a less mature ECMAscript (aka. JavaScript) front-end.
Posted Dec 4, 2012 10:40 UTC (Tue) by dakas (guest, #88146)
[Link]
It is the extension language for LilyPond and quite tightly interwoven with it, though both conceptual and data structure integration are an ongoing task and we have not yet managed migration to Guilev2 which would make some things easier in that regard.
In some respects, Guilev2 is a step backwards for the sake of being an extension language and a step forward for a general-purpose programming system, mainly because of its larger complexity, things like file-level byte-compilation, its more complex architecture.
Now what are comparison points with regard to Lua, possibly its largest contender?
a) Lua is minimalistic regarding its available data types and structures. It has 8 data types, one of which is opaque "user data", and one is its sole data structure, the table. There is only one numerical data type implemented as a double. This minimalism is actually an advantage for extension languages since it makes the mapping of language features to extension language features straightforward. string or symbol? Not a question: Lua interns _all_ strings at some performance impact, and so the principal feature of a symbol, constant time comparison and fixed hash code, is available with every string. Guile, in contrast, has basically a type for each purpose which makes for best utilization of machine resources regarding storage representation. It also offers more potential for performance improvement by compiling to machine code, though trace compilers (like luajit) can usually keep the code optimized for the typical use cases, recompiling when expectations are violated.
b) Lua is a procedural language, Guile is functional. This makes Lua more pleasant for imperative programming, but Guile more syntactically embeddable since there are no boundaries between "constant", "expression", "statement" and "program". If you have a mechanism for referring to a constant in the extension language, all the rest falls into place. Even the Lua command line interpreter recognizes this shortcoming and offers a shortcut "=" for evaluating and printing an expression.
c) Lua has a simple syntax for coding, Guile has no syntax for coding. Guile code is executed by reading a Scheme expression, typically a list, and evaluating it. Lists can be nested, and there is nothing like operator precedences or anything else needed for evaluating a list. That makes it less pleasant for humans to interact with Guile (like most LISP-like languages), and fabulous to have programs interact with Guile: the read syntax basically already delivers the "parse tree", while Lua can only evaluate strings. Even though its syntax is simple, you can't manipulate programs sensibly through text manipulations. Guile has a powerful macro and syntax transform system that can easily be adapted to a lot of tasks.
d) since Lua can only evaluate chunks from a string, something like evaluating user-provided material in lexical closure is not feasible (basically, you would have to splice the user-provided material into a source code string and recompile the whole function). Guile can work with lexical closure in a number of ways. Check out <URL:http://news.lilynet.net/?The-LilyPond-Report-27#a_kind_of...> for an example of tight interweaving of user-provided material and preexisting code, crossing the border between LilyPond interpreter and Guile interpreter back-and-forth without apparent effort.
e) Lua only has doubles as numerical types, Guile has a full numeric stack with integers (arbitrary size), rationals, floats, and by now also complex numbers. If you want to do symbolic computation or other "I don't want to bother with the sideeffects from approximative results" work, that's certainly a boon.
I am a big fan of Lua's minimalism, and Guilev2 is a step backward in effortless integration due to its file-level compilation and other growing pains. And while a LilyPond based on Lua as extension language would certainly have been a quite feasible project as well, using Guile as a Scheme-based extension language for LilyPond has made a conceptual and programmatic integration possible that is not easily rearchitectable to an imperative language. There is still a lot of open potential, and the other large GNU projects showcasing Guile as an extension language (GNUcash and TeXmacs) don't have, as far as I can tell, a similarly invasive integration of code and concepts, so their language choice appears a bit more arbitrary than that of LilyPond, and there are more voices for replacing it.
Both Guile and Lua have some mechanisms to "grow with you", but Guile is quite larger at the start, and Lua more focuses on keeping good relations with your project while letting it grow alone.
Probably one of the most interesting "afterthought" extension projects using Lua is LuaTeX. Guile is harder to tack onto an existing project after the fact, you better start designing with it from the start.
GNU Guile 2.0.7 released
Posted Dec 4, 2012 10:58 UTC (Tue) by mpr22 (subscriber, #60784)
[Link]
(e) is somewhat inaccurate. While it's true that a given instance of Lua only has a single numeric type, and the default configuration uses double, you can recompile your particular instance of Lua to use some other numeric type if that's what your use case indicates.
GNU Guile 2.0.7 released
Posted Dec 4, 2012 11:30 UTC (Tue) by dakas (guest, #88146)
[Link]
I don't consider it inaccurate. Yes, you can recompile Lua to use a single other numerical type, typically integer, possibly even complex, because the source code uses a #define for this and has been carefully written to avoid mixing its number type with actual internal operations. That is considerate, but it does not give Lua a numerical stack but merely changes its single type, so you then forego the use of double.
And you need to recompile Lua for that, whereas you can just link with the standard libguile whatever your number requirements may be.
You can consider me a Lua fanboy, so if I mention a disadvantage in passing, it is rarely an advantage to dwell on it as I might have good reason for my opinion.
GNU Guile 2.0.7 released
Posted Dec 4, 2012 18:45 UTC (Tue) by beagnach (guest, #32987)
[Link]
Thank you for the detailed technical overview of the relative merits of these two languages. I wish more people commenting on technical issues would adopt a similarly thorough and mature approach.
GNU Guile 2.0.7 released
Posted Dec 4, 2012 18:49 UTC (Tue) by atai (subscriber, #10977)
[Link]
A disadvantage of Guile is that it should offer good support for minimalist use, to be able to compete with Lua in many scenarios. Having a full tower of numerical types is a good feature, but for applications like a bootloader do you need all the numerical types? Grub 2 uses Lua, if I remember correctly
GNU Guile 2.0.7 released
Posted Dec 4, 2012 19:36 UTC (Tue) by dakas (guest, #88146)
[Link]
Yes, Guile is not minimalistic, and Guilev2 is a further step away. In particular when you are not designing a system from scratch but just looking for a simple way to extend an existing system with some programmability not bringing a whole lot of its own complexity into the game, Lua might be a better choice. Guile is moving into the direction of a system foundation rather than a system extension. That is basically its positioning for getting into Emacs, and that is getting more and more the way in which it is integrated with LilyPond.
But it is not exactly the niche of "extension language" that it is mostly being advertised for.
GNU Guile 2.0.7 released
Posted Dec 4, 2012 20:49 UTC (Tue) by HelloWorld (guest, #56129)
[Link]
> Grub 2 uses Lua, if I remember correctly
You don't, Grub 2 has its own sh-like scripting language.
GNU Guile 2.0.7 released
Posted Dec 4, 2012 23:53 UTC (Tue) by atai (subscriber, #10977)
[Link]
OK I did some search. Grub 2 did use Lua for some time and later dropped it.
GNU Guile 2.0.7 released
Posted Dec 5, 2012 19:14 UTC (Wed) by cjwatson (subscriber, #7322)
[Link]
Not quite true either. It was never the default; and we still support it as a bolt-on extension from grub-extras. It's the sort of thing you might build in if you have particularly complex scripting needs. For most purposes, we'd rather focus on the sh-like "GRUB script".
Grub script
Posted Dec 12, 2012 13:57 UTC (Wed) by HelloWorld (guest, #56129)
[Link]
By the way, is there a way to iterate over the files in a directory with that language? There seems to be no command substitution and it doesn't seem possible to loop over the result of a globbing expression either.
GNU Guile 2.0.7 released
Posted Dec 6, 2012 1:13 UTC (Thu) by geofft (subscriber, #59789)
[Link]
It's in grub-extras, but not part of the GRUB core (and as far as I know not in any distro packages):
Posted Dec 5, 2012 6:31 UTC (Wed) by khim (subscriber, #9252)
[Link]
The main competitor of Lua (which is used more often then Guile!) is python which is hardly minimalistic.
Nitpicking
Posted Dec 5, 2012 9:53 UTC (Wed) by renox (subscriber, #23785)
[Link]
> Having a full tower of numerical types is a good feature
Yes, if the "full tower" was actually full: I hate the term "full tower" when it is used on languages which only provides floating point to describe real number, if these languages were also providing floating point **ranges** then I would agree that this is a "full tower of numerical types".
Nitpicking
Posted Dec 5, 2012 14:08 UTC (Wed) by dakas (guest, #88146)
[Link]
Well, add modular types and Galois fields and/or polynomials into the mix as they also belong to a "full numeric stack".
With Guile, you can easily extend the numeric stack using GOOPS, its OO system. The main disadvantage with GOOPS is that it is so hopelessly generic, invasive, and flavorless that it provides no guidance for how to actually cast your OO task into concepts, and it is hard to guess just what kind of usage might get streamlined for speed, and what not.
Extending the numeric stack, however, is rather straightforward, and the GOOPS manual illustrates it by demonstrating how one would implement a complex type if it was not already there.
Nitpicking
Posted Dec 5, 2012 14:20 UTC (Wed) by renox (subscriber, #23785)
[Link]
> Well, add modular types and Galois fields and/or polynomials into the mix as they also belong to a "full numeric stack".
A numeric stack can never be full OK, but I wouldn't put on the same level "Galois fields"(whatever they are) and a proper representation of real numbers(*)!
*:which I don't consider normal floating point representation to be.
Nitpicking
Posted Dec 5, 2012 16:26 UTC (Wed) by HelloWorld (guest, #56129)
[Link]
So what would you consider a "proper" representation of real numbers, and what's wrong with floating point numbers?
Nitpicking
Posted Dec 5, 2012 16:50 UTC (Wed) by renox (subscriber, #23785)
[Link]
> So what would you consider a "proper" representation of real numbers, and what's wrong with floating point numbers?
I guess I should have been clearer in http://lwn.net/Articles/528065/ ..
What is wrong with floating point number is that they give you an approximation of the real number and it's a lot of work to know which bits of the floating-point mantissa are meaningful and which are garbage..
Floating-point range/interval (http://en.wikipedia.org/wiki/Interval_arithmetic) provide bounds on rounding errors.
Nitpicking
Posted Dec 5, 2012 19:05 UTC (Wed) by HelloWorld (guest, #56129)
[Link]
Oh, that's interesting, thank you.
Nitpicking
Posted Dec 6, 2012 0:14 UTC (Thu) by khim (subscriber, #9252)
[Link]
It's not all that interesting because once you start going in this directions you can never stop. Quite often intervals are not enough (when you have something like x=0.1±0.2 suddenly 1/x becomes almost useless) and then variety of approaches are used (aforementioned Wikipedia article mentions quite a few of them). I fail to see why general-purpose language needs all that cruft: guile gives you rationals (which are suitable for most purposes) and when you need speed you can fall back to FPU-provided float (with appropriate price paid in loss of precision). If and when our CPUs will start providing intervals arithmetic in hardware it'll be useful to give access to these, too, but till then... interval arithmetic belongs to the same bucket Galois fields and/or polynomials.
Nitpicking
Posted Dec 6, 2012 8:42 UTC (Thu) by renox (subscriber, #23785)
[Link]
> It's not all that interesting because once you start going in this directions you can never stop. Quite often intervals are not enough
This is the opposite IMHO, most of the time the precision you have with floating point is good enough, that's why nobody care about intervals, but without intervals when (very rarely) you have a precision issue, you don't notice it which can be very problematic as in your example if you're trying to do 1/x on x=0.1+-0.2 with floating points you have the result 10 and you're (mistakenly) happy, with intervals you can see that there is an issue.
Of course, the discussions about interval arithmetic talk about the potential issues of interval arithmetic where your computation are precise enough but the interval is too big (because you wrote x*x instead of x^2 for example), this doesn't mean that this happen often..
> guile gives you rationals (which are suitable for most purposes)
Unless you want to use "rare" things such as square root, logarithms, exponentials, cos/sin, etc?
As for CPU speed, I'm not sure that for common operation (+,-,*,/) floating point ranges are much slower than rationals (on x86s which have powerful CPUs)..
Nitpicking
Posted Dec 8, 2012 17:10 UTC (Sat) by khim (subscriber, #9252)
[Link]
As for CPU speed, I'm not sure that for common operation (+,-,*,/) floating point ranges are much slower than rationals (on x86s which have powerful CPUs)..
It's not about speed. It's about exact calculations vs nonexact calculations (non-coincidentally "exact" is property of a number in scheme and thus guile). Arbitrary-precision rationals are top-of-the-pyramid for the exact calculations. As for inexact ones... they will always be non-exact and you can build whatever you want on top of what CPU (and guile) is offering.
The fact that recent versions of both AMD and Intel CPUs added support for half-precision (16bit!) floating point numbers should say you something about this whole business. Exact calculations may be true or not - and guile gives you everything you need for these. Inexact calculations are always approximation and there are bazillion ways to do that approximation thus guile's approach to give you FPU-provided primitives and nothing else looks sensible. You may extend the tower using GOOPS in any direction you want.
Unless you want to use "rare" things such as square root, logarithms, exponentials, cos/sin, etc?
Indeed. All these things are extremely rare. What you need relatively often is rounded up (or sometimes down) square root, rounded up (or sometimes down) logarithm, etc. Floating points are usually enough for that.
This is the opposite IMHO, most of the time the precision you have with floating point is good enough, that's why nobody care about intervals, but without intervals when (very rarely) you have a precision issue, you don't notice it which can be very problematic as in your example if you're trying to do 1/x on x=0.1+-0.2 with floating points you have the result 10 and you're (mistakenly) happy, with intervals you can see that there is an issue.
And what can you do with your numbers at this point? The answer: usually nothing. You may be surprised but programs which produce useful result 99% of time but some nonsense 1% of time are preferred by users to programs which produce useful result 90% of time and refuse to even run 10% of time. Even if such programs never produce incorrect result.
Of course, the discussions about interval arithmetic talk about the potential issues of interval arithmetic where your computation are precise enough but the interval is too big (because you wrote x*x instead of x^2 for example), this doesn't mean that this happen often..
This is wrong measure. Most of the time interval arithmetic and plain old IEEE arithmetic give you more-or-less the same answer. But in cases where interval arithmetic says that there are no useful result more often then not it's wrong. Why? Because numbers which you receive from real life don't adhere to the intervals idea! When you get something like 0.1±0.2 as an input usually it means that it's probably 0.1±0.05, but if stars were all aligned incorrectly when measurement took place and all possible sources of errors materialized at once it may become 0.3 or -0.1. IEEE will give you x=10 and most of the time it'll be good enough (because you don't really exploit all your systems at close to 100% of capacity and often spare power is quite large) so you'll be able to cope with 20 or 30, too. Intervals will give you the answer: "wrong input data" and you'll be forced to revamp the whole model.
Interval arithmetic if not used everywhere and is not supported by FPUs for a reason.
P.S. Funny that you mentioned cos/sin in your argument. Do you know how sin and cos are implemented in FPU and what precision they actually offer? The answer is obvious: you don't. And if you naively expect to get the result with full precision supported by double then you are sorely mistaken. This means that if you want to ever use interval arithmetic with sin or cos (and other transcendent functions) then you need to reimplement them from scratch in a much, much, MUCH less efficient manner. It may be useful in some cases, but this is not something you want in general-purpose extension language by default.
Embedding vs. extending
Posted Dec 5, 2012 0:16 UTC (Wed) by civodul (subscriber, #58311)
[Link]
Posted Dec 6, 2012 20:48 UTC (Thu) by dvdeug (subscriber, #10998)
[Link]
The discussions don't seem to target my issues at all. When I'm thinking of embedding a language, it's because I have a program that I would like for people to be able to extend; say a graphics program that people want an easy way to write plugins for, or a game that people want to write AIs for. I may well want for certain environments to be able to not compile in a 3MB Python interpreter. The Python one asks "do you want your application to inter-operate with other applications that Python can use?" Why would I? I'm not building a library here; why is it vitally important that Gimp and Quake can run at the same time?
Embedding vs. extending
Posted Dec 6, 2012 21:19 UTC (Thu) by andrel (subscriber, #5166)
[Link]
Well if your goal is to automate a pipeline which starts with a Quake screenshot and process it in GIMP to get the final output, then yes you want them both running at the same time.
Embedding vs. extending
Posted Dec 6, 2012 23:16 UTC (Thu) by dvdeug (subscriber, #10998)
[Link]
Why? You produce the screenshot, and send it through the pipeline and send it into GIMP. No need to bring everything into one process.