<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Étoilé News</title>
  <link rel="self" href="http://etoileos.com/feeds/news/atom/"/>
  <icon>http://etoileos.com/favicon.png</icon>
  <updated>2008-11-21T07:45:00-08:00</updated>
  <author>
    <name>Étoilé Project</name>
    <email>info@etoileos.com</email>
    <uri>http://etoileos.com/</uri>
  </author>
  <id>http://etoileos.com/</id>
  
<entry>
<title>Étoilé 0.4.0 Release Announcement</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/11/16/2300/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/11/16/2300/</id>
<updated>2008-11-16T23:00:00-08:00</updated>
<content type="html"><![CDATA[<p>Étoilé intends to be an innovative, GNUstep-based, user environment built from
the ground up on highly modular and light components. It is created with
project and document orientation in mind, in order to allow users to create
their own workflow by reshaping or recombining provided Services (aka
Applications) and Components.  Flexibility and modularity on both User
Interface and code level should allow us to scale from handheld to desktop 
environments.</p>

<p>0.4 is a developer-targeted release on its way towards this goal.  As a
developer-focussed release, this predominantly consists of frameworks.  A few
demonstration applications are also included.  More will be added during the
0.4.x release series, leading to a user-focussed 0.5 release next year.</p>

<h3>Highlights</h3>

<p><em>CoreObject</em> is a framework for describing and organizing model objects.  It
supports automatic persistence and versioning by recording messages sent to
objects. It offers a flexible versioning scheme where both individual objects
and their entire object graph can be versioned separately. The built-in object
model is a generalization of the property model used by the AddressBook
framework.  Foreign model objects can be also integrated by wrapping them with
a special proxy.  CoreObject uses the <em>EtoileSerialize</em> framework which, in many
cases, allows objects and messages to be automatically serialized with no
extra code being written.</p>

<p><em>LanguageKit</em> is a compiler kit built on top of LLVM for creating dynamic
language implementations using an Objective-C runtime for the object model.
This is used by <em>SmalltalkKit</em>, implementing Étoilé's Pragmatic Smalltalk, a
Smalltalk JIT compiler which generates code binary-compatible with Objective-C,
allowing classes to be written in a mixture of Smalltalk and Objective-C.</p>

<p><em>EtoileFoundation</em> is the core framework for all Étoilé projects, providing
numerous convenience methods on top of the OpenStep foundation and
significantly better support for reflection.  This includes <em>EtoileThread</em>
which allows objects to transparently be run in a separate thread.  It also
includes a number of extensions to the Objective-C object model, allowing
traits and mixins.  This framework is used by most of the rest of Étoilé and
provides a number of core functions, such as UUID and XML handling.</p>

<p><em>EtoileUI</em> is also available as an early preview release and should not be
considered stable.  EtoileUI is a high-level, object-oriented, user interface
toolkit that provides a uniform tree representation for graphical objects on
top of the AppKit.  All User Interface concerns such as layouts, event handlers,
styles, model objects etc. will be implemented as pluggable aspects.  It
also shares the same interfaces as other CoreObject systems.  The combination of
these three key features makes possible to inspect and reshape both User
Interface and model objects at runtime through direct manipulation.  It comes
with a library of layouts where each one encapsulates a custom and pluggable
visual presentation.</p>

<p>Other frameworks, such as <em>LuceneKit</em>, providing full-text indexing and
searching, and <em>OgreKit</em>, a powerful regular expression framework are also
included.  <em>UnitKit</em> is a simple and flexible unit testing framework used by 
much of Étoilé.  A new addition is <em>MediaKit</em>, a framework used to provide 
support for sound playback and recording and, in future, video.  <em>SystemConfig</em> 
has received a number of improvements since our last release, including support 
for modifying basic X11 keyboard settings and monitoring the battery level.</p>

<p>Several applications are part of this release, such as <em>Mélodie</em>, a music
jukebox using CoreObject for the music library and <em>MediaKit</em> for playback.
Étoilé applications which use <em>ScriptKit</em> are scriptable from outside using
Objective-C or Smalltalk.  This is used by the hot corners and gesture
recognition tool to run arbitrary commands in response to corner activations or
mouse gestures, and by <em>ScriptServices</em> which allows arbitrary shell or
Smalltalk scripts to be invoked on the current selection from any GNUstep or
Étoilé application.</p>

<h3>Screenshots</h3>

<table width="85%" align="center">
<tr>
<td><a href="/uploads/screenshots/etoile-0.4-starryreader.png"><img src="/uploads/screenshots/etoile-0.4-starryreader-mini.jpg" alt="Étoilé in the Dictionary" /></td>
<td><a href="/uploads/screenshots/etoile-0.4-vindaloo.png"><img src="/uploads/screenshots/etoile-0.4-vindaloo-mini.jpg" alt="About Étoilé and Vindaloo PDF reader" /></a></td>
</tr>
<tr align="center">
<td>Étoilé in the Dictionary</td>
<td>About and Vindaloo PDF reader</td>
</tr>
</table>

<h3>Availability</h3>

<p>Étoilé 0.4.0 is currently available in code source form only 
and may be downloaded at <a href="http://download.gna.org/etoile/etoile-0.4.0.tar.gz">http://download.gna.org/etoile/etoile-0.4.0.tar.gz</a> 
It may also be obtained from Subversion with the following command:</p>

<pre><code>svn co svn://svn.gna.org/svn/etoile/tags/Etoile-0.4.0
</code></pre>

<p>If you wish to use the latest stable release, then you can download
<a href="http://download.gna.org/etoile/etoile-0.4.0-svn.tar.gz">http://download.gna.org/etoile/etoile-0.4.0-svn.tar.gz</a> before running 
<code>svn up</code> to seed your source tree.</p>

<h3>More Information</h3>

<p>Visit our website: <a href="http://www.etoileos.com/">http://www.etoileos.com/</a>
and blog: <a href="http://etoileos.com/news/">http://etoileos.com/news/</a>
Or subscribe to our mailing lists: <a href="https://gna.org/mail/?group=etoile">https://gna.org/mail/?group=etoile</a>
Or join our SILC channel: <a href="silc://silc.etoileos.com/Etoile">silc://silc.etoileos.com/Etoile</a></p>
]]></content>
</entry>

<entry>
<title>Static Compiling Smalltalk</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/11/10/1921/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/11/10/1921/</id>
<updated>2008-11-10T19:21:00-08:00</updated>
<content type="html"><![CDATA[<p>One of the things I wanted to do with Smalltalk was allow static compilation.  This is possible with LLVM as the back end.  The compiler creates LLVM IR, a low-level intermediate representation form, which is then used to perform optimisations and can be compiled or interpreted.  I was using this for the JIT - the IR was created when the code was loaded but turned in to native code on-demand, when each method was used.</p>

<p>Today I committed a few changes to LanguageKit to allow the bitcode to be written to a file instead of loaded.  This was slightly more complicated than you might imagine.  I use a trick with the JIT where each Smalltalk module uses the set of functions defining small integer messages as a template.  This allows them to be inlined nicely without having to worry about cross-module optimisations.  For static compilation, this is not desirable, so the biggest change was allowing it to reference these functions externally or internally depending on how the code generator was being used.</p>

<p>Once this was done, I added a new -c option to edlc.  If you now do:</p>

<pre><code>$ edlc -c -f test.st
</code></pre>

<p>You will get a file test.bc as output.  This contains the LLVM bitcode for the Smalltalk file.  The next step is to link together all of the .bc files, including the MsgSendSmallInt.bc file which contains definitions of small integer messages:</p>

<pre><code>$llvm-link $(GNUSTEP_LOCAL_ROOT)/Library/Frameworks/LanguageKit.framework/Versions/0/Resources/MsgSendSmallInt.bc test.bc -o smalltalk.bc
</code></pre>

<p>This outputs a single file, smalltalk.bc, containing all of the bitcode from the various modules.  If you compiled more than one Smalltalk file then list all of the .bc files here.  This is completely unoptimised, so let's run some optimisations on it:</p>

<pre><code>$ opt -O3 smalltalk.bc -o smalltalk.optimised.bc
</code></pre>

<p>This runs the same set of optimisations that llvm-gcc runs at -O3.  I haven't actually done any sensible tests to see if this is sensible, but hopefully it is (if anyone can come up with a good list of optimisations before I get around to doing some sensible testing, please let me know).</p>

<p>Now we have an optimised bitcode file, we want to turn this into object code.  This is a two-step process:</p>

<pre><code>$ llc smalltalk.optimised.bc
$ gcc -c smalltalk.optimised.s
</code></pre>

<p>The first step produces assembly code, and the second step assembles it (you can use as for the second step, but I was lazy and just threw it at the GCC compiler driver).  You now have a file called smallltalk.optimised.o, an object code file that you can link in to your executable just as you would an object code file compiled from Objective-C.</p>

<p>This sounds a bit complicated, and it is.  It's actually more steps than the first C compiler I ever used (where preprocess, compile, assemble, and link were all separate steps) required.  Fortunately, Nicola Pero is working on adding support for it to GNUstep Make, so soon it should be just a matter of putting SMALLTALK_FILES=... in your GNUmakefile.</p>

<p>The bad news is that this is too big a change to be properly reviewed in time for 0.4.0, so unless you are running trunk you will have to wait for a bit to see it.  0.4.1 should be out around the new year, so you don't have too long to wait...</p>
]]></content>
</entry>

<entry>
<title>Packaging Étoilé</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/10/27/1211/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/10/27/1211/</id>
<updated>2008-10-27T12:11:00-07:00</updated>
<content type="html"><![CDATA[<p>Nicolas just sent me a link to <a href="http://brainstorm.ubuntu.com/idea/13050">this Ubuntu brainstorm idea</a>.  Someone is proposing full Étoilé packages for inclusion in Ubuntu.</p>

<p>Currently, Étoilé is a bit of a moving target.  It's been a long time since our last release.  FreeBSD has ports for this release, but so much has changed in subversion since then that these are no longer a good introduction to Étoilé.</p>

<p>Hopefully this will change next month.  We are planning on releasing Étoilé 0.4.0 on the 31st of October.  If you want to get an idea of what it will contain then take a look at the current stable branch - this will be tagged 0.4.0 in under a week.</p>

<p>After this, we will be moving to a time-based point release schedule, with Étoilé 0.4.1 being released at the end of the year, 0.4.2 at the end of February, and so on.</p>

<p>Hopefully this will make life easier for packagers.  We aim to only require released versions of dependencies for release versions of Étoilé (0.4.0 will require LLVM 2.4, for example, which is due for release on October 30).</p>

<p>If you are interested in providing packages for your platform, then please get in touch and let us know what we can do to help.</p>
]]></content>
</entry>

<entry>
<title>The road to CoreObject Part 3: Mixing Temporal Object Store and Name Service</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/10/19/0053/"/>
<author><name>Quentin Mathé</name></author>
<id>http://etoileos.com/news/archive/2008/10/19/0053/</id>
<updated>2008-10-19T00:53:00-07:00</updated>
<content type="html"><![CDATA[<p><a href="http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Frameworks/CoreObject/">CoreObject</a> is a central piece of Étoilé, often discussed but rarely seen :-) The good news is that it's currently shaping up pretty well. But before entering in the details and illustrating CoreObject persistency with an example in a next post, I'd like to give a brief overview of it.</p>

<p>The overall architecture has evolved substantially over the past two years. The implementation started with the writing of <a href="/news/archive/2007/07/19/1755/">EtoileSerialize</a> by David, and <a href="http://svn.gna.org/viewcvs/etoile/trunk/Etoile/Frameworks/CollectionKit/">CollectionKit</a> then <a href="http://svn.gna.org/viewcvs/etoile/branches/OrganizeKit/">OrganizeKit</a> by Yen-Ju. These last two frameworks were built to provide a semi-structured object model inspired by AddressBook framework, that can be used to write applications managing collection of objects (music, photo, contacts etc.). This summer, Eric wrote a music manager named <a href="/news/archive/2008/05/26/1929/">Mélodie</a> based on this reusable object model. As such, Mélodie is the first Étoilé application that truly uses CoreObject.</p>

<p>Until recently, CoreObject mostly existed as a fork of OrganizeKit in Étoilé repository. The persistency model was to store the whole core object graph into a single property list, or multiple property lists but without the possibility to reference core objects across these property lists. This was a very important limitation that prevented concurrency control and versioning of objects through EtoileSerialize. Moreover each time a process wanted to access a core object, the entire core object graph had to be deserialized. Over the past two months, I have revisited CoreObject, in order it fully leverages EtoileSerialize for persistency, supports the loading of the core objects in memory on demand, interacts with a metadata server to track stored objects, and provides a better control over the history of core objects.</p>

<p>The updated version of the semi-structured object model also brings a very transparent approach to persistency, you don't need to call EtoileSerialize explicitly or even use a proxy to wrap your objects.</p>

<p>Now let's look at the various building blocks of the framework. The basic idea behind CoreObject is to provide a reusable model for organizing objects and handling their persistency. The low-level persistency logic is implemented by EtoileSerialize, CoreObject extends it with:</p>

<ul>
<li>a protocol to organize core objects into groups (COObject and COGroup protocols)</li>
<li>a main backend that provides a semi-structured object model (COObject and COGroup classes)</li>
<li>additional backends to attach external object graphs (for example mounting a filesystem or exporting an application UI into the core object graph)</li>
<li>COProxy for integrating persistent model objects not derived from the COObject class</li>
<li>a metadata server to track stored objects and index both metadatas and content of core objects (COMetadataServer class)</li>
<li>a per process object factory and cache that is used to handle the faulting and uniquing of core objects (COObjectServer class)</li>
</ul>

<p>So CoreObject mostly adds a name service on top of a EtoileSerialize and persists the name service structure and the objects bound to it in the same uniform representation. This representation is the core object graph, where each object and each group is stored as a persistent root by EtoileSerialize. Each persistent root is identified by an UUID/URL pair. Persistent roots are currently stored as object bundles on the filesystem. An object bundle is a directory the contains the history of the object in term of snapshots and deltas. Deltas are serialized invocations that represent logical changes. EtoileSerialize defines a protocol for the storage model, so new ways to store the objects could be defined. For example, changing the layout of object bundles, storing all the objects in a single flat file, over the network or other kind of data stores such as ZFS DMU (the low-level ZFS transactional store on which the filesystem is built).</p>

<p>The UUID/URL pairs are stored in a metadata server, which defines all the objects that belong to a core object graph. In future, the core object graph should thus be able to span multiple computers or data stores backed by a single metadata server. The metadata server is currently based on a PostgreSQL database.</p>

<p>For this first approach, multiple users cannot share a single core object graph and the access rights are simply defined by the permissions set on the object bundles at the filesystem level.</p>

<p>Out of the box, EtoileSerialize provides the basic infrastructure for per object history. This allows to support undo/redo per object. However objects such as photos, music, contacts are usually organized into libraries and it is expected undo/redo will operate on the last modification for the currently opened library, when you use a photo manager or a music manager. If that wasn't the case, undo/redo would only work if one or several objects are selected as targets for undo. This also means the user would have to remember the last modified object if he changed the selection after editing this object.</p>

<p>To solve this problem, CoreObject introduces the notion of object contexts. An object context is a pool where you insert related core objects. The object context records an history that is the interleaved histories of all the objects that belong to it. By this mean, it becomes possible to navigate and restore the history per object and per context.</p>

<p>Most of the elements of the architecture outlined at the beginning have already been implemented, if we put aside the indexing service. Various key pieces remain to be written though: concurrency control, update feed to push object changes to client applications, in-store deletion model and history cleaning.</p>

<p>In a more broad perspective, integration with the branching support of EtoileSerialize, exporting core objects to other formats and collaborative editing, will also have to be fully worked out. Finally the versioning of structured documents will require additional support to be truly convenient and integrate perfectly with EtoileUI.</p>
]]></content>
</entry>

<entry>
<title>So, you want to invent a language?</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/10/12/1600/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/10/12/1600/</id>
<updated>2008-10-12T16:00:00-07:00</updated>
<content type="html"><![CDATA[<p>I posted a little while ago about the Smalltalk compiler in Étoilé svn.  Since then, Truls Becken has rewritten my parser (which was quite bad, and is now quite good) and tidied up the code a little.  I've also refactored it into two frameworks, LangaugeKit and SmalltalkKit.  LanguageKit contains all of the abstract syntax tree and code generation stuff, while SmalltalkKit contains all of the Smalltalk-specific parts.</p>

<p>The total line count for the Smalltalk-specific part is a shade over 500 lines of code.  This means that writing a new front-end for something Smalltalk-like is very easy (I plan on adding some things to LanguageKit to make slightly less Smalltalk-like languages similarly easy).</p>

<p>If you want to play, then the first thing you need is a subclass of LKCompiler, which implements two methods: <code>+fileExtension</code> and <code>+parser</code>.  The first returns the extension used by scripts in your language (<code>@"st"</code> for Smalltalk), while the second returns the <code>Class</code> implementing your parser.</p>

<p>Then you need to implement the parser.  This just needs to implement one method, <code>parseString:</code> which takes a string as an argument and returns an <code>AST</code>.  For Smalltalk, I have a hand-written tokeniser and use LEMON (from the SQLite project) for the parser.  The tokeniser simply turns the string into a stream of tokens and then passes them one at a time to the parser (it might be simpler if I wrote it using something like Lex, but since it's only 200 lines of code now I can't really be bothered).  The parser is generated from a BNF-like description of the grammar, with instructions in Objective-C on how to generate the AST from this.</p>

<p>Now that Truls has rewritten it, the Smalltalk grammar is a fairly good example of a LEMON grammar.  If you want to write a new language, a good first step is tweaking Smalltalk a bit.  If you find that you want a semantic construct that isn't supported by the AST, drop in to SILC and talk to me - adding static flow control (<code>if</code> statements and <code>while</code> loops) is high on my list of priorities, as is support for primitive (non-object) types that aren't auto-boxed.</p>
]]></content>
</entry>

<entry>
<title>Scripting and Gestures</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/08/13/1336/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/08/13/1336/</id>
<updated>2008-08-13T13:36:00-07:00</updated>
<content type="html"><![CDATA[<p>Two of the things that have been on my TODO list for about two (maybe three) years are cross-app scripting and mouse gestures.  StepTalk had some preliminary support for cross-app scripting, but I don't think it made it into a release.  I never really liked its approach, since it seemed horrible over-engineered (for reference, the Smalltalk interpreter in StepTalk is about twice as much code as the Pragmatic Smalltalk compiler and support library).</p>

<p>Yesterday, I committed the first version of ScriptKit.  This is a very lightweight cross-app scripting framework built on top of Distributed Objects.  It simply exports a dictionary containing a set of named objects for scripting.  By default, <code>NSApp</code> (the application object) is exported.  If you don't want to give unrestricted access to remote scripts you can export your own object with the 'Application' key and filter out some messages.  You can also export other objects with their own names.  In future we will define a set of standard-but-optional ones that Étoilé services should export (e.g. the current document, some CoreObject related things and so on).</p>

<p>For the paranoid, I plan on adding a 'Paranoid Mode' which uses a pre-shared key to prevent unauthorised scripts from controlling the app.</p>

<p>The nice side-effect of using DO as the core is that it is also trivial to send scripting events from Objective-C.  Anyone who has tried doing this with Cocoa has probably given up and just generated a string containing AppleScript code and passed this to the scripting engine.  Since we are using a Smalltalk which is toll-free bridged with Objective-C, it makes sense to just expose scripting objects as Objective-C / Smalltalk objects (well, object proxies) and use them directly, without a confusing abstraction layer.</p>

<p>The other thing I added yesterday was a gesture recognition engine.  Today I remembered that 'x is a-cross' and fixed it so that it actually works.  This is embedded in Corner.app, which currently handles hot corners for Étoilé (allowing scripts to be run when the mouse enters and leaves a screen corner).  If you hold down control and shift, it enters a gesture quasi-mode.  It then tracks mouse movements.  Each movement is treated as an approximation of a movement in one of 8 directions, numbered 1 to 8 clockwise from the top (i.e. 1 is up, 5 is down, and so on).  Complete gestures are therefore turned into strings ('gesture words'), so an 'h' shape would be '5135' (down-up-right-down).  Distance moved in each direction is ignored because when doing mouse gestures I am rubbish at getting distances right, while with this system I can consistently do the gesture I was trying to.</p>

<p>Corner maintains a dictionary mapping gesture words to objects.  These objects can be written in Smalltalk or Objective-C.  They have to implement a <code>-gesturePerformed</code> method, and this will be called whenever the gesture they are associated with is drawn.  Now that cross-application scripting is working, this can be used to control any application, for example locking the screen and setting an away message in the Jabber client.</p>

<p>Currently, there is one default gesture - drawing an h hides the active application (if the active application supports scripting, otherwise it does nothing).  Others will probably be added in time for 0.4.</p>
]]></content>
</entry>

<entry>
<title>OgreKit Tutorial #3</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/08/06/1447/"/>
<author><name>Yen-Ju Chen</name></author>
<id>http://etoileos.com/news/archive/2008/08/06/1447/</id>
<updated>2008-08-06T14:47:00-07:00</updated>
<content type="html"><![CDATA[<p>OgreKit also comes with a find panel. It can work on NSTextView, NSTableView and NSOutlineView. The later two are not ported yet, but the architecture is extendable to other graphic interface. An example of using OgreKit find panel is under '/Etoile/Developer/Examples/OgreKitExample'. First, we need to connect the find panel to the text view:</p>

<pre><code>- (void) awakeFromNib
{
    textView = [scrollView documentView];
    textFinder = [OgreTextFinder sharedTextFinder];
    [textView setRichText: NO]; /* Use Plain text adaptor */
    [textFinder setTargetToFindIn: textView];
}
</code></pre>

<p>OgreKit find panel can search both plain text and attributed text. Here, text view is set to use plain text and the right adaptor will be used by OgreKit find panel automatically. To connect find panel and text view, use -setTargetToFindIn: from OgreTextFinder. That's all.</p>

<p>To bring up the find panel, add this action into menu:</p>

<pre><code>- (void) findPanelAction: (id)sender
{
    [textFinder showFindPanel: sender]; 
}
</code></pre>

<p>Now, you have a find panel which supports regular expression by default. Here is a screenshot:</p>

<div><img src="/news/posts/2008/08/06/1447.png" /></div>
]]></content>
</entry>

<entry>
<title>OgreKit Tutorial #2</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/08/01/0947/"/>
<author><name>Yen-Ju Chen</name></author>
<id>http://etoileos.com/news/archive/2008/08/01/0947/</id>
<updated>2008-08-01T09:47:00-07:00</updated>
<content type="html"><![CDATA[<p>Here are some examples of using OgreKit:</p>

<p>In NSMutableString, -chomp remove all newlines ('\n') anywhere in a mutable string.</p>

<pre><code>NSObject subclass: SmalltalkTool
[
    run
    [
        | target |
        target := NSMutableString stringWithString: 'alphabetagammadelta\n\n\n'.
        target length log.
        target chomp.
        target length log.
    ]
]
</code></pre>

<p>In OGRegularExpression, -replaceAllMatchesInString:withString: replaces all matched strings.</p>

<pre><code>NSObject subclass: SmalltalkTool
[
    run
    [
        | regex target result |
        regex := OGRegularExpression regularExpressionWithString:'a[^a]*a'.
        target := 'alphabetagammadelta'.
        result := regex replaceAllMatchesInString:target withString: '###'.
        target log.
        result log.
    ]
]
</code></pre>

<p>You can even swap the matched substring like this:</p>

<pre><code>NSObject subclass: SmalltalkTool
[
    run
    [
        | regex target result |
        regex := OGRegularExpression regularExpressionWithString:'(a)([^a]*a)'.
        target := 'alphabetagammadelta'.
        result := regex replaceAllMatchesInString:target withString: '(\2)(\1)'.
        target log.
        result log.
    ]
]
</code></pre>

<p>OgreKit also supports various regular expression syntax:</p>

<pre><code>OgrePOSIXBasicSyntax    POSIX Basic RE
OgrePOSIXExtendedSyntax POSIX Extended RE
OgreEmacsSyntax     Emacs
OgreGrepSyntax      grep
OgreGNURegexSyntax  GNU regex
OgreJavaSyntax      Java (Sun java.util.regex)
OgrePerlSyntax      Perl
OgreRubySyntax      Ruby (default)
OgreSimpleMatchingSyntax    Simple Matching
</code></pre>

<p>Now, let's go back to Objective-C. Instead of using regular expression to replace string, you can have a delegate method for that. Use -replaceAllMatchesInString:delegate:replaceSelector:contextInfo: to specify the delegate and method, then write your own replace method. Here, the replace method is -count:contextInfo:, which will return the number of matched letter.</p>

<pre><code>(void) testReplaceDelegate
{
    OGRegularExpression *regex = [OGRegularExpression regularExpressionWithString: @"a[^a]*a"];
    NSString *target = @"alphabetagammadelta";
    NSString *result = [regex replaceAllMatchesInString: target
                                               delegate: self
                                        replaceSelector: @selector(count:contextInfo:)
                                            contextInfo: nil];
    NSLog(@"Target %@", target);
    NSLog(@"Result %@", result);
}

- (NSString *) count: (OGRegularExpressionMatch *) match
         contextInfo: (id) contextInfo
{
    return [NSString stringWithFormat: @"(%d)", [[match matchedString] length]];
}
</code></pre>

<p>The result will be:</p>

<pre><code>Target alphabetagammadelta
Result (5)bet(3)mm(6)
</code></pre>
]]></content>
</entry>

<entry>
<title>OgreKit Tutorial #1</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/07/31/1343/"/>
<author><name>Yen-Ju Chen</name></author>
<id>http://etoileos.com/news/archive/2008/07/31/1343/</id>
<updated>2008-07-31T13:43:00-07:00</updated>
<content type="html"><![CDATA[<p>David asked me to write an example of using OgreKit framework. I figured it might be interesting to do that in combination with SmallTalk. This post shows you how to set up everything on Ubuntu 8.04. Of course, you need to have <a href="http://gnustep.blogspot.com/2008/06/gnustep-on-ubuntu-804.html">GNUstep installed</a> first.</p>

<p>Dependencies for LLVM are 'lemon', 'flex' and 'bison'. They can be installed from Ubuntu packages. It is necessary to use LLVM trunk for Smalltalk. Based on <a href="http://www.llvm.org/docs/GettingStarted.html">LLVM User Guide</a>, you can download LLVM trunk with</p>

<pre><code>svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm
</code></pre>

<p>After configuration with './configure', compile it with 'make ENABLE_OPTIMIZED=1' for release build (10x faster than debug build) and install it with 'make install'. It is not necessary to install the frontend for this purpose.</p>

<p>Once LLVM is ready, compile and install 'EtoileFoundation' and 'Smalltalk'. To avoid debug information from Smalltalk, use 'make debug=no' for compilation. Use 'st -f test.sh' under Smalltalk directory to testing Smalltalk. There are also a few examples under 'examples' directory.</p>

<p>For OgreKit, you need to have <a href="http://www.geocities.jp/kosako3/oniguruma/">oniguruma</a> from Ubuntu packages. Then compile and install OgreKit as usual.</p>

<p>Finally, this is a small script to check everything.</p>

<pre><code>NSObject subclass: SmalltalkTool
[
    run
    [
        | regex matches |
        regex := OGRegularExpression regularExpressionWithString:'a[^a]*a'.
        matches := regex allMatchesInString:'alphabetagammadelta'.
        matches foreach:[ :x | x matchedString log.].
    ]
]
</code></pre>

<p>Save it in a text file called 'ogre.st', for example, and run it with 'st -f ogre.st -l OgreKit'. Parameter 'f' refers to the file name and 'l' refers to the OgreKit framework. The regular expression patterns is 'a[^a]*a', which means a string that the first and the last letter is 'a', but none of the letters in-between is 'a'. Using this pattern to match a string 'alphabetagammadelta' will give 3 substrings: 'alpha', 'aga', 'adelta'. Results are stored in an array of OGRegularExpressionMatch. Use '-matchedString' to retrive the matched substring.</p>
]]></content>
</entry>

<entry>
<title>Fun With Threads</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/07/29/0231/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/07/29/0231/</id>
<updated>2008-07-29T02:31:00-07:00</updated>
<content type="html"><![CDATA[<p>This weekend I started working on a replacement for MultimediaKit.  This has been on my TODO list for a while, since the current one is GPL-tainted.  I started working with libavcodec and libavformat directly, since these are LGPLd.</p>

<p>In order to get consistent latency, ideally I wanted the decoder running in its own thread.  Since we have a threading library in svn, I thought I'd try using it (okay, I wrote it, but I've not actually had the need of a threading framework since then).  The first thing I needed to do was create the player object and put it in its own thread:</p>

<pre><code>MusicPlayer *player = [[MusicPlayer alloc] initWithDefaultDevice];
// Move the player into a new thread.
player = [player inNewThread];
</code></pre>

<p>Actually, that's all I needed to do.  After putting some files in the player's queue, I could periodically query its state, like this:</p>

<pre><code>// Periodically wake up and see where we are.
while (1)
{
    id pool = [NSAutoreleasePool new];
    sleep(2);
    NSLog(@"Playing %@ at %lld/%lld", [player currentFile], 
        [player currentPosition] / 1000, [player duration] / 1000);
    [pool release];
}
</code></pre>

<p>Note the complete lack of any locking or thread operations here.  The <code>player</code> object, after the call to <code>-inNewThread</code> is really a proxy which maintains a lockless ring buffer storing messages between the player and my main thread.  When I send it a <code>currentFile</code> message, it adds it to the queue and returns a proxy.  If I try to use the proxy (here, <code>NSLog</code> will do so by sending it a <code>-description</code> message) then my calling thread will block.  The other two messages return primitives, so they block immediately.</p>

<p>When I am not sending the player messages, the run loop managed by EtoileThread sends it a <code>-shouldIdle</code> message whenever the message queue is empty, and if it is then it sends it an <code>-idle</code> message.  The <code>-idle</code> method reads the next frame from the audio file, decodes it, and passes it to the output device.  All of these are synchronous, blocking, calls (although the output device does some buffering) and so it's very simple code.  Neither thread needs to spend much time waiting on a mutex - the structure used to send messages between threads is a hybrid ring buffer, which runs in lockless mode unless it has spent a little bit of time spinning (at which point it uses a mutex).</p>

<p>This means that, while playing, the cost of checking for new messages is very cheap (one comparison operation, in fact).  While paused (and not receiving messages), the object will automatically switch to locked mode and wait for a condition variable to wake it up, so you aren't wasting CPU.</p>

<p>The best thing is that all of this is hidden away in EtoileThread (in EtoileFoundation), so any of your objects can use the same mechanism with almost no code.  Just adopt the <code>Idle</code> protocol if you want to do something when your object isn't receiving messages from another thread, and send it an inNewThread message just after creation.</p>
]]></content>
</entry>

<entry>
<title>Pragmatic Smalltalk 0.5</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/07/12/1410/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/07/12/1410/</id>
<updated>2008-07-12T14:10:00-07:00</updated>
<content type="html"><![CDATA[<p>I've been calling Étoilé 'a pragmatic Smalltalk' for a long time (although Nicolas, I believe, was the one to coin the expression).  Smalltalk is a really great language, but it has two disadvantage:</p>

<p>1) It tends to be bytecode-interpreted, which is not very fast.
2) Implementations tend to be all-or-nothing.</p>

<p>The first is less of a problem now that CPUs are so fast they spend 90% of their time idle in a typical desktop workload.  The second is much more of a problem.  Smalltalk-80 includes a complete GUI and common implementations, such as <a href="http://www.squeak.org/">Squeak</a> adopt this model.  This means that Squeak applications and 'native' applications are entirely separate.  If there is one thing that Squeak doesn't have that you need, then using Squeak is not easy.</p>

<p>This week, I committed the first version of the Smalltalk compiler I have been working on to Étoilé svn.  Unlike other Smalltalk implementations, this is designed from the ground up for interoperability.  Smalltalk objects are compiled (to native code) as Objective-C objects.  This means that they can subclass Objective-C objects, and can even implement categories on Objective-C objects.  There is no C function interface - if you want to call C functions then call them from Objective-C.</p>

<p>The compiler is in three components.  SmalltalkKit contains everything required to take a string containing Smalltalk code and compile it to a set of Objective-C objects.</p>

<p>The Support library contains things needed by Smalltalk but not Objective-C.  The most important class here is the <code>BlockClosure</code> class, which implements a Smalltalk block as an Objective-C object with a function pointer as an instance variable and pointers to bound variables and space for promoting other variables (eliminating the need for garbage collected stack frames).  There are also a few categories, such as <code>map:</code> and related methods on <code>NSArray</code> which take blocks as arguments.  Note that these are implemented in Objective-C even though they are used by Smalltalk - they could, in most cases, easily be implemented in Smalltalk instead.</p>

<p>The final part is a tool which compiles a Smalltalk file, instantiates a specified class, and send the instance a <code>run</code> message.  This is very small and shows how the compiler can be used, and will serve as the framework for writing complete applications in Smalltalk.</p>

<p>The parsing is done in Objective-C, using the Lemon parser generator from SQLite.  The abstract syntax tree (AST) is constructed out of Objective-C objects, which means it's exposed to Smalltalk.  As a result, Smalltalk programs can generate code easily by constructing the AST and invoking its <code>compileWith:</code> method, or by instantiating a parser and giving it a string.</p>

<p>Currently, the compiler only works in-process.  It uses runtime introspection when constructing the AST.  Code generation, however, is done via <a href="http://llvm.org">LLVM</a>, and involves generating an LLVM intermediate representation (IR) version of the AST, running LLVM optimisation passes on this, and then compiling it to native code.  With minor modifications, it is possible to emit the LLVM IR as bitcode and then run extra optimisations on it or compile and link it as a native library.  Whether this is interesting depends on how long it takes to run the compiler.  For the simple test I've done so far, program startup has taken much longer than parsing and code generation (and I'm using a debug build of LLVM, which is about 10% the speed of a release build).  For larger programs, it might be worth statically-compiling.  If parsing is a major overhead, it might be worth caching the bitcode for each Smalltalk input class.</p>

<p>So far, it is a fairly naive implementation.  Lots more optimisations are possible (some are very easy) than are currently done.  My aim, however, is to move as many as possible into LLVM passes, so that they can be used when compiling other dynamic languages.  The code representing the Objective-C object model is taken from code I wrote for clang, the new C language family front end for LLVM, and so is also used for compiling Objective-C with LLVM.</p>
]]></content>
</entry>

<entry>
<title>Building a Better Garbage Collector</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/07/06/1636/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/07/06/1636/</id>
<updated>2008-07-06T16:36:00-07:00</updated>
<content type="html"><![CDATA[<blockquote>
  <p>One day a student came to Moon and said, "I understand how to make a better garbage collector. We must keep a reference count of the pointers to each of the cans." Moon patiently told the student the following story:</p>
  
  <p>"One day a student came to Moon and said, "I understand how to make a better garbage collector...</p>
</blockquote>

<p>I am not a fan of many of the things Apple has done to Objective-C recently. The one thing I liked the idea of in principle was garbage collection. Unfortunately, they seem to have done this very badly, so I set about seeing if there was a better way.  First, some background:</p>

<p>There are, generally speaking, two kind of garbage collection: reference counting and tracing.  With reference counting, every assignment increments the reference count of the new value and decrements the reference count of the old value.  When an object's reference count hits zero, it is freed.  This is what is traditionally done with OpenStep, via the <code>-retain</code> and <code>-release</code> methods.</p>

<p>The other alternative is tracing.  This requires every object to be known to the garbage collector.  Globals are identified as 'roots' and periodically the collector attempts to navigate from the roots to every reachable object. Those that can not be reached are freed.</p>

<p>In 2004, some very bright guys at IBM's T.J. Watson Research Center (a nice place to visit, by the way - it's on top of a hill, with huge windows and overlooks some gorgeous scenery) came up with a <a href="http://portal.acm.org/citation.cfm?doid=1028976.1028982">Unified Theory of Garbage collection</a> in which they propose that these are really equivalent.  A tracing garbage collector needs to set a flag indicating that an object has been reached, and this can be seen as a special case of a reference count (one capped at one).  Reference counting garbage collectors need some extra mechanism for detecting loops, and this is equivalent to the tracing operation.</p>

<p>When Apple added tracing GC to Cocoa, they threw away the reference counting mechanism.  This was a shame, since all that is needed to turn reference counting into full GC is the addition of a cycle detecting algorithm.  If <code>a</code> has a reference to <code>b</code> and <code>b</code> has a reference to <code>a</code> then, with pure reference counting, both <code>a</code> and <code>b</code> will leak.  The rôle of the cycle detector is to run periodically and make sure this does not happen.</p>

<p>Fortunately, the two of the same guys who came up with the unified theory had, a few years earlier, published <a href="http://www.research.ibm.com/people/d/dfb/papers/Bacon01Concurrent.pdf">another paper</a> in which they describe a mechanism for adding an efficient (i.e. fast) cycle detector to a reference counting system.</p>

<p>I have implemented this for GNUstep, and it shows promise.  I've made a few modifications to <code>NSObject</code> - retain counts are now stored in a 16-bit value (if you have more than 65535 references to a single object, you probably have a bug) and the other 16 bits are now used to store flags, including a colour. The colour is set by the cycle detection algorithm, which is invoked periodically when a buffer of objects which have been released but not freed becomes full.</p>

<p>One minor problem with this is that objects can now exist safely in loops and <code>-retain</code> can be called on an object which is currently executing <code>-dealloc</code>. This can lead to an infinite loop, and some careful juggling is required to ensure that no objects deallocate themselves while freeing loops.</p>

<p>The code works, although it has a few (easily fixable) limitations.  I created a small graph of five <code>Pair</code> objects.  Each one has a reference to itself and to the next one in the ring.  The code correctly determines that this contains a loop, and destroys all five objects when the autorelease pool is destroyed.</p>

<p>The only major limitation is that I've only written code for atomically accessing the colours on x86.  This can be fixed trivially by simply writing these functions.  A smaller issue is that a number of GNUstep classes indulge in premature optimisation by calling <code>NSDeallocateObject()</code> in their <code>-dealloc</code> method, rather than calling <code>[super dealloc]</code>.</p>

<p>I currently use a modified version of the algorithm in the paper which uses an <code>NSHashTable</code> to store pointers to objects that might contain loops.  Since there's space in the flags field for a 'buffered' flag, I can easily extend it to use this, and replace the hash table with a static array.  This is better for two reasons: it should be faster, and it means that we can use thread-local storage without having to worry about explicit destructors (which are currently called by listening for a thread terminating notification, which is slightly fragile and will potentially fail to catch things released when a thread is dying).</p>

<p>Since some code already handles loops via unretained references, the current code has problems.  To avoid this, I introduced an extra colour (transparent), and any objects with this colour are assumed to always be acyclic.  This allows automatic loop detection to be turned on on a per-object, or per-class basis.  In future, this can be used in reverse: to turn off loop detection for intrinsically acyclic data structures (e.g. trees).</p>

<p>My main motivation for this is for the Smalltalk compiler I am currently working on.  Since Smalltalk expects garbage collection, and Objective-C does not provide it, this presents a small problem.  A tracing collector can be used, however this is very tricky when integrating with a C-like language, since it means that everything which may potentially contain pointers has to be checked, including integers and untyped buffers.</p>
]]></content>
</entry>

<entry>
<title>On the way to EtoileUI, Part 1: Back to the Hackathon</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/06/06/2325/"/>
<author><name>Quentin Mathé</name></author>
<id>http://etoileos.com/news/archive/2008/06/06/2325/</id>
<updated>2008-06-06T23:25:00-07:00</updated>
<content type="html"><![CDATA[<p>For the Swansea hackathon, I gave a quick overview of EtoileUI. When I came back, I intended to upload it and wrote a post on the subject but the time went by faster than I expected :-)</p>

<p>During April and May, the framework has steadily improved to the point of being now usable on both GNUstep and Cocoa, but it is still quite experimental and many things remain to be worked out. In the early days of April, the stability of EtoileUI on GNUstep wasn't really satisfying too, since I initially wrote a large part of it on Mac OS X before backporting it this winter.</p>

<p>Before trying to explain what is EtoileUI in upcoming posts, here is the link to  <a href="/uploads/presentations/etoileui-quick-overview-swansea.pdf">the presentation</a> (PDF) I did.</p>

<p>As you probably know from the previous post, the integration of CoreObject and EtoileUI is moving forward, especially now that Eric has started to use both in a real application named EtoileTunes. This recent project has also motivated me to be quicker at squashing annoying bugs in these frameworks. On my side, a generic object manager based on the example of the last slide is coming along nicely. For now, it is mostly a CoreObject-based file manager which supports several views (icon, list, column, etc.), although it can be used to browse and mutate any object graphs that comply to a simple object collection protocol (declared in EtoileFoundation).</p>
]]></content>
</entry>

<entry>
<title>EtoileTunes</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/05/26/1929/"/>
<author><name>Eric Wasylishen</name></author>
<id>http://etoileos.com/news/archive/2008/05/26/1929/</id>
<updated>2008-05-26T19:29:00-07:00</updated>
<content type="html"><![CDATA[<p>For the past few weeks I've been working on EtoileTunes, a music player for Etoile. 
My goals were to try improve my Objective-C/GNUStep knowledge, to try out programming with EtoileUI and CoreObject, to work on a replacement for MultimediaKit, and to hopefully end up with a good enough music player to use regularly.</p>

<p>It's still in fairly early stages, but I have something that uses TagLib to read music file metadata, then constructs a CoreObject with that metadata. It then puts these into a COGroup subclass which represents a playlist, and displays this group with EtoileUI. The eventual goal, as I understand it, is for EtoileTunes not to be a separate application, but just a pre-defined layout which the normal object-manager UI in Etoile can take on. Jesse, Quentin, and I discussed some ideas for what would make a good music manager UI, so hopefully I can build some working mockups with EtoileTunes.</p>

<p>On the MultimediaKit replacement side, I have an incomplete, but working, Objective-C wrapper around Xine-lib which provides an API similar to MultimediaKit's (only for music, not video playback so far.) I'm also working on a GStreamer backend. A future task might be to write a MultimediaKit framework from "scratch" - an Objective-C framework that would fit between Etoile apps/services and the operating system's/sound server's audio API. It could use the ffmpeg project's libavcodec/libavformat libraries to do all of the hard work of decoding media formats. The advantages of this would be having something that exactly fits Etoile's needs, and fits in to the system perfectly (for example, the same code for decoding music could be used for transcoding between different formats, and be integrated into a system Etoile might provide for converting file formats), and being able to ensure details like gapless playback work perfectly. This might be a lot of work though - especially if it has to handle video playback and recording, and multiple OS backends, so it may be best to stick with GStreamer/Xine for now.</p>

<p>Here's a screenshot of EtoileTunes:</p>

<div><a href="http://etoileos.com/news/posts/2008/05/26/EtoileTunes.png"><img src="http://etoileos.com/news/posts/2008/05/26/EtoileTunesSmall.png" /></a></div>

<p>If you would like to try it, the code is in /branches/ericwa/EtoileTunes. It's still very work-in-progress, though.</p>

<p>Lastly, any suggestions for a better name? :)</p>
]]></content>
</entry>

<entry>
<title>Compiler Fun</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/05/12/1719/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/05/12/1719/</id>
<updated>2008-05-12T17:19:00-07:00</updated>
<content type="html"><![CDATA[<p>Anyone following the Étoilé svn logs recently will notice that I haven't been committing much for a few weeks.  The reason for this is that I've been taking a short break to do some compiler hacking.</p>

<p>Objective-C support was first added to GCC by some guys at NeXT.  They didn't want to release their code, but were eventually forced to by the FSF.  They did not release the code for their runtime library, and so this code was completely useless to anyone else.  RMS wrote a drop-in replacement for this library, which became the GNU Objective-C runtime.  Gradually the GNU and NeXT runtimes diverged and the Objective-C support code in GCC became littered with #ifdefs.</p>

<p>After Apple bought NeXT, they continued developing their version of GCC in a branch.  This branch was slightly cleaner, since it never had support for the GNU runtime, but no use to anyone on platforms other than Darwin for the same reason.  This code is no fun at all to work with - Objective-C structures are lowered to the corresponding C structures, so there is no clean Objective-C AST to work with and runtime-specific code is interleaved with the abstract representations.  When Apple add a new language feature, they add it to their branch, and if anyone else wants to use it then they have to merge the changes into the main trunk.  Unfortunately, no one is doing this and Objective-C support in GCC is in a rather depressing state (bugs in Objective-C are not seen as show stoppers for a release, as we saw in the early 4.x series).</p>

<p>Recently, GCC switched to GPLv3.  Apple corporate policy is that they will not touch GPLv3 code, and so the Apple branch is now a fork of GCC 4.2.  Features added to GNU GCC will not find their way into Apple GCC and vice versa, unless explicitly licensed in a compatible way by their contributor.</p>

<p>Apple have also started looking at a new compiler, known as <a href="http://llvm.org/">LLVM</a>.  This is a modular infrastructure for building compilers.  It currently has an Objective-C/C/C++ front end based on Apple's GCC.  This combination of an LLVM back end and a GCC front-end is typically known as llvm-gcc.  It is found in the iPhone SDK and is likely to be found in the OS X dev tools soon.  GCC isn't really designed to be split apart like this, however, and so the Apple guys have been working on a <a href="http://clang.llvm.org">new one</a>.</p>

<p>Unlike GCC, clang has very clean layering.  This is intentional, since Apple also want to use it in XCode for syntax highlighting and refactoring tools.  This means that every single Objective-C language construct gets corresponding AST nodes which are then passed to another part of the program which emits LLVM intermediate representation (IR) code - single static assignment assembly language - which is then turned into native code for the desired platform.</p>

<p>When I first looked at clang, most of the parsing code for Objective-C was done, but none of the code generation part.  This meant that I was free to add any interfaces I wanted.  Clang now has an abstract class encapsulating all of the runtime-specific behaviour and hooks in the generic code that call this.  I have also written a complete implementation of this for the GNU runtime and an almost-complete one for the Étoilé runtime.  As a result of this, clang can now compile about 90% of the files in GNUstep-base without issue.  The remaining ones are failing due to a couple of outstanding bugs with implicit casts (the LLVM type system is a lot more strict than the Objective-C one and so casts which are implicit in Objective-C need to become explicit in the IR) and a few C features.  GNUstep uses variable length arrays in a few places, for example, and I have only added partial support for these.</p>

<p>My changes to Clang are currently undergoing code review, but after this has happened and I've made the required changes they should go in.</p>

<p>Objective-C isn't the only thing that makes this interesting.  Since the object model code is all isolated in a separate class, it is possible to plug this into other compilers trivially.  Generating classes, protocols and categories, selectors and message sends that use the underlying GNU runtime (and soon the Étoilé runtime) functionality is trivial when using this class (each high-level construct is mapped to a method call).  I am currently in the process of writing a Smalltalk compiler that uses this same back end.  LLVM supports both JIT and static compilation, so we will be able to JIT-compile Smalltalk while developing, dump it to a file, and static compile it for distribution.</p>

<p>This means that Smalltalk will be a first-class citizen of the Étoilé ecosystem.  Applications will be able to be written in Smalltalk and Smalltalk classes will be able to inherit from Objective-C classes.  There is no bridging - Smalltalk methods will be compiled to native code and attached to the same structures as Objective-C methods.  Once this is finished, I will be recommending Smalltalk as the development language-of-choice for new Étoilé applications.  If you discover that a particular piece of code is too slow (after profiling) then you might want to rewrite it in Objective-C (or even pure C), although I don't expect Smalltalk to be much slower than Objective-C.</p>

<p>Smalltalk is not the only high-level language we will implement in this way - just the first.  Expect Io, JavaScript and maybe even Self implementations later.  These languages are all prototype-based, however, and so require a few features that are not found in the GNU runtime (but are in the Étoilé runtime) for full support.</p>
]]></content>
</entry>

<entry>
<title>Hackathon Recap</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/04/11/0117/"/>
<author><name>Quentin Mathé</name></author>
<id>http://etoileos.com/news/archive/2008/04/11/0117/</id>
<updated>2008-04-11T01:17:00-07:00</updated>
<content type="html"><![CDATA[<p>Étoilé hackathon ended ten days ago, I left Swansea on Tuesday afternoon to flight back to Paris after a mix of train and bus. Afterwards David and <a href="http://people.untyped.org/damien.pollet/">Damien Pollet</a> succeeded in closing the hackaton by writing the first bits of a bridge between <a href="http://smalltalk.gnu.org/">GNU Smalltalk</a> and Objective-C.</p>

<p>Following Friday talks, we wandered around the university looking for a pub where we could eat. We finally ended up at David's place and had a nice break around beers (that aren't beers but ales), coffee, saucissons and we ordered some real food too. Afterwards Nicolas was still motivated to learn more about EtoileUI. His interest for EtoileUI had the bad side-effect of shortening the night quite dramatically!</p>

<p>During the week-end, we discussed the proper way to implement a semantic editor and how to integrate it with EtoileUI and CoreObject. Nicolas spent most of his time writing a new prototype. He already wrote <a href="http://camaelon.blogspot.com/2005/11/structured-edition.html">a very rough one</a> few years ago.</p>

<p>Damien arrived from Lugano on the second day of the hackaton. After having installed Étoilé, he started to play with the possibility to hack a Smalltalk bridge. In the meantime, David continued his work on EtoileSerialize, while I spent a large part of the week-end cleaning stuff here and there and hunting bugs of EtoileUI on GNUstep (Saturday and Sunday night especially :-).</p>

<p>We also began to clean EtoileFoundation a bit, David moved EtoileThread to it, and last week I recently managed to bring EtoileXML too and have both compiles fine as subframeworks (EtoileFoundation.h playing the role of an umbrella header). In the middle of our discussions centered around CoreObject and EtoileSerialize, I got the impression David was doing some coding on LLVM too, while Damien was fighting with autotools next to me. At least, I was able to follow David's presence on the #llvm channel right on the wall screen where Jesse appeared the previous day. I'm pretty sure everything went on rougly that way until Monday!</p>

<p>On Saturday evening, I lost myself in Swansea suburbs and the five minutes walk to buy a few ales became a one hour walk in the Welsh drizzle. The next day, the weather persisted to be quite unstable, constantly hesitating between storm, sun and waxy clouds. Monday, our own trinity (EtoileSerialize, CoreObject and EtoileUI) was expecting us for a last serious day of hacking. The sky was now in a better shape and could have been qualified of sunny and warm by previous day standards ;-) David had the good idea to plan a break at the pub for the evenining, so we could slow down a bit before really ending the hackaton. For the last day, I went to a coffee shop where I previously bought some nice scones and Chelsea cakes (iirc), then we left David's place for the university and our daily coffee session with a nice vista on the sea and the sound of the seagulls in background (or is it just my vivid imagination?).</p>

<p>The hackaton was just great, although the time went by very quickly. David had well organized everything and after our daily hacking sessions, he even managed to cook some very nice stuff (like weird and tasty squashes) for the hungry french hackers, so I'm looking forward to the next one. May be in France…</p>
]]></content>
</entry>

<entry>
<title>Hackathon Progress</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/03/30/2128/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/03/30/2128/</id>
<updated>2008-03-30T21:28:00-07:00</updated>
<content type="html"><![CDATA[<p>The hackathon started on Friday, with Quentin and Nicolas arriving in Swansea in the early afternoon.  After briefly settling in, the three of us gave a short series of talks to the postgraduate students in the department of computer science.</p>

<p><img alt='Quentin expains things' src='http://etoileos.com/images/hackathon/qmath_talk.jpg' width='510' /></p>

<p>I managed to pursuade Quentin to write some documentation, which can be seen here:</p>

<p><img alt='Quentin&quot; documentation' src='http://etoileos.com/images/hackathon/qmath_doc.jpg' width='510' /></p>

<p>Jesse, unfortunately, was unable to be with us in the flesh, but appeared on the wall in the middle of the afternoon as our very own Big Brother (or possibly Emmanuel Goldstein):</p>

<p><img alt='Big Brother Jesse' src='http://etoileos.com/images/hackathon/jross1.jpg' width='510' /></p>

<p>Most of the time has been spent working on CoreObject-related things.  Nicolas has implemented a basic semantic text editor, which Quentin is wrapping up in CoreObject.  I spent most of the time so far working on EtoileSerialise (or EtoileSerialize, as it is now known).  It now passes the test automatically serialising nested structures of arrays of structures.  The storage has also been abstracted away, and branching (finally) implemented.</p>

<p><img alt='Nicolas explains his code to Quentin' src='http://etoileos.com/images/hackathon/nico_code.jpg' width='510' /></p>

<p>Last night, after a day of hacking on various things, we implemented CorePizza, the official Étoilé project food:</p>

<p><img alt='The Real Core Object' src='http://etoileos.com/images/hackathon/core_pizza.jpg' width='510' /></p>

<p>Someone stole an hour from the middle of last night, so we're a bit tired today, but still making progress.</p>
]]></content>
</entry>

<entry>
<title>Summer of Code</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/03/18/1222/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/03/18/1222/</id>
<updated>2008-03-18T12:22:00-07:00</updated>
<content type="html"><![CDATA[<p>The Google Summer of Code list was published last night.  We have some good news and some bad news.  The bad news is that Étoilé wasn't selected.  The good news is that GNUstep was.  Since Étoilé is built on top of GNUstep, everything that benefits them benefits us, so anyone interested in the summer of code and Étoilé should consider applying for one of the GNUstep places.  We don't know how many places each project was awareded until later on in the process, but last year they got two so hopefully a couple of interesting projects can be finished as a result of the summer.</p>
]]></content>
</entry>

<entry>
<title>Spring Hackathon</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2008/03/06/1622/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2008/03/06/1622/</id>
<updated>2008-03-06T16:22:00-08:00</updated>
<content type="html"><![CDATA[<p>The dates and location of the first Étoilé Spring Hackathon are now finalised.  We will officially be starting on Friday the 28th of March and continuing until the 1st of April.</p>

<p>The Swansea University Computer Science department has very kindly agreed to provide us with a room for the duration of the hackathon in <a href="http://maps.google.co.uk/maps?f=d&amp;hl=en&amp;geocode=&amp;saddr=51.609416,-3.97895&amp;daddr=&amp;mra=mi&amp;mrsp=0&amp;sz=17&amp;sll=51.609589,-3.979958&amp;sspn=0.004284,0.008476&amp;ie=UTF8&amp;ll=51.609902,-3.982372&amp;spn=0.008568,0.016952&amp;t=h&amp;z=16">this building</a>.  Access to the building and room is via security card.  I'll arrange some visitors' cards for attendees.</p>

<p>We're about fifteen minutes walk away from <a href="http://maps.google.co.uk/maps?f=q&amp;hl=en&amp;geocode=&amp;q=westbourne+pub+swansea&amp;ie=UTF8&amp;ll=51.616391,-3.959885&amp;spn=0.017134,0.033903&amp;t=h&amp;z=15&amp;iwloc=A">a pub that serves real ale and has free WiFi</a>, which should come in handy for the evenings.</p>

<p>If you're coming, let me know when you're likely to arrive.  I'll try to arrange some kind of social event on the Thursday evening before the real hacking starts.</p>
]]></content>
</entry>

<entry>
<title>Futures in Objective-C</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2007/09/23/2117/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2007/09/23/2117/</id>
<updated>2007-09-23T21:17:00-07:00</updated>
<content type="html"><![CDATA[<p>I like concurrent programming, but I don't like threads.  Like files, they're a nice abstraction for operating system designers but not so much for userspace hippies.</p>

<p>In functional languages, you can often get concurrency for free by having a clever compiler, instead of a clever human.  This is good, because clever humans are expensive.  Clever compilers are too, but they're easier to copy than clever humans.</p>

<p>Consider the following bit of Objective-C:</p>

<p><pre>
id foo = [anObject doSomehing];
...
[foo doSomethingElse];
</pre></p>

<p>In Smalltalk, objects were regarded as simple computers that communicated by message passing.  The fact that this message passing was implemented with a stack was hidden.  To the Smalltalk way of thinking, the objects were independent.  This bit of code sends a doSomething message to anObject, and block until it sends a return message.</p>

<p>From here, it doesn't take long to realise that you don't actually need it to block until the [foo doSomethingElse] line.  So, can we implement this in Objective-C in the general case?  The answer is yes, and that's what the EtoileThread framework (soon to be in EtoileFoundation) does.  It works on OS X too.</p>

<p>I actually wrote EtoileThread in a hotel in Dublin in June last year, but I recently rewrote a lot of it to be more efficient.  I'd like to give a little overview of how it works.</p>

<p>There are three core components to this.  The first is the ETThreadedObject class, which encapsulates an object in its own thread.  It's an NSProxy subclass, and forwards messages to the real object.  You create it typically via an NSObject category, which adds +threadedNew and -inNewThread methods.  When you send a message to the object returned by either of these, the following sequence happens:</p>

<ol>
<li>The invocation is caught by the ETThreadedObject and put into a ring buffer.
<li>The forwardInvocation: method returns, and the calling code receives an ETThreadProxyReturn object.
<li>The second thread retrieves the invocation from the ring buffer and executes it.  
<li>The second thread passes the real return value to the previously returned ETThreadProxyReturn.
<li>Any calls to methods in the returned proxy block until this point.
</ol>

<p>What does that look like in practice?  Well, we'll look at the simple example program included with the framework (ETThreadTest.m for those following in svn) and see.  First, we define a simple class that has some trivial methods:</p>

<p><pre>
@implementation ThreadTest
- (void) log:(NSString*)aString
{
    sleep(2);
    NSLog(@"%@", aString);
}
- (id) getFoo
{
    sleep(2);
    return @"foo";
}
@end
</pre></p>

<p>The first just NSLogs whatever is passed to it, and the second returns a constant string.  Next, in the main body, we create an instance of this in its own thread:</p>

<p><pre>
    id proxy = [ThreadTest threadedNew];
</pre></p>

<p>We then send this a log message:</p>

<p><pre>
    [proxy log:@"1) Logging in another thread"];
</pre></p>

<p>And then a getFoo message.  Recall that the implementations of both of these messages had 2 second delay built into them.  This was introduced to make it obvious which order everything was being executed in.</p>

<p><pre>
    NSString * foo = [proxy getFoo];
</pre>
Next, we NSLog something from the main thread, just to show where we are.</p>

<p><pre>
    NSLog(@"2) [proxy getFoo] called.  Attempting to capitalize the return...");
</pre></p>

<p>Then, we NSLog the return value from the getFoo method (for good measure, we'll send it a message and NSLog the result, rather than NSLoging it directly):</p>

<p><pre>
    NSLog(@"3) [proxy getFoo] is capitalized as %@", [foo capitalizedString]);
</pre></p>

<p>Finally, since we know we are calling a future, we get the real object out and NSLog it.</p>

<p><pre>
    if([foo isFuture])
    {
        NSLog(@"4) Real object returned by future: %@",
                [(ETThreadProxyReturn*)foo value]);
    }
</pre></p>

<p>What happens when we run this?  Take a look:</p>

<p><pre>
$ ./ETThreadTest 
2007-09-23 21:59:39.718 ETThreadTest[25196] 2) [proxy getFoo] called.  Attempting to capitalize the return...
2007-09-23 21:59:41.695 ETThreadTest[25196] 1) Logging in another thread
2007-09-23 21:59:43.695 ETThreadTest[25196] 3) [proxy getFoo] is capitalized as Foo
2007-09-23 21:59:43.695 ETThreadTest[25196] 4) Real object returned by future: foo
</pre></p>

<p>Note that the NSLog from the main thread completes first.  Note also the two second delays.  Finally, note that the third and fourth log statements don't complete until after the getFoo method has run, since they depend on the returned value.</p>

<p>What's improved in the implementation of this in the last week?  My first version was quite experimental.  It used an NSMutableArray to store the invocation queue.  This meant that every message going into the queue required these steps:</p>

<ol>
<li>Acquiring a mutex.
<li>Inserting an object into an NSMutableArray.
<li>Signalling a condition variable (if the array was empty).
<li>Releasing a mutex.
</ol>

<p>On the receiving end, you needed the following:</p>

<ol>
<li>Acquiring a mutex.
<li>Sleeping on a condition variable (if the array is empty).
<li>Removing the first object from an NSMutableArray (quite expensive).
<li>Releasing a mutex.
</ol>

<p>This is a minimum of four system calls (a maximum of six) and at least one expensive array operation.  This isn't too bad if you are only very occasionally sending messages to your threaded objects, and are expecting them to take a long time to complete.  If you are sending a lot of messages, however, the overhead quickly stops it being worthwhile to bother with the second thread.</p>

<p>The new implementation uses a lockless ring buffer in this situation.  Inserting an object into this involves a subtraction and a comparison to see if it's full (we just spin using sched_yield() if it is, but with enough space for 128 invocations in the buffer that should be rare), inserting two objects in a C array (the invocation and the proxy value), an addition, and a memory buffer (on weakly-ordered platforms, not on x86).  Removing an object switches back to the old-style locking mode if the queue is empty.  We don't want to spin if there is no work to do for the consumer thread, because that could last a long time.  Then, taking the objects out of the array is just copying their pointers out of the array and another addition.</p>

<p>The ring buffers, like those in Xen, use free-running counters and a mask of the lower bits to translate this into an address.</p>

<p>There are two special cases.  The futures code only works for methods that return objects.  For methods that return non-objects, we need to wait until the invocation has completed.  For void return methods, we simply complete asynchronously, but don't return a proxy object.</p>

<p>If you want a more detailed overview of how it all works, there are lots of comments in the code.  Have fun, and file helpful bug reports.</p>

<!-- COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/07125033623483825868" rel="nofollow">Peter</a>
COMMENT-DATE:11:04 PM
COMMENT-BODY:I will probably need to re-read this to digest it.  But one question: Is this at all similar to Apple's new NSOperation class?  I work in a research institute that is very excited by OpenMPI, and so NSOperation's advertised affinity to OpenMPI is very sexy.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/04390989998347964272" rel="nofollow">Yen-Ju Chen</a>
COMMENT-DATE:11:17 PM
COMMENT-BODY:I wonder whether it is useful for something like "searching while typing" and "counting words while typing". I image it requires not only thread, but also the ability to stop current thread so that a new one can start.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/04057058584432088746" rel="nofollow">Nicolas</a>
COMMENT-DATE:12:57 AM
COMMENT-BODY:yen-ju: it should be doable -- we are using pthread underneath after all, so a pthread_kill could do the trick (of course, nicely encapsulated in a message call). That would be a cool feature to add, indeed. A notification or ability to provide a block (Quentin has some cool things...) executed when the thread is done could be neat as well.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:1:46 AM
COMMENT-BODY:it is not a good idea to use pthread_kill, what if the thread you intend still holds resources (mutexes, sockets, files...) ?

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/13618832348086828111" rel="nofollow">Kumar</a>
COMMENT-DATE:10:33 AM
COMMENT-BODY:There is a keyword called "oneway" in Apple's Objective-C implementation whose specification is probably what you want .. except that it seems to be relevant only when communicating with remote objects. <BR/><BR/>See section "Language support" in http://developer.apple.com/documentation/Cocoa/Conceptual/ObjectiveC/Arti cles/chapter_5_section_6.html-->
]]></content>
</entry>

<entry>
<title>XHTML-IM Support</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2007/08/27/1832/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2007/08/27/1832/</id>
<updated>2007-08-27T18:32:00-07:00</updated>
<content type="html"><![CDATA[<p>Ages ago, I wrote most of an <a href="http://www.xmpp.org/extensions/xep-0071.html">XHTML-IM</a> parser for StepChat.  I didn't enable it in the default build, since it wasn't quite working.  Over the weekend, I finished it off, tested it, and added support for generating some XHTML-IM.  The code is not completely compliant with the specification, since it doesn't bother checking if the other party supports HTML.  This will probably be added soon.  It also contains a couple of work-arounds for libgaim-based clients, which interpret the standard quite creatively.</p>

<p>Below, you can see a conversation I had with my debugging persona (yes, I know talking to yourself is a sign of madness, especially when you use the Internet to do it).  The first image comes from FreeBSD/GNUstep while the second one comes from OS X.  Camaelon is not enabled for Jabber on my FreeBSD box because it was breaking things (I think it's fixed now, but I haven't got around to removing the default)</p>

<div style="text-align: center;"><img src="http://www.etoile-project.org/etoile/blog/uploaded_images/xhtml-730663.png" alt="StepChat on FreeBSD/GNUstep" border="1" /> <img src="http://www.etoile-project.org/etoile/blog/uploaded_images/xhtml_osx-793546.png" alt="StepChat on OS X" border="0" /></div>

<p>The more observant among you will notice that I fixed a bug in the handling of bold text in the middle of this conversation.</p>

<div style="clear:both; padding-bottom:0.25em"></div>

<p class="blogger-labels">Labels: <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/jabber.html">jabber</a>, <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/omgponies.html">omgponies</a>, <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/stepchat.html">stepchat</a>, <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/xhtml-im.html">xhtml-im</a>, <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/xmpp.html">xmpp</a></p>
]]></content>
</entry>

<entry>
<title>Drop Shadows</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2007/08/09/1721/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2007/08/09/1721/</id>
<updated>2007-08-09T17:21:00-07:00</updated>
<content type="html"><![CDATA[<p>Shadows are nice.  Since we got compositing managers for X11, we've had the ability to do this.  The xcompmgr program does it, but in a gimmicky, eye-candy way, which doesn't really add much to usability.</p>

<p>Shadows are definitely something we want though, so yesterday I forked xcompmgr and put it in our repository.  Today we have some (early) results.  Drop shadows:</p>

<p><a href="http://www.etoile-project.org/etoile/blog/uploaded_images/Shadow1-722348.png"><img style="cursor:pointer; cursor:hand;" src="http://www.etoile-project.org/etoile/blog/uploaded_images/Shadow1-722341.png" border="0" alt="" /></a></p>

<p>Three  things to note.  The first is that the dock and menu bar don't have shadows.  The second is that the active window has a bigger one than the others.  Finally, there are no shadows visible on the Typewriter window at the top right of the screen.  The first two of these are intentional.  The third is not, but only occurs in screenshots, not on the screen, and so is probably not very important.</p>

<div style="clear:both; padding-bottom:0.25em"></div>

<p class="blogger-labels">Labels: <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/shadow.html">shadow</a>, <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/shiny.html">shiny</a>, <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/ui.html">ui</a></p>

<!-- COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:7:49 PM
COMMENT-BODY:Maybe I'm tired, but I definitely see a shadow on the window that says "Shadows are quite shiny, no?"<BR/><BR/>Good job.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/06582362579394220260" rel="nofollow">Jesse Ross</a>
COMMENT-DATE:8:13 PM
COMMENT-BODY:I think he meant the fact that DictionaryReader is not casting a shadow on Typewriter, which it should be since they overlap.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/04893729285856691511" rel="nofollow">Thomas Perl</a>
COMMENT-DATE:9:23 PM
COMMENT-BODY:Does this mean it will be possible to make AZDock's currently gray background transparent now? That would rock!-->
]]></content>
</entry>

<entry>
<title>Étoilé 0.2 Troubleshoot</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2007/08/03/0240/"/>
<author><name>Yen-Ju Chen</name></author>
<id>http://etoileos.com/news/archive/2007/08/03/0240/</id>
<updated>2007-08-03T02:40:00-07:00</updated>
<content type="html"><![CDATA[<p>Since 0.2 release, there are some issues regarding setting up the Étoilé environment. Here are a few steps to narrow down the problem.</p>

<p>First, make sure your GNUstep is correctly installed. Current stable release of GNUstep is Make 2, Base 1.14, GUI/Back 0.12. You can also get them from GNUstep <a href="http://gnustep.blogspot.com/2007/04/new-gnustep-releases.html">stable branch</a>. Run a few GNUstep <a href="http://www.gnustep.org/experience/apps.html">applications</a> in any graphic environment to be sure your GNUstep is working. And remember to <a href="http://www.gnustep.org/resources/documentation/User/GNUstep/gnustep-howto_4.html">source GNUstep.sh</a> in your profile. You can get help from <a href="http://www.gnustep.org/information/gethelp.html">GNUstep maillist</a> if problems occur at this stage.</p>

<p>Second, after installing Étoilé, run a few user-level applications, such as Typewriter, Sketch, StepChat, Vindaloo, AddressManager and FontManager. They are regular GNUstep applications. You can run them in any graphic environment such as GNOME, KDE or WindowMaker.  If you run 'setup.sh' during the installation, several bundles have also been installed. For testing purpose, you can remove them by:</p>

<pre><code>defaults delete NSGlobalDomain GSAppKitUserBundles
</code></pre>

<p>and add them back by :</p>

<pre><code>defaults write NSGlobalDomain GSAppKitUserBundles '(
/usr/local/GNUstep/System/Library/Bundles/Camaelon.themeEngine,
/usr/local/GNUstep/System/Library/Bundles/EtoileMenus.bundle, 
/usr/local/GNUstep/System/Library/Bundles/EtoileBehavior.bundle)'
</code></pre>

<p>Make sure the paths are correct. You can also try different combination of these bundles. Camaelon is the theme engine. EtoileMenus is the horizontal menu. EtoileBehavior handles various tasks behind the scene and you will not see any change on user interface with it.</p>

<p>Third, you should be able to set up Étoilé manually. With GNOME, you can log into a fault-safe session with xterm only. There should be something similar on KDE. Once xterm shows up, run these system-level applications one-by-one:</p>

<pre><code>gdomap &amp;
openapp Azalea &amp;
openapp AZBackground &amp;
openapp EtoileMenuServer &amp;
openapp AZDock &amp;
</code></pre>

<p>If they all run propertly, you are close to have a functional Étoilé environment. Log out the session by exiting from xterm and log into the fault-safe session again. Run '<i>etoile_system</i>' tool (no <i>openapp</i> !) and all the system applications should launch automatically. If not, check your <i>SystemTaskList.plist</i> in your GNUstep/System/Library/Etoile/ or ~/GNUstep/Library/Etoile/. It contains all the applications you launched one step before.</p>

<p>Finally, to add Étoilé into your GDM, make sure these files exists:</p>

<ol>
<li><i>etoile.desktop</i>, in your xsession directory, such as '/usr/share/xsessions'. And it should contain a line 'Exec=/usr/local/bin/etoile'. You can get this file in <i>Etoile/Services/Private/System/</i>.
<li><i>/usr/local/bin/etoile</i>. This is the actual script to run '<i>etoile_system</i>'. It should look like this:
<blockquote>
. /usr/local/GNUstep/System/Library/Makefiles/GNUstep.sh
etoile_system
</blockquote>
There is a space between '.' and '/usr/local/GNUstep/System/Library/Makefiles/GNUstep.sh'. And be sure the permission is correct.
</ol>

<p>If you log into the fault-safe session again, you should be able to run this script '/usr/local/bin/etoile' to launch etoile_system, which will then launch all other system-level applications. By this point, you should have a Étoilé session in GDM for Étoilé environment.</p>

<p>If you want to set up the Login.app, see '<i>Etoile/Services/Private/Login/README</i>' for details.</p>

<p><b>Update:</b> There is a <a href="https://mail.gna.org/public/etoile-discuss/2007-08/msg00080.html">summary</a> of latest GNUstep/Etoile on Solaris.</p>

<!--COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/06800577670466787997" rel="nofollow">James</a>
COMMENT-DATE:4:33 AM
COMMENT-BODY:Any debian packages in the works? -->
]]></content>
</entry>

<entry>
<title>Étoilé 0.2 is now officially released</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2007/07/28/2206/"/>
<author><name>Yen-Ju Chen</name></author>
<id>http://etoileos.com/news/archive/2007/07/28/2206/</id>
<updated>2007-07-28T22:06:00-07:00</updated>
<content type="html"><![CDATA[<p>Étoilé 0.2 is now officially released.  See the full <a href="http://www.etoile-project.org/etoile/mediawiki/index.php?title=0.2_Release_Announcement">0.2 Release Announcement</a> for more information.  There are a number of <a href="http://www.etoile-project.org/etoile/mediawiki/index.php?title=Etoile_02_Release_Screenshots">screenshots</a> of this release online.  A <a href="http://download.gna.org/etoile/etoile-0.2.tar.gz"> source tarball</a> is available for download.  Those preferring to use subversion should check out /tags/Etoile-0.2 from the repository.  If you have any questions regarding this release, please post your queries to the <a href="https://mail.gna.org/listinfo/etoile-discuss/">Etoile-discuss mailing list</a> or visit the SILC channel Etoile on silc.etoile-project.org.</p>

<!--COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/07125033623483825868" rel="nofollow">Peter</a>
COMMENT-DATE:4:23 AM
COMMENT-BODY:Congratulations on your release!  I'll try building it up this week!

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:12:11 AM
COMMENT-BODY:Too bad we're still stuck with X

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:12:59 AM
COMMENT-BODY:poo poo poo poo poo

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/00339637852708124157" rel="nofollow">Arjun</a>
COMMENT-DATE:3:44 AM
COMMENT-BODY:good job ! keep it up !

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:5:05 AM
COMMENT-BODY:@Anonymous: what's wrong with X?

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:6:40 AM
COMMENT-BODY:http://www.simson.net/ref/ugh.pdf<BR/><BR/>Refer to Chapter 7.<BR/><BR/>Programming X blows.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:9:27 AM
COMMENT-BODY:great work guys!!<BR/>I hope this project continues and not finished unmaintened and /or forgotten<BR/><BR/>and remember a good option will be Etoile + compiz fusion, this will bring more people interested

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<a href="http://gufo.wordpress.com" rel="nofollow">ilgufo</a>
COMMENT-DATE:6:33 PM
COMMENT-BODY:Congratulations for this release.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:8:44 PM
COMMENT-BODY:Hey anonymous about the "programming X blows":<BR/><BR/>The Unix Haters handbook was compiled in 1994.   Most of the book is actually from earlier; 1990 or 1991.  <BR/><BR/>Some things have changed since then.   But I guess you're just ignorant.<BR/><BR/>Sure, there's some things that still could use work, but X has improved by leaps and bounds in the last 15 years.. -->
]]></content>
</entry>

<entry>
<title>The Road to CoreObject Part 1: EtoileSerialise</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2007/07/19/1755/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2007/07/19/1755/</id>
<updated>2007-07-19T17:55:00-07:00</updated>
<content type="html"><![CDATA[<h1>The Road to CoreObject Part 1: EtoileSerialise</h1>

<p>I've now submitted my PhD thesis and more or less wrapped up my <a href="http://www.amazon.co.uk/gp/redirect.html?ie=UTF8&location=http%3A%2F%2Fwww.amazon.com%2FHacking-Xen-Definitive-Prentice-Development%2Fdp%2F013234971X%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1184327503%26sr%3D8-1&tag=theravesnest-21&linkCode=ur2&camp=1634&creative=6738">Xen Book</a>, so now I'm taking the summer off (apart from the odd article) to work on Étoilé before looking for some kind of job.</p>

<p>I've mainly been focussing on development of CoreObject, specifically the low level components required for CoreObject, this month.</p>

<h2>Files Suck</h2>

<p>Many of the ideas here come from a discussion between myself and Nicolas a few years back about how computers suck and how we can make them suck less (a recurring theme, that eventually led to the formation of Étoilé when it turned out that we weren't the only people having this conversation).</p>

<p>CoreObject is intended to be one of the foundation pieces of Étoilé.  The current roadmap calls for an experimental version in 0.3, a stable interface in 0.4, and a completely stable version in 0.5.</p>

<p>What is CoreObject?  Basically, it's a replacement for a filesystem as a programmer and user interface.  Files (in the UNIX sense of the word) never were a good abstraction; an untyped series of bytes is no use to anyone.  The operating system needs to deal with things like this, but programmers shouldn't have to.</p>

<p>We already have a much nicer abstraction than a file; the object.  Unlike files, objects have all of the structure and introspection that we want in order to be able to interact with them programatically.  In Étoilé, we want to treat everything as an object, and objects as first-class citizens.</p>

<h2>Persistence</h2>

<p>At the lowest level, CoreObject provides a persistence layer, and that's what the EtoileSerialise framework is for.  It turns out that the Objective-C runtime stores the names and types of all of a class's instance variables, making it almost possible to serialise arbitrary objects without any extra code.</p>

<p>Why Almost?  Because Objective-C isn't really a language, it's two languages that you are allowed to mix together in the same source file.  One of these languages is a close relative of Smalltalk.  The other is C.  Anything that just uses the Smalltalk components of the language is easy, since the runtime stores all of the type information.  Anything that uses the C component is impossible, because there is no runtime information at all.  Most code that we are interested in lies on the boundary.</p>

<p>The EtoileSerialise framework doesn't serialise anything other than objects.  Objects, however, have instance variables that can be C types.  Some of these are easy.  An int, or float, for example, has its type encoded in the object's description, and so we just need some special handlers for the various C types (of which there are not many).  The same is true of static arrays.  If you say something like 'int foo[20];' in an instance variable description, the runtime encodes the size of the array and we can retrieve that and transparently serialise the array.  The same is true of structs, where the runtime stores the type for each field.</p>

<p>Dynamic arrays start to get a bit harder.  A dynamic array in C is just a pointer.  If you say 'int * foo' then the only information available to the serialiser is that foo is a pointer to an integer.  It could be an array, or a pointer to an aliased intrinsic.  If it's an array, we have no way of knowing the size.  This is not quite true.  On Windows and OS X there are extensions to the malloc() family that let us know the size of a block of memory identified by a pointer, but they are non-portable.  This doesn't help us at all when we have something like 'int **' though, since we don't know if it's a 2D array, an index array, or something else.  At this point, the serialiser just gives up.</p>

<p>Fortunately, Objective-C is a nice dynamic language, so we can fudge this slightly.  For objects that use low-level components of C, we introduce an informal protocol that asks the object to manually serialise it.  This takes the ivar name and the serialiser back end as arguments, and so anything the serialiser can do, this method can too.  On the deserialisation end, two other methods are available for fixups.  One is the converse of this, requesting that an object manually deserialise an ivar.  The other is invoked with no arguments once an entire object graph has been deserialised.  Note that the serialise and deserialise methods don't do any type checking for manually serialised things, so you can serialise an int as a C string if you need to.  One reason you might want to do this is for an object wrapping a file, where the ivar would contain a file descriptor (an int).  If you just store this and reload it, you will get nonsense, so you might instead store the file name and re-open the file on deserialisation.</p>

<p>There are two other pieces of the puzzle.  One is named structures.  Some structures need special handling, and it is a bit rubbish to expect the developer of every object that needs to handle them to know about this.  Fortunately, the runtime system knows the name of structures that are used.    To make use of this, you can register a function that handles serialisation of a named structure.  The serialiser will then call this whenever a structure of this form is encountered.  The other part is versioning.</p>

<p>OpenStep's NSObject already has a -version and a -setVersion: method.  We make use of this with the serialiser by encoding the version with each serialised class (for subclasses, we encode the version of each class in the hierarchy with the instance variables inherited from that class).  The manual deserialiser method takes the version as a third argument.  If you change the instance variables of a class, it's easy to add support for deserialising the old version by implementing this.  It is even possible to do this in reverse, by supplying a category on the old object that loads the new one, or even deserialise an object using an object of a completely different class using the poseAs: mechanism.</p>

<h2>Versioning</h2>

<p>We can version classes, but what about objects?  It would be nice to have the revision history preserved.  We do this by turning a model-controller-view trio into a model-(CoreObject proxy)-controller-view system.</p>

<p>With Objective-C, everything is an object, including the messages you send to objects (the equivalent of method calls in C++/Java).  The combination of the message name (selector) and arguments is known as an invocation, represented by the NSInvocation class.  Our COProxy object, or a subclass, sits between the model and controller and serialises every message that is sent to the model.  This stores the complete revision history of the object.  To reload any version of the object, you can just reload and replay the invocations.  So this doesn't take too long, the COProxy object periodically serialises a copy of the object.  Currently this is done every 100 messages.  In future it will be configurable.</p>

<p>I mentioned COProxy subclasses.  The reason for needing these is that Objective-C doesn't have the concept of 'const' methods, i.e. methods that are guaranteed not to affect the state of the object.  We don't want to bother serialising these, so we will use a subclass for each class we might use as the principle class in our model to automatically pass these through.</p>

<p>We thus have saving, restoring, and versioning of arbitrary objects for free.  Since we're greedy, we want more.  Let's also have branching and merging.  Branching is easy; we just define two objects with the same previous version.  What about merging?  Well, I think we can do this by re-playing the invocations from the two branches in an interleaved way.  This will probably be done with a UI allowing the user to select which invocation should be run next.</p>

<p>Anything else?  What about collaboration?  Since we are serialising invocations, we can pass them over a network to another user, and they can keep their copy of an object in sync with ours.  With a simple locking protocol, we can have bi-directional syncing.  The serialiser and deserialiser are split into a front and back end, with the back end defining the storage format.  At the moment there is a binary file format and a simple human-readable output-only back end for testing.  An XML backend will be added too, allowing objects (including invocations) to be passed over XMPP (Jabber).</p>

<p>Oh, one more thing.  This also gives us non-destructive editing of any arbitrary object type, from text through images to video, as long as we have an object encapsulating it.  Excited yet?</p>

<h2>Does it work?</h2>

<p>So, what's the current status?  Actually, pretty good.  The code contains a few 32-bit x86isms that need fixing.  Serialisation works for a lot of objects with no modification, and more with a little tweaking.  Deserialisation is a bit less finished.  Deserialisation of named structures is not finished, and neither is the special code-path for serialising invocations.  The COProxy object works, and serialises invocations properly.  It does not yet include a mechanism for re-loading them, but the example back end allows you to see that all the required information is saved.</p>

<p>Currently, the build system creates a test app, rather than a framework.  This will be changed towards the end of the month, when the first alpha will be ready.  The interfaces are still likely to change, however, so don't start integrating it into your code yet.  Étoilé 0.3 will have a fairly stable version for everyone to play with and, hopefully, some of the higher-levels of CoreObject, which will deal with metadata, indexing, and type conversions too.</p>

<h2>Idiot!  Use Smalltalk!</h2>

<p>Some people will be reading this and thinking 'this whole thing would be much easier in Smalltalk.'  This is true.  In Smalltalk it would be possible to write the completely generic version, and use the garbage collector to track any aliasing, etc.    So, why don't we use Smalltalk?  Smalltalk's a great language (ask Nicolas why, but only if you've got a long time to listen to the answer), and easy to learn; even small children can pick it up quickly. It doesn't, however, play nicely with other languages (or even GUIs), and there are not many people who know the language well.</p>

<p>Nicolas has described Étoilé as a 'pragmatic Smalltalk.'  We sacrifice some of the nice features of Smalltalk, but gain the ability to make use of lots of legacy C code.  Objective-C isn't quite as nice as Smalltak, although it's close, but we gain a lot more from the Objective-C frameworks than we lose from the language.</p>

<div style="clear:both; padding-bottom:0.25em"></div>

<p class="blogger-labels">Labels: <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/CoreObject.html">CoreObject</a>, <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/EtoileSerialise.html">EtoileSerialise</a>, <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/shiny.html">shiny</a></p>

<!--COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:5:59 PM
COMMENT-BODY:Does this have anything at all to do with Apple's CoreData?

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/16578819125635628256" rel="nofollow">David Chisnall</a>
COMMENT-DATE:7:44 PM
COMMENT-BODY:Not directly.  CoreObject allows you to design your data models in a data modeling language, and write your code in Objective-C.  This has two problems.  The first is that it requires you to define your data models in one language and manipulate them in another.  The second is that it is really only useful for new applications.  Trying to add CoreData support to existing code is not at all easy.  <BR/><BR/>The goal of CoreObject is to be very simple to use, and to add to existing codebases.  You will just insert the CoreObject proxy into your existing code between the model and controller and get all of the benefits.  It won't require a complete re-write of your model objects (although you may need to add categories for some that use pointers a lot), and it won't require you to write much code to use (because, let's face it, we're all lazy).<BR/><BR/>By the way, CoreData is in many ways a simplified version of the old Enterprise Object Framework from NeXT.  GNUstep already has an implementation of this, in the form of GDL2.  I believe someone has done a partial implementation of CoreData on top of GDL2, but I haven't been following the project closely.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/16578819125635628256" rel="nofollow">David Chisnall</a>
COMMENT-DATE:8:23 PM
COMMENT-BODY:<I>CoreObject allows you to design your data models in a data modeling language, and write your code in Objective-C.</I><BR/><BR/>And, by CoreObject, I obviously mean CoreData.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/08311081332386864366" rel="nofollow">Emanuele &quot;∞&quot; Vulcano</a>
COMMENT-DATE:8:35 PM
COMMENT-BODY:Why reinvent serialization if Foundation has the nice and clean NSCoding thingy that also takes care of all C evilness?

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/16578819125635628256" rel="nofollow">David Chisnall</a>
COMMENT-DATE:11:48 AM
COMMENT-BODY:NSCoding works, but it's a lot of effort to use.  When writing a new class, you need to implement the serialiseWithCoder: and corresponding deserialisation methods yourself.  I am much too lazy to do this.  The aim with CoreObject is to require as little new code as possible.  The aim is for 90% of objects to require no modification, and the rest to only require minimal changes.  <BR/><BR/>With EtoileSerialise at the moment, you can mix and match between manual and automatic serialisation.  If you compile the framework with WARN_IF_GUESS defined, it will warn you whenever it's making a guess (e.g. that char* is a NULL-terminated string) or if it can't handle something automatically, logging the class and ivar name.  You can then write a custom method that handles just that ivar, and lets the system automatically serialise the rest.  The serialisation methods required for a fairly complicated class with  EtoileSerialise are much shorter than those required by NSCoding, and for some classes no extra code is required at all.<BR/><BR/>NSCoding leaves everything up to the programmer, while EtoileSerialise only needs the programmer to fill in the gaps where the runtime doesn't have enough information to determine the structure of the data automatically.  This means you need less code.  Less code means fewer bugs and more time spent working on things other than basic housekeeping.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/04057058584432088746" rel="nofollow">Nicolas</a>
COMMENT-DATE:2:19 PM
COMMENT-BODY:emanuele: NSCoding does work, and it's not too annoying at first glance: only two methods to write.. for each object. With the persistence implemented in CoreObject, you don't need to do anything for the vast majority of your objects. As David said, it's less code to write, less bugs for you.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:12:48 AM
COMMENT-BODY:Can you compare and contrast with WindowMaker? I have been using that for a while. -->
]]></content>
</entry>

<entry>
<title>The Road to CoreObject Part 2:  Why Bother?</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2007/07/30/1156/"/>
<author><name>David Chisnall</name></author>
<id>http://etoileos.com/news/archive/2007/07/30/1156/</id>
<updated>2007-07-30T11:56:00-07:00</updated>
<content type="html"><![CDATA[<p>Since the last post, a lot of people have asked me 'why are you doing this?  What advantage does it actually give?'  In this post, I'll try to explain.</p>

<h2>One Abstraction, Two Uses</h2>

<p>What is a file?  Over the last year, I've asked a number of people that, from computer scientists to technophobes.  None has managed to give me a clear answer.  The next question I asked is 'What is a document?'  Everyone I asked gave me a clear answer.</p>

<p>From a user interface perspective, it's clear that a document is a better abstraction than a file.  A file is a very convenient abstraction for operating systems; it's basically a virtualised block device with a simple text key (the path/filename) that can be used to uniquely identify it.  It is not a good abstraction for users.</p>

<p>Files are used for two things:</p>

<ul>
<li>Storing a document.
<li>Publishing a document.
</ul>

<p>From a user interface perspective, these are very different tasks.  Storing a document is not something that should ever need to be done explicitly.  Raskin's first law states:</p>

<blockquote>
A program shall not harm a user's data, or through inaction allow the user's data to come to harm.
</blockquote>

<p>Everything I do to a document should automatically be stored if possible.  In some situations, such as sudden power failure, some data loss is inevitable, but the program should do everything it can to minimise the chance of avoidable data loss.  A simple corollary to this is that versioning information should also be stored.  If I hit select all, delete, then I don't want the stored form of my document to be overwritten with an empty document.  I want an undo feature, and I don't want this to be contingent on keeping the document in memory (select all, delete, {autosave}, power failure, panic).</p>

<p>CoreObject's serialisation function does this.  You don't need to explicitly save a document.  From the time an application tells CoreObject to manage the object graph representing the document model, you have the ability to replay every single change you've made to it (this actually works in the version in /trunk now, although it needs more testing).</p>

<p>While you don't have to save a document explicitly, you might want to tag it with some metadata.  Some of this will be created automatically for all objects (creation dates, modification dates, etc).  Some will be created automatically for certain object types (e.g. colour depth, word count, table of contents).  Some can be specified manually.  This will be indexed by the higher layers of CoreObject.  These tags can either be assigned to a specific version, or to the latest version.  You might tag a book you are working on with the book title, and also tag the version you sent to the proof readers, so you can jump back to that one to compare with the comments they gave you.</p>

<p>Publishing is a very different problem.  When you publish a document, you typically don't want to include revision information, you want a snapshot.  A few government agencies have been embarrassed in recent years by forgetting that Word Documents are intended for storing, not publishing, and include a lot of revision information.</p>

<p>How does CoreObject help with the publishing?  Well, the current implementation doesn't (yet), but the plan is to integrate something like Apple's UTI (or, more likely, UTI itself).  This is a type hierarchy supporting multiple inheritance that is orthogonal to the object hierarchy.  Each compliant object will publish a number of types that is inherits from, such as rich text, or image.  It will also support exporting its contents as each of these.  For complex compound documents, the root document will simply query the enclosed components, and assemble a composite of images, text etc.  Each object only needs to be able to export to something one layer up the type hierarchy.  For example, a word processor might export as rich text, and the system would then convert this to text using a shared component.</p>

<h2>What About My Friends</h2>

<p>The other important feature of CoreObject is collaboration, which is central to the Étoilé vision.  CoreObject's serialisation of invocations allows these to be sent across any kind of network connection.  In 0.3, there will be a XML-over-XMPP system for this.  This will stream changes between two (or, in theory, more) users as they are made.  Some systems exist for doing this in very specific cases, such as SubEthaEdit for text and a few whiteboarding solutions for images.  CoreObject will allow us to do this in the general case.  Any document that works with CoreObject will be able to be shared in this way.</p>

<p>Because it only sends the deltas, this approach will scale to relatively large object types.  Imagine something like a raw digital photograph.  These can easily be several tens of megabytes.  The changes made to them, however, are usually of the form 'alter the brightness level by 5%,' or 'apply this filter with these parameters.'  These are not very big, and so once the photograph is initially shared, it can be tweaked in a collaborative fashion easily.</p>

<p>This is even true of video editing.  Something like Apple's Final Cut does non-destructive editing.  While the source footage is often tens of gigabytes, the project file is very small, since all it contains are instructions like 'take insert ten seconds from source file x at y in the timeline,' and 'cross fade for 10 seconds.'  With CoreObject, we get this kind of non-destructive editing for free, and we also get the ability to collaborate on documents like this for free.  We could have two people editing the same video on their own machines and having the changes automatically kept in sync.  Once it's done, they export it as something like MPEG-4, and anyone can view it irrespective of whether they're using Étoilé.</p>

<div style="clear:both; padding-bottom:0.25em"></div>

<p class="blogger-labels">Labels: <a rel='tag' href="http://www.etoile-project.org/etoile/blog/labels/CoreObject.html">CoreObject</a></p>

<!--COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/15634679125191713463" rel="nofollow">Karl Bartel</a>
COMMENT-DATE:9:36 PM
COMMENT-BODY:Nice writeup. This makes the motivation a lot more clear. I especially like the clear distinction between storing and publishing a document.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/06908257758689326780" rel="nofollow">Martijn</a>
COMMENT-DATE:2:42 PM
COMMENT-BODY:Very interesting.. and even cooler that some code has already been written. Really cool that Etiole is more than the Mac OS X clone people claim it to be.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/02426200026757544490" rel="nofollow">Jan</a>
COMMENT-DATE:6:57 PM
COMMENT-BODY:Would this also be used to represent things that are traditionally not really files? I'm thinking of people in my address book, e-mails, meetings in my calendar, ...

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/06582362579394220260" rel="nofollow">Jesse Ross</a>
COMMENT-DATE:8:14 PM
COMMENT-BODY:jan: Yep, that's part of the plan. Perhaps David could clarify the technical details, but we're definitely aiming towards having all of those items you listed above, as well as some others, represented by objects. <BR/><BR/>Additionally, having all of those items represented as objects should allow them to reference one another in a CoreObject database. For example, this would let you could generate a list of all the documents on your system you've ever sent (via IM or email or otherwise) to a particular person, or let you query the phone number of the person you're meeting for lunch next Tuesday (and, once we have a phone app available, automatically start a call with them).<BR/><BR/>The ability to build relationships between all of these items once we have them in a standard format is another great advantage of using something like CoreObject.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:8:31 AM
COMMENT-BODY:Well very good, however, don't be surprised if any apple "engineer" is having a look of Etoile development and they will come in the next release with Etolie ideas and then they pattent this

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/06582362579394220260" rel="nofollow">Jesse Ross</a>
COMMENT-DATE:10:03 AM
COMMENT-BODY:Well, now we have dated prior art :)

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/01837547991064791020" rel="nofollow">Joe</a>
COMMENT-DATE:12:27 AM
COMMENT-BODY:Will any of this be x-plat compatible with OS X? This sounds like an awesome architecture and solves a number of distributed editing issues that are not limited to just Etoile.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/15601204803374423591" rel="nofollow">Chmeee</a>
COMMENT-DATE:1:05 AM
COMMENT-BODY:CoreObject looks to be a lot like what I'm trying to do with my new operating system, only further along than what I have.  I'm glad I'm not the only one who sees problems with files as the only abstraction currently available to users.<BR/><BR/>I read through the source of EtoileSerializer and noticed that you're using URLs as the identifier.  Do you have any plans to make it instead more database driven, and associative between objects instead of objects with names?  (e.g. identifying an object by an icon rather than by a name)  That's my ultimate goal, and would be interesting to hear your thoughts on such.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/06582362579394220260" rel="nofollow">Jesse Ross</a>
COMMENT-DATE:5:39 AM
COMMENT-BODY:chmeee: I can't speak for David and his plans, but I do know that <I>I've</I> expressed a strong desire that documents not be required to have names. A good example of when this would be useful would be for photos from a digital camera. Currently digital cameras give photos arbitrary sequential names, which mean nothing to a user. In that case, the name is a worthless piece of data, since the user would likely identify a particular image based on a thumbnail of it anyway.<BR/><BR/>If the user does want to add a name for the document, my suggestion is that it be treated as optional metadata, like labels, comments, tags or any other piece of metadata.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/06412453076777492155" rel="nofollow">diroussel</a>
COMMENT-DATE:8:34 AM
COMMENT-BODY:This discussion strongly reminds me of distributed version control systems GIT and Mercurial.<BR/><BR/>It would be worth looking at how they do naming, and how they achieve such high performance.<BR/><BR/>Not that GIT is content addressable, the files are named after the SHA-1 of the binary contents, plus a tiny header.  That can be how you name a picture.<BR/><BR/>If you want to keep the same name for different versions, then you'll need a slightly different approach.  Perhaps using the SHA-1 of the initial version.<BR/><BR/>You can keep this consistent with using URLs by using a SHA-1 hash of the URL as an internal name, and the URL as the human readable name.<BR/><BR/>I really like the idea of distributed version control and undo/redo levels coming together as one comcept.<BR/><BR/>David

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">pirit</span>
COMMENT-DATE:1:52 PM
COMMENT-BODY:For inspiration about the intersection of undo and version control, you should check out this article about the text editor called 'e': <A HREF="http://e-texteditor.com/blog/2006/making-undo-usable" REL="nofollow">Making undo usable</A>.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon blogger-comment-icon"><img src="http://www.blogger.com/img/b16-rounded.gif" alt="Blogger" style="display:inline;" /></span>&nbsp;<a href="http://www.blogger.com/profile/16578819125635628256" rel="nofollow">David Chisnall</a>
COMMENT-DATE:4:23 PM
COMMENT-BODY:Hi Everyone, Blogger doesn't poke me when people comment here, so I hadn't seen there were so many thing to reply to.<BR/><BR/>jan: Yes, everything can be stored by CoreObject.  One of the first uses will probably be the presence log in StepChat.  Currently, it doesn't preserve this log, but I intend to use it as one of the first test cases for CO.  Anything that's represented as Objective-C objects can be stored by CO.<BR/><BR/>Jesse: Each CO-managed document[1] will have a globally unique ID, which can be referenced elsewhere.<BR/><BR/>Anonymous: Apple have something of a history of patenting things I thought of a few years earlier and didn't get around to publishing or exploiting.  Part of the reason for this blog is so I have a record of prior art.  <BR/><BR/>Joe: The code is tied very heavily to the GNU Objective-C runtime.  It would be possible to implement ETSerialiser and ETDeserialiser for the Apple / NeXT runtime, but I don't plan to.  The other problem is that most CO-stored objects will contain serialised Foundation objects, and these won't be compatible with different implementations of Foundation (Apple / GNUstep / libfoundation).  It would be possible to write a bridge but, again, I have no plans to.  If someone else does, then I have no problem with it going in the repository, and I will make an effort not to change any interfaces in ways that break either of them.<BR/><BR/>chmeee: URLs are just location IDs.  They are used by EtoileSerialise, but won't be used much by the user-visible parts of CO.  The user will be able to set the storage location for a document to either options like 'local disk' 'removable disk' or 'Remote URL,' but most of the time they will just leave these set to their default value and CO will handle the storage.  The URLs point to documents  How objects within these documents are accessed is up to the back end.  At the end of the day, there needs to be some way of identifying the blob where the data is stored, and that's what the URLs are for.  They are not intended to be user-visible, unless it makes sense to do so (for example setting a WebDAV or FTP server as your document repository).  One of the higher levels of CO will maintain a UUID to URL mapping.  Most code will only bother storing the UUID, and leave it up to CO to handle the translation.  One thing I'd like to do is write a CO back end that uses ZFS storage pools directly (no filesystem) and lets CO handle all of the metadata, without translating it via POSIX metadata.<BR/><BR/>Jesse (again): I completely agree.  File names as unique identifiers don't make sense.  File names as just another kind of arbitrary metadata do[2].  <BR/><BR/>diroussel: The idea of using SHA-1 hashes is fairly obvious.  I came up with the same solution a couple of years ago for use on another research project run by my PhD supervisor.  The implementation I proposed then also supported fine-grained encryption, including a mechanism for multi-user access to encrypted files without needing to trust the server.  CO is, in part, an extension of some of the ideas I had while thinking about this project, and so I wouldn't be surprised if they show up again in some form or other.<BR/><BR/>pirit: Interesting article.  I think the only feature I hadn't planned already was the visualisation (in spite of my PhD title, I don't think visually at all, so I often miss this kind of thing).  It's a very nice idea though.  We could possibly do this by adding a method like this to COProxy:<BR/><BR/>- (NSString*) visualiseInvocation:(NSInvocation*)anInvocation;<BR/><BR/>By default, this would return the selector name interspersed with the string value of the arguments (so you'd get something like 'appendString:foo' out of it).  Document-specific subclasses of COProxy could override this to provide something a bit more human-friendly.  <BR/><BR/>[1] It's important to distinguish between objects and documents, even though I use the terms interchangeably quite often.  EtoileSerialise stores object <I>graphs</I>.  Each graph has a principle object, but also stored are all the other objects referenced by this object.  While I talk about CO storing objects, it is really storing documents encapsulated in object graphs.<BR/><BR/>[2] I consider this to be the one design flaw of BFS.  It treated metadata indexes as a special case of directories, rather than treating directories as a special case of metadata indexes.  A directory is just an index of all files where the 'parent' metadata entry is a specific value.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:9:38 PM
COMMENT-BODY:Re:I asked is 'What is a document?' Everyone I asked gave me a clear answer.<BR/><BR/>I doubt the clear answer actually included a complete document history. That is undoubtedly a nice-to-have, not a must-have. Other than that, a nice presentation. Congratulations.

COMMENT-AUTHOR:<span style="line-height:16px" class="comment-icon anon-comment-icon"><img src="http://www.blogger.com/img/anon16-rounded.gif" alt="Anonymous" style="display:inline;" /></span>&nbsp;<span class="anon-comment-author">Anonymous</span>
COMMENT-DATE:5:23 PM
COMMENT-BODY:Will object instances implement interfaces<BR/>or will objects be instances of classes that implements interfaces?<BR/><BR/>How do you plan on handling evolution of inerfaces and implementations? I.e. forward and backward compatibility.<BR/><BR/>What kind of type syste will the system support? Static, dynamic, strong, weak? Will it be fixed to the system or can it be extended? -->
]]></content>
</entry>

<entry>
<title>First Steps into Étoilé and GNUstep Programming</title>
<link rel="alternate" type="text/html" href="http://etoileos.com/news/archive/2007/07/20/1300/"/>
<author><name>Quentin Mathé</name></author>
<id>http://etoileos.com/news/archive/2007/07/20/1300/</id>
<updated>2007-07-20T13:00:00-07:00</updated>
<content type="html"><![CDATA[<p>If you are interested to contribute to Étoilé directly or by writing your own applications, I have compiled below some resources to learn GNUstep programming…</p>

<p>The best resource for Objective-C development with Cocoa/GNUstep frameworks is Apple documentation in my opinion. Cocoa documentation is now excellent, but don't forget GNUstep isn't always in sync with Cocoa and Carbon stuff isn't available on GNUstep platforms.</p>

<p>To begin the best is probably to read the following Apple guide: <a href="http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaFundamentals/index.html">Cocoa Fundamentals</a>.</p>

<p>On GNUstep website, visit <a href="http://gnustep.org/developers/documentation.html">Developer documentation area</a>.
From this documentation, you should read <a href="http://gnustep.org/resources/documentation/Developer/Make/Manual/make_toc.html">gnustep-make documentation</a>. Take note it isn't really exhaustive and doesn't cover the new stuff brought by latest release 2.0.
<a href="http://gnustep.org/resources/documentation/Developer/Base/ProgrammingManual/manual_toc.html">Base Programming Manual</a> can be worth to read. It details a bit some GNUstep specific extensions like Documentation system, logging etc. and includes a very good overview of Distributed Objects with real examples.</p>

<p>GNUstep API references:</p>

<ul><li><a href="http://gnustep.org/resources/documentation/Developer/Base/Reference/index.html">Foundation</a></li>
<li><a href="http://www.gnustep.org/resources/documentation/Developer/BaseAdditions/Reference/index.html">Foundation Additions</a>… This is the place where you can find documentation on XML support and Runtime utility functions.</li>
<li><a href="http://www.gnustep.org/resources/documentation/Developer/Tools/Reference/index.html">Foundation Tools</a>… Important place where <a href="http://www.gnustep.org/resources/documentation/Developer/Tools/Reference/gsdoc.html">GNUstep Documentation system</a> (aka GSDoc) with the related tool <a href="http://www.gnustep.org/resources/documentation/Developer/Tools/Reference/autogsdoc.html">autogsdoc</a> is explained.</li>
<li><a href="http://gnustep.org/resources/documentation/Developer/Gui/Reference/index.html">AppKit</a></li></ul>

<p><a href="http://cocoadevcentral.com/">Cocoa Dev Central</a> is a good place to start with plenty of nice tutorials too.</p>

<p>Here are other very good