Tuesday, February 17, 2009

Stone Tools and Scala Development - Part I Editing

I see great potential in Scala, the programming language.

Scala is a good thing. Scala deserves to win, it deserves to supplant Java in enterprise IT because it is better. If their exists some law of nature dictating that the universe must maintain itself in good kilter and balance every "worse is better" thing with a better thing then Scala will succeed.

Currently the language and compiler exceeds any IDEs capability to properly host it. And a huge proportion of developers have never experienced anything other then the all mothering Eclipse, Netbeans, or Microsoft IDE. Without the skeletal support of the IDE they are rendered near impotent, become jelly like, puddle and quiver back and forth producing nary a line of code.

Thankfully there are Scala plugins for Netbeans, Intellij and Eclipse. Yet there exists no more gnashing teeth on the Scala mailing list then concerning the relative immaturity of these plugins.

Amazingly these days, so interlinked is the concept of computer language and its IDE(s) many no longer see them as less then monolithic. Scala, the language, sucks because the IDE support sucks.

Fortunately, frankly surprisingly, one sees continued steady effort and work invested in improving these plugins. Surprisingly because it is a near thankless job and borders on pure drudgery. We salute you.

Until these tools mature, I claim it is possible to eek out a development existence, even a highly productive one using nothing more then the stone tools of a compiler, editor, make-like system, unix utilities and the command line. Some even view this as the superior, even ultimate IDE.

Here is how I roll with my stone tools for Scala development.

First off Linux. All of details below assume a Linux system.

Editing Scala Code With Emacs.


I know, we all heard it a 1000 times about those emacs gods who transcend the very laws of nature through advanced enlightenment with emacs which simply escapes us low karmic souls.

It's true, if you invest in emacs long enough it starts to pay off like a rigged slot machine. Put you have to feed it a lot of quarters first. I'm far from an emacs guru, but I've reached a point down the 7-fold path where I can't live without it and marvel how I ever did.

Get the latest emacs. Emacs was moribund for years but has experience a renaissance recently. The vastly improved font handling is worth it alone. It is once again better then XEmacs IMHO. Get good ol' emacs, I build it from cvs and it's easy. Standard configure, make, dance and if I remember the README gives an option to bypass configure with the proper Make incantation.

Here is my base .emacs stuff.

(global-font-lock-mode t)

(windmove-default-keybindings)

(setq use-file-dialog nil)

;; "y or n" instead of "yes or no"
(fset 'yes-or-no-p 'y-or-n-p)

;; Highlight regions and add special behaviors to regions.
;; "C-h d transient" for more info
(setq transient-mark-mode t)

;; Display line and column numbers
(setq line-number-mode t)
(setq column-number-mode t)

(global-set-key "\C-c\C-w" 'backward-kill-word)

;; Remove unnecessary gui stuff
(if (fboundp 'scroll-bar-mode) (scroll-bar-mode -1))
(if (fboundp 'tool-bar-mode) (tool-bar-mode -1))
(if (fboundp 'menu-bar-mode) (menu-bar-mode 1))

(blink-cursor-mode 0) ;; no blink

(set-background-color "black")
(set-face-background 'default "black")
(set-face-background 'region "black")
(set-face-foreground 'default "white")
(set-face-foreground 'region "gray60")
(set-foreground-color "white")
(set-cursor-color "red")

This will give you a clean, black background based emacs with maximum screen space, but leaving the main menu, which I found on someones (thank you) emacs blog.

Next install the Scala folks provided scala-mode for emacs. They did a nice job.

svn co http://lampsvn.epfl.ch/svn-repos/scala/scala-tool-support/trunk/src/emacs

Follow the readme and install. The yasnippit stuff is not bad, but I don't use it extensively, but give it a whirl and decide yourself.

For the record here is what my .emacs file looks like after I installed the provided scala-mode and yasnippit for scala.

;;;;;;;;;;;;
;; SCALA
;;;;;;;;;;;

(let ((path "/usr/local/share/emacs/site-lisp/scala"))
(setq load-path (cons path load-path))
(load "scala-mode-auto.el"))

(defun scala-turnoff-indent-tabs-mode ()
(setq indent-tabs-mode nil))

;; scala mode hooks
(add-hook 'scala-mode-hook 'scala-turnoff-indent-tabs-mode)

;; Maven bound to
(add-hook 'scala-mode-hook
'(lambda ()
(define-key scala-mode-map '[f6] 'mvn)))

;;;;;;;;;;;;;
;; YASNIPPIT
;;;;;;;;;;;;;

(add-to-list 'load-path "/usr/local/share/emacs/site-lisp/yasnippet-0.5.7")
(require 'yasnippet)
(yas/initialize)
(yas/load-directory "/usr/local/share/emacs/site-lisp/yasnippet-0.5.7")

More on that Maven key binding later.

Now we can edit Scala code effectively. There are some indentation issues and I've been able to improve it a bit but I still have fix a few things which I broke in the process before it is worthy.

With Yasnippit and alt-/ completion its not too bad. The next piece is exuberant ctags so you can alt-. and jump directly to that class, object or trait definition.

First there is ctags and then there is ctags. Emacs comes with a program called ctags. ctags will index your source code symbols so you can hop around your source code files.

There is a variation of ctags called exuberant ctags found at http://ctags.sourceforge.net/ and you need to install it. Again it should be quick and easy if you've ever done the ol' Linux Make dance.

Be careful, when you make install emacs as it reinstalls its version of ctags so you need to make install exhuberant ctags. Just make sure however you go about it, exhuberant ctags is what is executed in your PATH and not the standard emacs ctags.

In your home directory create a .ctags file with the following.

--langdef=Scala
--langmap=Scala:.scala
--regex-Scala=/^[^\*\/]*class[ \t]*([a-zA-Z0-9_]+)/\1/c,classes/
--regex-Scala=/^[^\*\/]*object[ \t]*([a-zA-Z0-9_]+)/\1/o,objects/
--regex-scala=/^[^\*\/]*trait[ \t]*([a-zA-Z0-9_]+)/\1/t,traits/
--regex-Scala=/^[^\*\/]*case[ \t]*class[ \t]*([a-zA-Z0-9_]+)/\1/m,case-classes/
--regex-Scala=/^[^\*\/]*abstract[ \t]*class[ \t]*([a-zA-Z0-9_]+)/\1/a,abstract-classes/
#--regex-Scala=/^[^\*\/]*def[ \t]*([a-zA-Z0-9_]+)[ \t]*.*[:=]/\1/f,functions/
#--regex-Scala=/^[^\*\/]*val[ \t]*([a-zA-Z0-9_]+)[ \t]*[:=]/\1/V,values/
#--regex-Scala=/^[^\*\/]*var[ \t]*([a-zA-Z0-9_]+)[ \t]*[:=]/\1/v,variables/
#--regex-Scala=/^[^\*\/]*type[ \t]*([a-zA-Z0-9_]+)[ \t]*[\[<>=]/\1/T,types/

I just like to index classes, traits, objects and case-classes. Hmmm just noticed I should add case objects as well.

Now when editing a scala file in emacs, under the emacs Scala menu item, Features you can build and use tag files which index key symbols in your source code.

Explore your Scala editing environment. No two people use emacs in the same fashion.
  • alt-x rgrep in emacs to ad-hoc search your scala files.
  • use alt-/ for simple minded completion.
  • Hit the F1 key to pop up your speed bar window. Note at the bottom you can click and switch to view, buffers, files etc in the speed bar.
  • alt-x erc and join #scala in your emacs for instant Scala support. :)
  • Are you using ctr-x o to move between buffers? There are tons of better ways. Open up a several scala buffer windows ctr-x 2 or 3, now hold down shift and use your arrow keys to move around.
  • Notice that there are 5-6 Tag search options under the Scala Menu, try them all.
  • While editing a scala file, put your cursor over a type definition (x: MyType, ...) and do alt-.
  • Toggle yas/snippit, alt-x yas/minor-mode. In your scala source file type 'def ' or 'class ' and hit the tab key.
  • Run the scala interpreter in emacs its right there in the Scala menu.

Next post I'll address setting up and building your Scala project using Maven from inside emacs.

5 comments:

Normen Müller said...

Thanks for this introduction. It just works nicely.

Regarding ctags:
I downloaded ctags at http://ctags.sourceforge.net/ and did the ol' Linux Make dance ;)

Before I ran ``make install'', however, I kept on reading your blog and got a bit confused on how to proceed. Emacs is already installed on my system (actually I'm using aquamacs). So, I can just run ``make install'' on ctags?

Anyway, I skipped the installation of ctags -- for now.

Currently I'm getting my first emacs/ scala experiences and for editing it is awesome. I still don't know how to compile/ build an entire project, though. I am waiting for your next blog entry ... ;)

I guess then I also have to learn maven -- which I never ever used before.

The Grey Lens Man said...

Normen,

Yes, make install should install ctags in /usr/local and in your path.

$ which ctags
/usr/local/bin/ctags
$ ctags --version
ctags: Warning: Ignoring non-option in /home/ray/.ctags

Exuberant Ctags 5.7, Copyright (C) 1996-2007 Darren Hiebert

This is what I see.

In my post I show the .ctags file content to put in you home directory. The warning does no harm, and goes away if you remove the # lines.

Anonymous said...

In your post of 22nd, you seem to be confused between
Java - which is a reasonably simple programming language. It has some flaws but none capable of forcing the sort of mess that it sounds like you've created, and
The 'Java Enterprise Programming' model, which is so flawed that it is hard to believe that any software professional could take it seriously.

The Grey Lens Man said...

Anon,

There may be debate on my opinions, but from my perspective no confusion. I have a pretty good feel for Java the language, and what a well designed language should be bringing to the table for certain classes of problems. Java is inadequate.

Java weakness is its overall weak capabilities; its fatal flaw is its inherent lack of extensibility; and its error will be the massive commercialized effort to continue Java well past the inflection point when in the normal course of events, it should plateau, and gracefully diminish. This will inhibit the next introduction cycle of software evolution. Java is the new COBOL.

Regarding the "mess". I'll say its primarily not one of my own making, but of inheritance.

Regarding the Java Enterprise Model, no doubt, deeply flawed Certainly Conway's Law is well reflected there. However, I also claim that model is an amplification of, and a compensation for, the limitations of the Java itself. In other words, a more powerful, extensible language, would have lead to a radically different result.

Robert Young said...

>> Java is the new COBOL.

While you are by no means the first to say it in print (Bruce Tate was the first I saw; and that was well after I said it, but didn't have any publishing then), this is what attracts Fortune X00 companies to it. It is possible, and the various Enterprise Frameworks abet this, to replicate the COBOL programmer's mind in Enterprise Java. Were it not for this, java would no longer exist.

While there are some other uses, if one subtracts both the Enterprise Coders and the Enterprise Framework Coders, one could fit the remaining java coders in a small dinghy.

Post a Comment