Friday, December 28, 2007

Install Proggy Fonts for Emacs in Gentoo

Coding horror discussed various nice programming fonts (see here and here). Intrigued by these posts, I decided to try these fonts on my Gentoo box. Following is a record of what I have done.

Install Fonts in Gentoo

I decided to use Proggy Clean font (website is here). This section is mainly related to this particular font, but I will discuss at the end of this section how to handle other fonts in the same site.

Instead of manually installing the font, I determined to writer one ebuild. Main rationale is to rely on font eclass to automate font installation work. The ebuild could be easily reused and even incorporate into Gentoo portage (hopefully). The other reason is that I want to practice a little bit on portage overlay and to write my first (trivial) ebuild.

Create portage overlay

If you have already setup a overlay, you may skip this part. However it should be noted that all the description in this post assumes that your overlay is located in /usr/local/portage.

Run the following commands.

# mkdir -p /usr/local/portage
# echo 'PORTDIR_OVERLAY="/usr/local/portage"' >> /etc/make.conf    

Create the ebuild

First, create the directories.

mkdir -p /usr/local/portage/media-fonts/ttf-proggy-clean

Next, create a file named ttf-proggy-clean-1.0.ebuild under the directory just created. Fill the contents as below.

inherit font

DESCRIPTION="Proggy Clean TTF font"
HOMEPAGE="http://www.proggyfonts.com/"
SRC_URI="http://www.proggyfonts.com/download/download_bridge.php?get=ProggyClean.ttf.zip"

LICENSE="Proggy"
SLOT="0"
KEYWORDS="alpha amd64 arm ia64 ppc s390 sh sparc x86"
IUSE=""

DEPEND=""

S="${WORKDIR}"
FONT_S=${S}
FONT_SUFFIX="ttf"
DOCS="Licence.txt Readme.txt"

RESTRICT="mirror" 

Some explanations of the ebuild:

  • Version: I believe the font is quite stable, therefore version 1.0 should be OK :-).
  • License: the license in the package is quite permissive, but since I cannot link it to any existing license, I category it simply as Proggy.

Run the following command to sign the ebuild.

# ebuild /usr/local/portage/media-fonts/ttf-proggy-clean/ttf-proggy-clean-1.0.ebuild digest

BTW, I refers a lot to this when writing this first ebuild (of course, the skeleton is from man font.eclass).

Install font

Now comes our familiar emerge.

# emerge media-fonts/ttf-proggy-clean

Now we need to add the font path. Open file /etc/X11/xorg.conf, find the section Section "Files", and add the following line within the section:

  FontPath "/usr/share/fonts/ttf-proggy-clean"

Then press Ctrl-Alt-Backspace to restart X server. After login again, you may issue the following command (if you have not installed xlsfonts, please do so by typing emerge xlsfonts).

# xlsfonts | grep proggy

You should see several lines looking like -altsys-proggycleantt.... If not, there is something wrong to fix (please check previous typings).

Caveat: before I add the FontPath line in section Files, that section is actually empty! Therefore X simply cannot restart. The solution is to add some default paths into that section, e.g. /usr/share/fonts/100dpi, /usr/share/fonts/misc.

How to use other fonts

Following is a guideline for other fonts listed in the same website.

  • Use appropriate directory and file name to represent the font. For example, for Proggy Square X font, one might setup directory /usr/local/portage/media-fonts/proggy-square, and create a ebuild called proggy-square-1.0.ebuild. The directory should be added into /etc/X11/xorg.conf as described above.
  • Modify the ebuild:
    • Specify appropriate DESCRIPTION.
    • Use correct SRC_URI.
    • Specify DOCS correctly. I found that X font package does not contain Readme.txt.
    • Specify FONT_SUFFIX. For X fonts, use gz; use ttf (like above) for TTF fonts.

Configure Emacs

Compared with the installation described above, this part is rather easy. Assume that you want to use the font -altsys-proggycleantt-medium-r-normal--0-0-0-0-m-0-iso8859-1 (you may select one from the output of xlsfonts as described above)d, simply add the following line in your .emacs:

(set-default-font "-altsys-proggycleantt-medium-r-normal--0-0-0-0-m-0-iso8859-1")

Monday, December 24, 2007

Weirdness of Erlang

But Erlang itself? It's too weird, and in my brief experiments, the implementation shows its age; we have in fact learned some things about software since way back then.
--Tim Bray, Prognostication

I'm just quite new to Erlang and read through Chapter 10 of Programming Erlang so far. The language really expand my mind greatly, with its pattern-matching capability (even for a Haskell user), and of course concurrency oriented programming. Inter-process communication, even across different machines, is a quite simple task in Erlang. However, as stated by Tim Bray, Erlang is too weird. In the following, I will list some weird things I met when studying Erlang. The focus is mainly on syntax, which seems to be non-essential but should have been easily improved (if backward compatibility is not an issue).

Usage of punctuation

A newcomer to Erlang will almost forget to type period after an expression one or more times. Why do we need such punctuation even in an interactive shell? I admit that using period, semicolon and comma in Emacs makes source editing more automatic, but I prefer not using them at all. Erlang should learn something from the elegance of Haskell in this aspect.

Awkward functional programming with fun

There is no fun when using fun. When writing an anonymous function, one have to use fun and append end. Even when calling a named function within a higher order function, one has to use fun like this lists:map(fun math:sqrt/1, [1.0, 2.0, 3.0]). This is awkward and Haskell way is way better again.

Handling Records

Although records are tuples in disguise, they are treated in a C-style way: i.e. if one record definition is to be used by multiple source files, it has to be put into an include file. Weird.

Macro

Fans of C/C++ may applaud when they learn that Erlang provided similar macro facilities. However it is doubtful whether this controversial feature is needed for such a functional programming language.

Makefile

Again advocates of C/C++ might be pleased to know that Erlang also relies on makefile for package management/build. Shed by the light of Haskell/Cabal, Common Lisp/ASDF or X/Y (put your favorite language and package management system here), one may expect that Erlang has a more modern way?

Conclusion

Apparently, above weird aspects are not show-stopper for the popularity of Erlang. However, appreciating the Ruby principle of Least Surprise, I cannot help but rant my impressions gathered when climbing the mind-blown-away learning curve.

Monday, December 17, 2007

Minimize Diagnostics in Common Lisp

Diagnostics generated by compilers are quite useful for programmers to spot bugs or inefficiencies in the first place. It is quite often to observe that command options -Wall -pedantic (or even -Werror) are used to invoke gcc. When investigating the situation in Common Lisp, a newcomer would be surprised to see that diagnostics and ways to handle them are actually standardized (just like other implementation-like-stuff-in-other-languages, say disassemble). In addition to the already standardized diagnostics like warning and style warning (the latter is actually a subtype of the former), some CL implementations (notably CMUCL and SBCL) provides efficiency notes, which alerts the user that the compiler has chosen a rather inefficient implementation for some operations. For SBCL users, it is highly recommended to read one part of SBCL manual to learn how to interpret SBCL diagnostics.

In typical development cycle, after writing/modifying some code and compilation, if compiler complains with such diagnostics, you know that somewhere needs your attention. However, you can only sense these new diagnostics if the number of existing diagnostics is quite small or zero. Otherwise you many not even notice the new diagnostics since you already have a bunch of them. In this sense, existing diagnostics are like broken windows, and they discourage you to identify new diagnostics. Your program will deteriorate if you do not fix these broken windows. In summary, to make the diagnostics useful, you have to minimize, or better yet, eliminate existing diagnostics.

There are two ways to stop the compiler emitting diagnostics: removal and muffling. We will discuss them separately. Note that we will use SBCL as our CL implementation in the following discussion.

1. Removing Diagnostics

This is of course our first choice, since diagnostics are indications of some risks in the code. In the following, we give some simple examples to illustrate how to delete such annoying (but useful somehow) complaints.

1.1 Warnings

Typically warnings are serious issues to be resolved immediately. One exception is that sometimes if one file contains multiple style warnings, a warning will be issued for the file itself as well. Therefore to remove such warning requires eliminating related style warnings, as discussed below.

1.2 Style Warnings

1.2.1 Variable X defined but never used.

The first consideration here should be to remove the variable causing diagnostics if possible, which has the additional benefit of simplifying code. However there are cases when we cannot change the function interface. For example, when we write reader macros with set-dispatch-macro-character, the 3rd argument is itself a function with 3 arguments like (stream char1 char2), and typically we do not use either char1 or char2. In this situation, we can use declarations like (declare (ignore char1 char2)). Sometimes, if the argument is used in some scenarios while not in other cases (typically in macro definitions), we can use declaration ignorable. An example here is the anaphoric macro acond2 defined in On Lisp, a declaration (declare (ignorable it)) is needed for the ubiquitous it.

1.2.2 Redefining FOO in BAR.

Typically such style warnings are issued when one file is reload, hence can be simply ignored. However there are some more complicated cases. One example is again related to the reader macro. If one want to use the reader macro in the same file, the definition of the reader macro should be encompassed with (eval-when (:compile-toplevel :load-toplevel :execute), as illustrated in HyperSpec. The problem is that if you write a function instead, every time you load the file, this style warning pops up. The solution? Either use anonymous functions as illustrated in HyperSpec, or spin out related part into a separate file without the eval-when stuff.

1.3 Efficiency Notes

It should be noted that efficiency notes are emitted only when we turn on optimization declarations, e.g. (declare (optimize (speed 3) (safety 0))). It is well known that premature optimization is the root of all evil. Therefore before battling against those notes, one should check whether the function in question is the bottleneck or not. If not, one should remove those optimization declarations, which can make the core simpler and more maintanable; otherwise (when the optimization is really necessary), one can proceed further with techniques discussed below.

As indicated by the informative CMUCL manual on efficiency notes, the solution to dismiss these notes is to provide sufficient type declarations. It should be noted that current SBCL is smart enough to perform type inference, therefore it is unnecessary to clutter the code with type declarations for every expressions.

1.3.1 Doing X to pointer coercion

Such notes are typically emitted for function return values which are of boxed types. For example, on 64-bit machines, double-float is still boxed (it requires exactly 64-bits!), therefore compiling the following functions will get a note doing float to pointer coercion (cost 13) to "<return value>".

Code-list-1

(defun df+ (x y)
  (declare (optimize (speed 3) (safety 0))
           (double-float x y))
  (+ x y))

How to remove these notes? One way is to use unboxed types. For example, in above example, one can use single-float instead of double-float for 64-bit CPUs. However such solution is not always available: one reason is that there are only a few unboxed types, and the other one is that sometimes the boxed types are what we really need: e.g. double-float is required from accuracy point of view. Another solution is to use local functions. Since compiler know how to utilize the return value, the efficiency notes will not be emitted. One example is shown below:

Code-list-2

(defun df-outer ()
  (flet ((df+ (x y)
           (declare (optimize (speed 3) (safety 0))
                    (double-float x y))
           (+ x y)))
    (coerce (df+ 1.0d0 2.0d0) 'float)))

Note that the above example is simply contrived to illustrate that using local functions can remove efficiency notes.

2. Muffling Diagnostics

There are many occasions that above solutions cannot be applied. In this case, we can muffle the diagnostics. The intention of muffling is not that we are going to adopt an ostrich policy for those diagnostics. The underlying rationale is actually as following:

  • We acknowledge that there is no way to eliminate the diagnostics.
  • The diagnostics do not impose any risks to the program per se.
  • The diagnostics have to be suppressed in order not to obscure other diagnostics.

One example is the above code-list-1. If such a standalone function optimized for double-float is really what we want, we cannot remove the efficiency note on 64-bit machines (when will 128-bit CPUs become mainstream?). Since there is no problem with the code, we can safely muffle the annoying note to avoid it to distract our attention further.

Common Lisp does provide a standard way to muffle standard diagnostics (i.e. warnings and style warnings, but not notes since they are not standardized). This is function muffle-warning, however its usage seems not straightforward. SBCL wraps it up and provides a pair of declarations sb-ext:muffle-conditions and sb-ext:unmuffle-conditions to muffle diagnostics. We will use them in the following discussion. If portability is desirable, one should use #+sbcl; however in the following examples, we do not use it for simplicity.

2.1 Local Control

It is preferred that we muffle the diagnostics in a local definition if possible. We can specify which types of diagnostics to muffle and use the pair of extensions for advanced purposes, as illustrated in SBCL manual. Following is an example to illustrate how it is applied to our example (code-list-1) above.

Code-list-3

(defun df+ (x y)
  (declare (optimize (speed 3) (safety 0))
           (double-float x y)
           (sb-ext:muffle-conditions sb-ext:compiler-note))
  (+ x y))

Note the usage of sb-ext:muffle-conditions in line 4 above.

2.2 Global Control

One can muffle diagnostics globally in the way like (declaim (sb-ext:muffle-conditions sb-ext:compiler-note)). However it is not recommend to do so since we will lose the whole point of using diagnostics. Nevertheless using pairs of global declarations is useful sometimes, since it can muffle the diagnostics issued for top level structures, and allow the compiler to complain again if it meets issues in other places.

Let's use code in On Lisp again as another example. When emulating Scheme-like continuations in Common Lisp, Paul Graham defined parameter *cont* as (setq *cont* #'identity) in top level. SBCL emits a warning undefined variable: *cont* when compiling the code. It should be noted that we cannot use defvar for this parameter, as discussed in the text. To muffle the warning, we can add a pair of declarations as in code-list-4 below.

Code-list-4

(declaim (sb-ext:muffle-conditions warning))
(setq *cont* #'identity)
(declaim (sb-ext:unmuffle-conditions warning))

Update: as pointed out by Lars Rune Nøstdal in the comment below, a cleaner way is to use locally. The above example can be simplified as following:

Code-list-5

(locally (declare (sb-ext:muffle-conditions warning))
  (setq *cont* #'identity))

Conclusion

To make the best of compiler diagnostics, it is good to remove the existing ones. Happy hacking beautiful code!

Tuesday, December 11, 2007

The Last Clip of SICP Video

This morning, I finished watching SICP video lectures with my tiny Dopod 838 QVGA screen when commuting on company shuttle bus. As I have pointed out in previous post, learning such a mind-expanding book has never been such a pleasure with the aid of videos.

When watching the video, one may have already noticed at the beginning that the atmosphere was somehow different, with Abelson wearing a foolscap and almost everybody wearing sunglasses. In this very last clip, after Sussman explained the simple-but-very-effective Minsky garbage collector and discussed the halting problem, the usual Q&A section started. The last tricky question was Is this the last question?, and Sussman replied Apparently yes after a long pause. And the lecture just closed here, with every student (actually HP employees) getting a close-up.

I just studied the lectures along with them, learned a lot of things, and was delighted and blown away many times. The video was taken in July 1986, when I had no idea of what computer is. It's interesting that I managed to learn things together with them. Although I have not really dived into the books and the exercises, I'm sure I will do so quite soon, at least to meet the authors again during reading.

Friday, December 7, 2007

Nicer Fonts for Gnuplot

Gnuplot is a great visualization tool to use. However the default font is not so pleasant for me. Following is the record on my adventure for alternative fonts. The description is mainly Gentoo oriented.

Which font to use?

I'd like to try TTF font for nicer looking, and Bitstream Vera bundled with Gnome just fits my taste. In case that you have not installed Gnome (e.g. you're pretty much satisfied with the plain terminal, or you use X only without any desktop environment, or you are a fan of other desktop environments like KDE or E17), you may install the font with one command in Gentoo: emerge ttf-bitstream-vera.

Build Gnuplot

Gnuplot should be built with libgd support. To do so, you should enable the USE flag "gd". You may add gd to your make.conf, or use the following command to add it for gnuplot alone:

echo "sci-visualization/gnuplot gd" >> /etc/portage/package.use

After that, build gnuplot by typing emerge gnuplot. The version I'm using for this post is 4.2.2.

Configure environment variable

Add the following line to one of the shell profiles (e.g. ~/.bash_profile):

export GDFONTPATH=/usr/share/fonts/ttf-bitstream-vera

Try it out

Now launch gnuplot. To test whether our settings take effect, type the following at gnuplot prompt:

gnuplot> set term png enhanced font "Vera,12"
Terminal type set to 'png'
Options are 'nocrop enhanced font Vera 12 '
gnuplot> set output "test.png"
gnuplot> plot sin(x)
gnuplot> quit

Now start your favorite photo viewer to examine test.png (I use Emacs in this case). Does the figure looks prettier than before? (Note: it seems that the font name is case sensitive and should be consistent with the actual file name of the font: "Vera" works in above example while "vera" not.)

One limitation is that TTF fonts are not available to X11 terminal therefore you cannot directly enjoy the effect within gnuplot. Emacs users using gnuplot-mode might not feel too much switching pain in this case. Another solution is: if you have ImageMagick installed, you can use png terminal, and pipe the output to ImageMagick by typing set output '|display png:-' instead of plain test.png as shown above.