
Getting Started with Emacs 24 - bozhidar
http://batsov.com/Emacs/2011/10/09/getting-started-with-emacs-24.html
======
agumonkey
Additional note, the traditional starter kit configuration files, now in
version 2 (tailored for emacs 24)

<https://github.com/technomancy/emacs-starter-kit>

~~~
WalterGR
_the traditional starter kit configuration files_

Traditional in what sense? Is emacs-starter-kit considered a must-have?

~~~
agumonkey
I didn't meant it literally, but in case newcomers are tempted to try this new
release, they might want some dotemacs files to play along.

~~~
bozhidar
That's why I've created the "non-traditional" Emacs Prelude
<https://github.com/bbatsov/emacs-prelude> ;-)

------
nyellin
Does anyone know the status of multithreading and concurrency in Emacs 24? As
far as I can tell, multithreading didn't make it in. Why not?

~~~
hollerith
None of the Unix shells (csh, bash, etc) are multithreaded either. Like Emacs,
what concurrency they have comes from fork, exec and setting "listeners"
(terminology?) for signals from child processes.

If I were to write a web server in Emacs Lisp (or bash) I would probably want
multithreading in Emacs or (bash) but I have never felt the desire to write a
web server _or anything else_ that needs multiple threads all running in Emacs
Lisp, and I've written many 10s of 1000s of lines of Emacs Lisp.

Although my web browser (Firefox) is multithreaded, I spend orders of
magnitude more time waiting for my web browser's UI to stop being unresponsive
than I do waiting for Emacs or any of the Unix shells I have used to stop
being unresponsive.

~~~
nyellin
Here are some features that to the best of my knowledge are currently
impossible:

* Non-blocking save on network drives

* Non-blocking autosave

* Rebuilding tag tables in the background

* Loading and fontifying large files in the background (i.e. concurrent fontification, not just jit-lock)

* Concurrent url fetching and downloads (e.g. updating el-get without blocking) [1]

* Concurrent spellcheck

* Fast scrolling in large buffers (especially complex XML files opened in nxml-mode) without annoying hacks like <http://stackoverflow.com/q/4160949>

There are plenty more improvements that wouldn't affect me personally. I
imagine erc and other networked packages would also benefit from true
concurrency.

[1] I just started using el-get on my laptop and I haven't checked this yet.
Maybe it somehow works.

~~~
jrockway
Some of these exist, and all are possible without threads.

 _Non-blocking save on network drives; Non-blocking autosave_

This requires a memcpy and the aio_* functions. When a save is requested, you
make a copy of the buffer in memory (so that what ends up on disk is what the
buffer looked like exactly when the save was requested), then you stream this
data to disk with aio_write (perhaps making the write atomic by doing a
synchronous rename after all the data is on disk). This would probably take no
more than a few hours to implement, and most of the complexity is simple to
handle with atomic writes and aio_cancel. I think the biggest problem is
handling the "userspace" semantics; after-save hooks expect to run after the
data is on disk but before the user has changed the buffer in any way. What do
you do about this?

(I've done this before. I have an Emacs mode at work that saves to a special
centralized database in addition to the local disk at every modification. We
just queue the write in before-save hook and tell some other process to read
the data from a temp file that we create. It works perfectly, even on
Windows!)

 _Rebuilding tag tables in the background_

This is easy and eproject already does it. You run etags in a background
process and when it's done, point Emacs at the new tags tables. Since the tags
tables don't do anything until a lookup is requested, this is completely
asynchronous.

Try it today:

[https://github.com/jrockway/eproject/blob/master/contrib/epr...](https://github.com/jrockway/eproject/blob/master/contrib/eproject-
tags.el)

 _Loading and fontifying large files in the background (i.e. concurrent
fontification, not just jit-lock)_

This you can't do unless you can guarantee that matchers are bounded and
generate correct results no matter what the boundaries are. I don't know of
any programming mode that could be made to meet this invariant easily;
consider the case:

    
    
        /* this code is bad: 
           int i = 0; */
    

If we had two threads fontifying this block, and the bounds were set to thread
1 = line 1, thread 2 = line 2, the results are going to be wrong. The first
line will be treated as a comment and the second line will look like a normal
variable declaration because getting the correct syntax information requires
analyzing the entire first line. Any language with multiline constructs
(string literals, preprocessor directives, comments, etc.) will have this
problem, thus making parallelization Not Easy. If font-locking is slow,
profile it and fix the algorithm, but don't expect speedups for free. Parsing
programs that are invalid (as most are while being typed; you type characters,
not tokens) and guessing what the user "means" is hard.

 _Concurrent url fetching and downloads (e.g. updating el-get without
blocking)._

Fork curl or wget. Display the result when done. Or, implement HTTP from
scratch; network IO is already nonblocking.

 _Concurrent spellcheck_

This is already implemented this way; a pipe is opened to aspell and words are
piped to aspell as necessary. If parsing the results is too expensive and you
don't care about interactivity, wait for bigger batches of data back from
aspell. All IO to other processes is asynchronous and can be made synchronous
with special calls like accept-process-output.

 _Fast scrolling in large buffers (especially complex XML files opened in
nxml-mode)_

How will threads solve this problem?

~~~
nyellin
Thank you, especially for your notes on aio_. As promised, I sent you
something by email, but know that your comment is worth more than that.

 _Fast scrolling in large buffers (especially complex XML files opened in
nxml-mode)_

I think nxml-where.el is guilty for the slow scrolling in large xml files. I
wanted to offload that to another thread, but a simpler solution is to only
update the path post-scroll.

~~~
jrockway
Thanks!

It's also worth pointing out that Emacs and Emacs Lisp need not be
multithreaded in order to implement specific asynchronous operations. If aio
did not exist, there's nothing stopping you from creating a thread (from C),
doing your blocking save there (and nothing else), and sending a note back to
the lisp side when it's done. It's generic threading that adds complexity,
because that would require all state-changing operations to be threadsafe,
which can be very difficult to "bolt on" to a complex system like Emacs. (Not
to mention locking overhead; see Python's GIL debate.)

A good example of this approach is the 0MQ messaging library. While it is
internally threaded, it does not care what the application does about thread
safety; there is no way that you can ever "see" its threads. It simply
requires that you pass ownership of blocks of memory to the library, thus
avoiding locking and issues of thread safety while still using threads.

