<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Maciej Piechotka&#039;s Blog</title>
	<atom:link href="http://blog.piechotka.com.pl/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.piechotka.com.pl</link>
	<description>Maciej Piechotka&#039;s Blog</description>
	<lastBuildDate>Sat, 18 May 2013 21:32:25 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='blog.piechotka.com.pl' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Maciej Piechotka&#039;s Blog</title>
		<link>http://blog.piechotka.com.pl</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://blog.piechotka.com.pl/osd.xml" title="Maciej Piechotka&#039;s Blog" />
	<atom:link rel='hub' href='http://blog.piechotka.com.pl/?pushpress=hub'/>
		<item>
		<title>Vala ABI and branch prediction</title>
		<link>http://blog.piechotka.com.pl/2013/05/18/vala-abi-and-branch-prediction/</link>
		<comments>http://blog.piechotka.com.pl/2013/05/18/vala-abi-and-branch-prediction/#comments</comments>
		<pubDate>Sat, 18 May 2013 21:32:24 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[GNOME]]></category>
		<category><![CDATA[GNU/Linux]]></category>
		<category><![CDATA[Libgee]]></category>
		<category><![CDATA[assembler]]></category>
		<category><![CDATA[optimisation]]></category>
		<category><![CDATA[vala]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=110</guid>
		<description><![CDATA[Maintaining Libgee for some time I run into interesting phenomena &#8211; performance did not behave in a way most people would expect. When the highier-order functions were planned it was pointed out that Vala doesn&#8217;t have complex inlining required for fast usage of higher-order functions. As shown by previous link the reverse is true. In [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=110&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Maintaining <a href="https://live.gnome.org/Libgee" title="Libgee - GObject collection library">Libgee</a> for some time I run into interesting phenomena &#8211; <a href="https://bugzilla.gnome.org/show_bug.cgi?id=645850#c4" title="Highier-order functions faster then simple iteration">performance did not behave in a way most people would expect</a>. When the highier-order functions were planned it was pointed out that <a href="https://live.gnome.org/Vala" title="Vala - Compiler for the GObject type system">Vala</a> doesn&#8217;t have complex inlining required for fast usage of higher-order functions.</p>
<p> As shown by previous link the reverse is true. In hindsight it seems to be clear that source of discrepancy is due to shorthands we employed while analyzing the performance.</p>
<p><span id="more-110"></span></p>
<h3>Why do we need the branch prediction</h3>
<p>The simplest way of thinking about processor is as machine executing one instruction at a time. While this is very simple description it doesn&#8217;t allow fast computation. Usually there is several stages which can work independently or semi-independently and the processor is <a href="http://en.wikipedia.org/wiki/Instruction_pipeline" title="Instruction pipeline">similar to assembly line (pipeline)</a> of data. Since each discrete stage needs to fit inside 1 cycle finer splitting allows faster clock rate &#8211; and larger throughput (this is simplified view as current processors are superscalar and out-of-order.</p>
<p>There are however few things that prevents reaching the theoretical maximum performance (other then bottlenecks outside processor) called hazard. Consider following program (in pseudo-assembly):</p>
<pre class="brush: plain; title: ; notranslate">
    mov [r0], r0
    jz r0, label
    mov [r1], r0
label:
    add r0, 1, r1
</pre>
<p>The processor does not know how to proceed after line 2. The simples resolution of a hazard is to stall (do nothing until it is known how to resolve the problem). However in many cases the processor can guess (predict) how to proceed &#8211; it requires a bit of bookkeeping in order to maintain consistent state when it fails to guess but it avoids just waiting on solution.</p>
<h3>Openness and branch prediction</h3>
<p>Traditionally the branches were quite simple &#8211; either a branch was taken or not taken. Since the direction of the branch was quite simple (1 bit) it allowed a number of smart methods:</p>
<ul>
<li>Counting the number when the branch is taken or not taken &#8211; we guess the branch which was taken most frequently in past.</li>
<li>Considering the history. It is possible to take say 5 past choices of taken/not taken and use it as part of address. It gives performance as single method might be called from 2 different places and have different branching depending on way it is called.</li>
</ul>
<p>However on modern processors (in practice &#8211; any produced during past 30 years or so) we can jump in any place in the code by function pointer:</p>
<pre class="brush: cpp; title: ; notranslate">
int main() {
    // f is pointer to some function
    int (*f)() = getF();
    f();
}
</pre>
<p>The style of calling an unknown function is currently very common &#8211; the method call depend on the data that is passed to function instead of place of such call. From processor point of view the virtual method calls, calling closure etc. are calling an arbitrary address. Now instead of potentially two outcomes of branching there can be arbitrary number of them. While usually processors guess that the last taken branch will be taken this time I have not heard about processors  doing anything more complicated (the history considered is still from traditional taken/not taken branches from what I understand</p>
<p>Usually the functional and object-oriented languages deal with the problem in various ways. For example they can employ data/control-flow analysis to check what types can occur at give pointers &#8211; example from C:</p>
<pre class="brush: cpp; title: ; notranslate">
struct A {
    virtual int f() = 0;
};

struct B : A {
    int f() __attribute__((noinline)) {
        return 0;
    }
};

struct C : A {
    int f() {
        return 1;
    }
};

int main() {
    B b;
    A *a = &amp;b;
    return a-&gt;f();
}
</pre>
<p>The gcc can see that nothing but <code>B</code> can be pointed by <code>a</code>. Hence he calls the <code>B::f</code> directly.</p>
<pre class="brush: plain; title: ; notranslate">
	.file	&quot;test.cc&quot;
	.section	.text._ZN1B1fEv,&quot;axG&quot;,@progbits,_ZN1B1fEv,comdat
	.align 2
	.p2align 4,,15
	.weak	_ZN1B1fEv
	.type	_ZN1B1fEv, @function
_ZN1B1fEv:
.LFB0:
	.cfi_startproc
	xorl	%eax, %eax
	ret
	.cfi_endproc
.LFE0:
	.size	_ZN1B1fEv, .-_ZN1B1fEv
	.section	.text.startup,&quot;ax&quot;,@progbits
	.p2align 4,,15
	.globl	main
	.type	main, @function
main:
.LFB2:
	.cfi_startproc
	leaq	-24(%rsp), %rdi
	jmp	_ZN1B1fEv
	.cfi_endproc
.LFE2:
	.size	main, .-main
	.ident	&quot;GCC: (Gentoo 4.7.2-r1 p1.4, pie-0.5.5) 4.7.2&quot;
	.section	.note.GNU-stack,&quot;&quot;,@progbit
</pre>
<p>However such techniques are (usually) not employed by C compilers as in many cases programmers can go behind its back and change the function pointers &#8211; even if programmers know it won&#8217;t be changed.</p>
<h4>Note about symbols</h4>
<p>Potential source of openness is symbol resolution. If the symbol can be outside library the resolution goes through <abbr title="Procedure Linkage Table">PLT</abbr>. If <code>f</code> was shared function `int main() {return f ();}` would compile into:</p>
<pre class="brush: plain; title: ; notranslate">
	.file	&quot;test-plt.c&quot;
	.text
	.globl	f
	.type	f, @function
f:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	f, .-f
	.globl	main
	.type	main, @function
main:
.LFB1:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	$0, %eax
	call	f@PLT
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE1:
	.size	main, .-main
	.ident	&quot;GCC: (Gentoo 4.7.2-r1 p1.4, pie-0.5.5) 4.7.2&quot;
	.section	.note.GNU-stack,&quot;&quot;,@progbits
</pre>
<p>The <code>f@PLT</code> is small function which calls appropriate function according to resolution. In general resolve to one additional indirect jump which can be perfectly predictable after first two misses. On x86 (32-bit version) due to technical limitations there is one additional direct jump. The detailed description is in Ulrich Drepper&#8217;s guide<a href="http://www.akkadia.org/drepper/dsohowto.pdf" title="How To Write Shared Libraries">&#8220;How To Write Shared Libraries&#8221;</a>.</p>
<h4>A note about real performance</h4>
<p>Measurement of the problems which can arise can be quite tricky. The modern processors and compilers can be quite smart and microbenchmarking of instruction can be fight against it while at the same time for the result to be meaningful there is need to exploit them.</p>
<p>I tried to use following code in my test:</p>
<pre class="brush: cpp; title: ; notranslate">
#include &lt;stdint.h&gt;
#include &lt;stdio.h&gt;
#include &lt;time.h&gt;
#include &lt;inttypes.h&gt;
#include &lt;math.h&gt;

static void f() __attribute__((noinline));
static void g() __attribute__((noinline));
 
static void f() {
    __asm__ __volatile__ (&quot;&quot;);
    return;
}
 
static void g() {
    __asm__ __volatile__ (&quot;&quot;);
    return;
}
 
 
typedef void (*fptr_t)();
 
#ifndef DIRECT
#ifdef CHANGE
static void swap(fptr_t *f, fptr_t *g) {
  fptr_t tmp = *f;
  *f = *g;
  *g = tmp;
}
#endif
#endif
 
#ifdef VOLATILE
#define LOAD_FPTR(n) \
  volatile fptr_t n ## ptr = n
#else
#define LOAD_FPTR(n) \
  static volatile fptr_t n ## ptr_static = n; \
  fptr_t n ## ptr = n ## ptr_static
#endif
 
int main() {
#ifndef DIRECT
  LOAD_FPTR(f);
#ifdef CHANGE
  LOAD_FPTR(g);
#endif
#else
    fptr_t fptr = f;
#ifdef CHANGE
    fptr_t gptr = g;
#endif
#endif
 
#ifndef TRIES
#define TRIES 10
#endif
    double times[TRIES];
    for (uint64_t j = 0; j &lt; TRIES; j++) {
        struct timespec start, end;
        clock_gettime (CLOCK_THREAD_CPUTIME_ID, &amp;start);
        for (uint64_t i = 0; i &lt; UINT64_C(0xFFFFFFF); i++) {
#ifndef CHANGE
            fptr();
#else
#ifndef DIRECT
            swap (&amp;fptr, &amp;gptr);
            fptr();
#else
            uint64_t f_or_g;
            asm (&quot;and $1, %0&quot; : &quot;=r&quot;(f_or_g) : &quot;0&quot;(i));
            if (f_or_g) {
                fptr();
            } else {
                gptr();
            }
#endif
#endif
        }
        clock_gettime (CLOCK_THREAD_CPUTIME_ID, &amp;end);
        times[j] = (end.tv_sec - start.tv_sec) + 1e-9*(end.tv_nsec - start.tv_nsec);
        printf(&quot;Time[%&quot; PRIu64 &quot;] = %f\n&quot;, j, times[j]);
    }
    double mean = 0.0;
    double mean2 = 0.0;
    for (int j = 0; j &lt; TRIES; j++) {
        mean += times[j]/TRIES;
        mean2 += (times[j] * times[j])/TRIES;
    }
    double stdev = sqrt(mean2 - mean * mean);
    printf(&quot;Mean  = %f\n&quot;, mean);
    printf(&quot;Stdev = %f\n&quot;, stdev);
    return 0;
}
</pre>
<table>
<thead>
<tr>
<th colspan="3">Type</th>
<th>Mean</th>
<th>Standard deviation</th>
<th>Notes</th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="3">Type</th>
<th>Mean</th>
<th>Standard deviation</th>
<th>Notes</th>
</tr>
</tfoot>
<tbody>
<tr>
<th rowspan="2">Direct jump</th>
<th colspan="2">Same location</th>
<td>0.540</td>
<td>0.036</td>
<td>This just measures the overhead of direct jump</td>
</tr>
<tr>
<th colspan="2">Alternating locations</th>
<td>0.524</td>
<td>0.031</td>
<td>All it does is add additional jump which can be predicted by history</td>
</tr>
<tr>
<th rowspan="4">Indirect jump</th>
<th rowspan="2">Same location</th>
<th>From register</th>
<td>0.459</td>
<td>0.031</td>
<td>The indirect jump which can be predicted and is known</td>
</tr>
<tr>
<th>From memory</th>
<td>0.459</td>
<td>0.029</td>
<td>This corresponds to Vala call which can be predicted</td>
</tr>
<tr>
<th rowspan="2">Alternating locations</th>
<th>From register</th>
<td>1.570</td>
<td>0.035</td>
<td>This corresponds to mis-predicted indirect jump</td>
</tr>
<tr>
<th>From memory</th>
<td>2.080</td>
<td>0.033</td>
<td>This is mis-predicted Vala call</td>
</tr>
<tbody>
</table>
<p>The table is closer to rough guide than any realistic simulation. For example many Vala virtual calls have 2 indirect jumps and the last row have additional stores to the memory.</p>
<h3>How does Vala fit into it</h3>
<p>Vala uses GObject under the hood and it was to some extend constraint by it. It needs to fit into existing ABI of libraries written in GObject/C. Since the methods were implemented in C by function pointers it is what done by Vala. However by transition the benefits of more complicated optimizations are lost &#8211; the C can no longer optimize the code. However using the open style (with methods) is more encouraged in Vala then C.</p>
<pre class="brush: csharp; title: ; notranslate">
List&lt;int&gt; list = new ArrayList&lt;int&gt;();
list.add(0);
// In C++ the add could point directly to ArrayList::add
// In Vala we do the indirect call
</pre>
<p>Even if the analysis was implemented in Vala the optimization could not be easily implemented without tweaks to detect the ABI. It would not be impossible to simply export <code>gee_array_list_add</code> to allow compiler to look up the correct function and use it directly. As it changes the ABI the classes would need to be explicitly annotated.</p>
<p>Other problem present in Vala is the abstract classes deriving from interfaces. If class overrides a method of such interface currently the following happens:</p>
<ol>
<li>Interface method resolution function (my own naming &#8211; not a standard one) is called &#8211; 1 direct jump</li>
<li>The interface vtable is looked up (memory load) and from it is read a location of abstract class resolution function &#8211; 1 indirect jump</li>
<li>The abstract class vtable is looked up (memory load) and from it the real function is executed &#8211; 1 indirect jump</li>
<li>The real method is executed</li>
</ol>
<p>In total it is 2 indirect jumps (depending on memory load) and 1 direct jump. There seems to be at least 2 ways of improving it:</p>
<ul>
<li>
<p>Instead of overriding just the abstract class the child class might simply reimplement the interface under the hood thus allowing to directly jump to the method. It seems to be possible given existence of <a href="https://developer.gnome.org/gobject/stable/gobject-Type-Information.html#g-type-interface-peek-parent" title="g_type_interface_peek_parent"><code>g_type_interface_peek_parent</code></a>.</p>
<p>As the interface implementation can be per-derived class instead of one per hierarchy the pointer to real implementation can be inserted into the vtable. This allows to skip the detour via abstract class resolution function and one indirect call saving some time.</p>
</li>
<li>
<p>While technically not fully compatible with GObject it is possible to directly resolve the method from outside the class. Consider following loop:</p>
<pre class="brush: csharp; title: ; notranslate">
List&lt;int&gt; list = ...
for (int i = 0; i &lt; list.size; i++) {
    do_something (list.get (i));
}
</pre>
<p>It would be compiled into something roughly corresponding to:</p>
<pre class="brush: csharp; title: ; notranslate">
GeeList list = ...
for (int i = 0; i &lt; gee_list_get_size (list); i++) {
    int tmp = gee_list_get (i);
    do_something (tmp);
}
</pre>
<p>Instead it would be possible to simply get the function pointers for the <code>gee_list_get_size</code> and <code>gee_list_get</code> &#8211; chances are that register won&#8217;t be saved on stack and they would be used right away. In following code it might not do much difference but it more complicated ones it might make an impact.</p>
</ul>
<h3>Conclusion</h3>
<p>Control flow may have an impact on the performance of the program. Usually the compiler, JIT and natural flow of language directs to certain usage-patterns which can be exploited. Unfortunately Vala doesn&#8217;t have many optimizations implemented (at least yet) and they cannot be done by C compiler.</p>
<p>In many cases people either don&#8217;t care about performance (does it matter if calculator displays result in few 17 ms faster?). Once people <strong>are</strong> interested in performance they can <a href="http://research.scee.net/files/presentations/gcapaustralia09/Pitfalls_of_Object_Oriented_Programming_GCAP_09.pdf" title="Pitfalls of Object Oriented Programming">start optimizing even if it is not natural way in a language</a> (for example struct of arrays in C/C++). It is worth to keep in mind for such case that Vala does not optimize the virtual calls as much as C++ or Java.</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/gnulinux/gnome/'>GNOME</a>, <a href='http://blog.piechotka.com.pl/category/gnulinux/'>GNU/Linux</a>, <a href='http://blog.piechotka.com.pl/category/gnulinux/gnome/libgee/'>Libgee</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/assembler/'>assembler</a>, <a href='http://blog.piechotka.com.pl/tag/optimisation/'>optimisation</a>, <a href='http://blog.piechotka.com.pl/tag/vala/'>vala</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/110/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/110/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=110&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2013/05/18/vala-abi-and-branch-prediction/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
		<item>
		<title>Don&#8217;t write your own build system</title>
		<link>http://blog.piechotka.com.pl/2013/04/13/dont-write-your-own-build-system/</link>
		<comments>http://blog.piechotka.com.pl/2013/04/13/dont-write-your-own-build-system/#comments</comments>
		<pubDate>Sat, 13 Apr 2013 11:31:17 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[autotools]]></category>
		<category><![CDATA[build system]]></category>
		<category><![CDATA[make]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[shake]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=132</guid>
		<description><![CDATA[The title might be a bit controversial but at least it is catchy one. Recently I&#8217;ve seen a few posts about Shake, a make replacement with several improvements (such as more flexible dependency specification). There are also examples how to use it with say Vala. The problem is that the Make and Shake are both [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=132&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>The title might be a bit controversial but at least it is catchy one. Recently I&#8217;ve seen a few posts about <a href="http://hackage.haskell.org/package/shake" title="Shake">Shake</a>, a make replacement with several improvements (such as more flexible dependency specification). There are also <a href="http://lethalman.blogspot.com/2013/04/build-vala-applications-with-shake.html" title="Build Vala applications with Shake build system">examples how to use it</a> with say <a href="https://live.gnome.org/Vala/" title="Vala - Compiler for the GObject type system">Vala</a>.</p>
<p>The problem is that the <a href="http://en.wikipedia.org/wiki/Make_(software)" title="Make">Make</a> and Shake are both rather quite low-level tools and while improvement in them <em>is</em> beneficial shake, at least currently, is not a replacement for <a href="http://en.wikipedia.org/wiki/GNU_build_system" title="GNU build system">autotools</a> or <a href="http://www.cmake.org/" title="CMake">CMake</a>.</p>
<p><span id="more-132"></span></p>
<p> There are number of things user might want to do with build system, which would need to be manually added to make or shake script:</p>
<ul>
<li><code>CC</code>, <code>CXX</code>, <code>VALAC</code>, <code>CFLAGS</code>&#8230; environment variables to allow fine-tuning the compilation by user (or developer who wants to for example test with <a href="http://clang.llvm.org/" title="clang: a C language family frontend for LLVM">clang</a> instead of <a href="http://gcc.gnu.org/" title="GCC, the GNU Compiler Collection">gcc</a>).</li>
<li>Personalizing the prefix to put program in right place (usually <code>/usr/local</code> is used for program compiled by source but it is often not accessible by users)</li>
<li>Installing in different root hierarchy steered by <code>DESTDIR</code>. This is different from prefix as latter denotes where program is run from while this variable locates a root (/) location during install time. This is used mostly for creating packages.</li>
<li><code>distcheck</code> which allows to create tarballs, build from them, run tests etc.</li>
<li>Cross-compilation</li>
<li>Compile dynamic libraries on whatever platform I&#8217;m on, handling all complexity (correct flags &#8211; say <code>-fPIC</code>, tools, &#8230;)</li>
<li>Build in separate build directory (useful for cross-compilation)</li>
<li>&#8230;</li>
</ul>
<p>Those features are not explicitly supported by Make or Shake as they are more low-level tools &#8211; which is fine if we treat them as such and use other libraries or tools automating the compiling and linking (I haven&#8217;t seen anyone claiming Shake is anything more, but it is good to keep in mind that build systems can grow quite complex while using it). However for a tool to be usable for wide range of users there should be provided &#8211; preferably with consistent interface with existing tools as it makes the integration easier with other tools (say portage) and does not require user to relearn the specifics. Unfortunately most make tutorials (and shake) omit those problems. It can be fine if we made some assumptions &#8211; say we have closed environment (so the need is to integrate with internal tools and only them, specific installation etc.) or we know that we need to provide those features. However it can cause problems if they do appear in published repository.</p>
<p>The <q>own build system</q> therefore is not the Make or Shake but rather systems built on top of them. My guess is that when someone knows the full requirements of a build system than writing more highier-level library on top of Shake should be relativly simple (as it&#8217;s <a href="http://www.haskell.org/haskellwiki/Embedded_domain_specific_language" title="Embedded Domain Specific Language">EDSL</a>) &#8211; however it is harder then it looks like.</p>
<p><strong>PS.</strong> While looking for links to the post I&#8217;ve (re)read <a href="http://blog.flameeyes.eu/2008/10/good-developers-dont-necessarily-create-good-build-systems" title="Good developers don't necessarily create good build systems">similar post</a>.</p>
<p><strong>PPS.</strong> The draft version of this post was accidentally published. Sorry for confusion.</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/programming/'>Programming</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/autotools/'>autotools</a>, <a href='http://blog.piechotka.com.pl/tag/build-system/'>build system</a>, <a href='http://blog.piechotka.com.pl/tag/make/'>make</a>, <a href='http://blog.piechotka.com.pl/tag/rant/'>rant</a>, <a href='http://blog.piechotka.com.pl/tag/shake/'>shake</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/132/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/132/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=132&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2013/04/13/dont-write-your-own-build-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
		<item>
		<title>Statically typed red-black trees</title>
		<link>http://blog.piechotka.com.pl/2013/04/10/statically-typed-red-black-trees/</link>
		<comments>http://blog.piechotka.com.pl/2013/04/10/statically-typed-red-black-trees/#comments</comments>
		<pubDate>Wed, 10 Apr 2013 10:53:47 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[haskell]]></category>
		<category><![CDATA[red-black tree]]></category>
		<category><![CDATA[static typing]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=116</guid>
		<description><![CDATA[I have met with claims that the static typing is useless as it is not mathematical proof (OK &#8211; for those knowing the discussion &#8211; I exaggerated a lot). However to large extend the static typing is prove of some sort and depending on the code it might be a prove of even quite strong [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=116&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I have met with claims that the static typing is useless as it is not mathematical proof (OK &#8211; for those knowing the discussion &#8211; I exaggerated a lot). However to large extend the static typing is prove of some sort and depending on the code it might be a prove of even quite strong properties.</p>
<p>As chosen field I tried to use <a href="http://www.cs.princeton.edu/~rs/talks/LLRB/LLRB.pdf" title="Left-Leaning Red Black Trees">LLRB</a> trees &#8211; I have implemented them <a href="https://mail.gnome.org/archives/vala-list/2009-March/msg00131.html" title="[Vala] [gee][patch] Left-leaning red-black tree implementation of set and map">quite long time ago</a> and I&#8217;ve run into problems <a href="http://read.seas.harvard.edu/~kohler/notes/llrb.html#trickywriting" title="Left-Leaning Red-Black Trees Considered Harmful">that violated the pre and post conditions</a>. Even when problem was discovered it took some time to find out the underlaying problems (my inexperience didn&#8217;t helped probably either)</p>
<p>I&#8217;ve tried to reimplement the code in GHC Haskell with following rules:</p>
<ul>
<li>Using only &#8216;safe&#8217; extensions</li>
<li>Making all functions total and without use of <code>undefined</code> or <code>error</code></li>
<li>Ensuring that all properties of tree are preserved</li>
</ul>
<p>Unfortunately this was my first time I used some of the concepts (like <a href="http://www.haskell.org/haskellwiki/Zipper" title="Zipper">Zipper</a>) so the implementation and description might be not the best (comments and corrections welcome).</p>
<p><span id="more-116"></span></p>
<p>I have used the code closer in structure to traditional implementations then the one described by Sedgewick. I don&#8217;t know the performance though as point was more to ensure the properties of the tree. It also includes both <a href="http://en.wikipedia.org/wiki/2-3_tree" title="2-3 tree">2-3</a> and <a href="http://en.wikipedia.org/wiki/2-4_tree" title="2-4 tree">2-4</a> implementation with latter one commented out.</p>
<p>While it took some time to implement it (for finding out how to convincing the type checker that (n + 1) + m = n + (m + 1)) it ensures the safety (and in total it have taken much less time then de debugging alone last time).</p>
<p><strong>WARNING!</strong> The code was written in hurry and while I have learned and I haven&#8217;t had time to clean it. It might contain strange variable names etc. It is also not written as efficient implementation but rather a proof of concept.</p>
<pre class="brush: plain; title: ; notranslate">
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE FlexibleContexts #-}
</pre>
<p> Above code is simply bunch of extentions that are used</p>
<pre class="brush: plain; first-line: 8; title: ; notranslate">
data Nat = Z | S Nat

type family Add (x :: Nat) (y :: Nat) :: Nat
type instance Add  Z     Z    = Z
type instance Add  Z     y    = y
type instance Add  x     Z    = x
type instance Add (S x) (S y) = S (S (Add x y))
</pre>
<p><code>DataKinds</code> extension allows to promote a type to a kind (type of type). The above code is simply an encoding of natural numbers on type level with addition</p>
<pre class="brush: plain; first-line: 16; title: ; notranslate">
data TaggedNat :: Nat -&gt; * where
  TaggedNat :: TaggedNat n

class NatHelper (n :: Nat) where
  nat :: (Z ~ n =&gt; a) -&gt; (forall n'. (S n' ~ n, NatHelper n') =&gt; TaggedNat n' -&gt; a) -&gt; TaggedNat n -&gt; a

instance NatHelper Z where
  nat z _ _ = z

instance NatHelper n =&gt; NatHelper (S n) where
  nat _ s _ = s (TaggedNat :: TaggedNat n)

data ChainNat :: Nat -&gt; * where
  ChainZero :: ChainNat Z
  ChainCons :: NatHelper n =&gt; ChainNat n -&gt; ChainNat (S n)

toChain :: NatHelper n =&gt; TaggedNat n -&gt; ChainNat n
toChain = nat ChainZero (ChainCons . toChain)

fromChain :: ChainNat n -&gt; TaggedNat n
fromChain ChainZero = TaggedNat
fromChain (ChainCons _) = TaggedNat

prev :: NatHelper (S n) =&gt; TaggedNat (S n) -&gt; (NatHelper n =&gt; TaggedNat n -&gt; a) -&gt; a
prev t x = case toChain t of
  ChainCons c -&gt; x $ fromChain c

addEq :: forall a n' m'. (NatHelper n', NatHelper m') =&gt;
         (Add n' (S m') ~ Add (S n') m' =&gt; a) -&gt;
         TaggedNat n' -&gt; TaggedNat m' -&gt;
         a
addEq x n m = nat (nat x (const x) m) (\n' -&gt; nat x (addEq x n') m) n
</pre>
<p>In general the type checker in Haskell is not a <a href="http://en.wikipedia.org/wiki/SMT_solver" title="SMT solver">SMT solver</a> (at least <a href="http://goto.ucsd.edu/~rjhala/liquid/haskell/blog/" title="Liquid Haskell">yet</a>). The above code provides prove of 2 properties:</p>
<ul>
<li>If we have <code>S n</code> (or n + 1) then n is a natural number.</li>
<li>Prove by induction (n + 1) + m = n + (m + 1). Unfortunately it currently is not optimized out despite my attempts to convince GHC by rules etc. that it is complex identity. If someone wanted to write the &#8216;real&#8217; code it might be a good spot to fix as it changes the complexity.</li>
</ul>
<pre class="brush: plain; first-line: 50; title: ; notranslate">
data BlackNode :: Nat -&gt; * -&gt; * where
  Nil :: BlackNode Z a
  BBNode :: BlackNode n a -&gt; a -&gt; BlackNode n a -&gt; BlackNode (S n) a
  RBNode :: RedNode n a -&gt; a -&gt; BlackNode n a -&gt; BlackNode (S n) a
--  RRNode :: RedNode n a -&gt; a -&gt; RedNode n a -&gt; BlackNode (S n) a

data RedNode :: Nat -&gt; * -&gt; * where
  RedNode :: BlackNode n a -&gt; a -&gt; BlackNode n a -&gt; RedNode n a
</pre>
<p>The above code defines the nodes. The second type parameter denotes number of non-nil black nodes in all paths in subtree. It states that (for uncommented version):</p>
<ul>
<li> For black trees the following rules apply:
<ul>
<li> Nil element is a black tree with no non-nil elements</li>
<li> If <code>l, r</code> are a black trees with <code>n</code> black non-nil nodes in all paths and <code>v</code> is a element (label) then <code>BBNode l v r</code> is black tree with <code>n + 1</code> black non-nil nodes in all paths</li>
<li> If <code>l</code>(<code>r</code>) is a red tree (respectively black tree) with <code>n</code> black non-nil nodes in all paths and code&gt;v</code> is a element (label) then <code>RBNode l v r</code> is black tree with <code>n + 1</code> black non-nil nodes in all paths</li>
<li>Nothing else is a black tree</li>
</ul>
</li>
<li> For red trees the following rules apply:
<ul>
<li> If <code>l, r</code> are a black trees with <code>n</code> black non-nil nodes in all paths and <code>v</code> is a element (label) then <code>RedNode l v r</code> is red tree with <code>n</code> black non-nil nodes in all paths</li>
<li>Nothing else is a red tree</li>
</ul>
</li>
</ul>
<p>By construction it ensures the <a href="http://en.wikipedia.org/wiki/Red%E2%80%93black_tree#Properties" title="Red-black tree's properties">all red-black tree's properties</a> are kept and the tree is left-leaning. The tree, which would violate any property is not possible to construct.</p>
<pre class="brush: plain; first-line: 59; title: ; notranslate">
data BlackNode' :: Nat -&gt; Nat -&gt; Nat -&gt; * -&gt; * where
  Top :: BlackNode' n Z n a
  BBNode'L :: (t ~ Add (S n) m) =&gt; BlackNode' (S n) m t a -&gt; a -&gt; BlackNode n a -&gt; BlackNode' n (S m) t a
  BBNode'R :: (t ~ Add (S n) m) =&gt; BlackNode n a -&gt; a -&gt; BlackNode' (S n) m t a -&gt; BlackNode' n (S m) t a
  RBNode'R :: (t ~ Add (S n) m) =&gt; RedNode n a -&gt; a -&gt; BlackNode' (S n) m t a -&gt; BlackNode' n (S m) t a
  RedNode'L :: (t ~ Add n m) =&gt; RedNode' n m t a -&gt; a -&gt; BlackNode n a -&gt; BlackNode' n m t a
  RedNode'R :: (t ~ Add n m) =&gt; BlackNode n a -&gt; a -&gt; RedNode' n m t a -&gt; BlackNode' n m t a

data RedNode' :: Nat -&gt; Nat -&gt; Nat -&gt; * -&gt; * where
  RBNode'L :: (t ~ Add (S n) m) =&gt; BlackNode' (S n) m t a -&gt; a -&gt; BlackNode n a -&gt; RedNode' n (S m) t a
--  RRNode'L :: (t ~ Add (S n) m) =&gt; BlackNode' (S n) m t a -&gt; a -&gt; RedNode n a -&gt; RedNode' n (S m) t a
--  RRNode'R :: (t ~ Add (S n) m) =&gt; RedNode n a -&gt; a -&gt; BlackNode' (S n) m t a -&gt; RedNode' n (S m) t a
</pre>
<p>Since the operation of insertion into tree needs to consider sometimes surrounding and we need to reconstruct the tree afterwards the notion of <a href="http://www.haskell.org/haskellwiki/Zipper" title="Zipper">Zipper</a> become handy. The simplest way of thinking about it is that if we view the tree from certain node we can split/cut the tree into subtree and tree with hole. Now we can represent the tree with hole as either empty suptree (the hole is the tree) or as tuple of sibling subtree, value at parent and tree with hole of 1 size bigger.</p>
<p>The parameters are used to keep the correct sizes of three, where first parameter (<code>n</code>) is number of black non-nil nodes in all paths in subtree, second (<code>m</code>) is  number of black nodes in path to root and third (<code>t</code>) is number of black non-nil nodes in all paths in whole tree.</p>
<pre class="brush: plain; first-line: 72; title: ; notranslate">
find :: (Ord a, NatHelper t) =&gt;
        (forall n m. t ~ Add n m =&gt; BlackNode n a -&gt; BlackNode' n m t a -&gt; b) -&gt;
        (forall n m. t ~ Add n m =&gt; RedNode n a -&gt; RedNode' n m t a -&gt; b) -&gt;
        BlackNode t a -&gt;
        a -&gt;
        b
find fb fr n = find'B fb fr n Top

find'B :: forall a b n m t. (Ord a, t ~ Add n m, NatHelper n, NatHelper m) =&gt;
         (forall n' m'. t ~ Add n' m' =&gt; BlackNode n' a -&gt; BlackNode' n' m' t a -&gt; b) -&gt;
         (forall n' m'. t ~ Add n' m' =&gt; RedNode n' a -&gt; RedNode' n' m' t a -&gt; b) -&gt;
         BlackNode n a -&gt;
         BlackNode' n m t a -&gt;
         a -&gt;
         b 
find'B fb _      Nil           ctx _  = fb Nil ctx
find'B fb fr bn@(BBNode l v r) ctx v' = case compare v' v of
  LT -&gt; prev (TaggedNat :: TaggedNat n) $ \n' -&gt; addEq (find'B fb fr l (BBNode'L ctx v r) v') n' (TaggedNat :: TaggedNat m)
  EQ -&gt; fb bn ctx
  GT -&gt; prev (TaggedNat :: TaggedNat n) $ \n' -&gt; addEq (find'B fb fr r (BBNode'R l v ctx) v') n' (TaggedNat :: TaggedNat m)
find'B fb fr bn@(RBNode l v r) ctx v' = case compare v' v of
  LT -&gt; prev (TaggedNat :: TaggedNat n) $ \n' -&gt; addEq (find'R fb fr l (RBNode'L ctx v r) v') n' (TaggedNat :: TaggedNat m)
  EQ -&gt; fb bn ctx
  GT -&gt; prev (TaggedNat :: TaggedNat n) $ \n' -&gt; addEq (find'B fb fr r (RBNode'R l v ctx) v') n' (TaggedNat :: TaggedNat m)
--find'B fb fr bn@(RRNode l v r) ctx v' = case compare v' v of
--  LT -&gt; prev (TaggedNat :: TaggedNat n) $ \n' -&gt; addEq (find'R fb fr l (RRNode'L ctx v r) v') n' (TaggedNat :: TaggedNat m)
--  EQ -&gt; fb bn ctx
--  GT -&gt; prev (TaggedNat :: TaggedNat n) $ \n' -&gt; addEq (find'R fb fr r (RRNode'R l v ctx) v') n' (TaggedNat :: TaggedNat m)

find'R :: (Ord a, t ~ Add n m, NatHelper n, NatHelper m) =&gt;
         (forall n' m'. t ~ Add n' m' =&gt; BlackNode n' a -&gt; BlackNode' n' m' t a -&gt; b) -&gt;
         (forall n' m'. t ~ Add n' m' =&gt; RedNode n' a -&gt; RedNode' n' m' t a -&gt; b) -&gt;
         RedNode n a -&gt;
         RedNode' n m t a -&gt;
         a -&gt;
         b 
find'R fb fr rn@(RedNode l v r) ctx v' = case compare v' v of
  LT -&gt; find'B fb fr l (RedNode'L ctx v r) v'
  EQ -&gt; fr rn ctx
  GT -&gt; find'B fb fr r (RedNode'R l v ctx) v'
</pre>
<p>Find allows to get the location (node and context) of element labelled by given value. Unfortunately the black case requires additional bookkeeping as type checker is not a SMT solver.</p>
<p>It is generalized function which can be used for implementation of contains, insert, delete etc. The insert function finds location to add - if it is not <code>Nil</code> then value is already present in tree and it aborts. Otherwise it creates a simple red tree and tries to plug it into the hole. There are four cases of plugging in (2 colors of hole x 2 colors of current subtree) starting with putting the red subtree into a black hole created by <code>Nil</code>.</p>
<pre class="brush: plain; first-line: 146; title: ; notranslate">
insert' :: forall a t. (Ord a, NatHelper t) =&gt; a -&gt; BlackNode t a -&gt; (Bool, Either (BlackNode t a) (BlackNode (S t) a))
insert' a n = find (\n' ctx -&gt; case n' of
                       Nil -&gt; (True, mergeRB (RedNode Nil a Nil) ctx)
                       _ -&gt; (False, Left $! n)) (\_ _ -&gt; (False, Left $! n)) n a
</pre>
<p>The simplest cases are plugging red subtree into red hole or black subtree into black hole. They are straightforward operations which simply reconstruct tree from location.</p>
<pre class="brush: plain; first-line: 113; title: ; notranslate">
mergeRR :: RedNode n a -&gt; RedNode' n m t a -&gt; Either (BlackNode t a) (BlackNode (S t) a)
mergeRR l (RBNode'L ctx v r) = mergeBB (RBNode l v r) ctx
--mergeRR l (RRNode'L ctx v r) = mergeBB (RRNode l v r) ctx
--mergeRR r (RRNode'R l v ctx) = mergeBB (RRNode l v r) ctx

mergeBB :: BlackNode n a -&gt; BlackNode' n m t a -&gt; Either (BlackNode t a) (BlackNode (S t) a)
mergeBB t  Top                = Left $! t
mergeBB l (BBNode'L  ctx v r) = mergeBB (BBNode l v r) ctx
mergeBB r (BBNode'R  l v ctx) = mergeBB (BBNode l v r) ctx
mergeBB r (RBNode'R  l v ctx) = mergeBB (RBNode l v r) ctx
mergeBB l (RedNode'L ctx v r) = mergeRR (RedNode l v r) ctx
mergeBB r (RedNode'R l v ctx) = mergeRR (RedNode l v r) ctx

mergeBR :: BlackNode n a -&gt; RedNode' n m t a -&gt; Either (BlackNode t a) (BlackNode (S t) a)
mergeBR l (RBNode'L ctx v r)                  = mergeBB (BBNode l v r) ctx
--mergeBR l (RRNode'L ctx v (RedNode l' v' r')) = mergeBB (RBNode (RedNode l v l') v' r') ctx
--mergeBR r (RRNode'R l v ctx)                  = mergeBB (RBNode l v r) ctx

blacken :: RedNode n a -&gt; BlackNode (S n) a
blacken (RedNode l v r) = BBNode l v r

mergeRB :: RedNode n a -&gt; BlackNode' n m t a -&gt; Either (BlackNode t a) (BlackNode (S t) a)
mergeRB t                   Top                                = Right $! blacken t
mergeRB l                  (BBNode'L ctx v r)                  = mergeBB (RBNode l v r) ctx
mergeRB (RedNode l' v' r') (BBNode'R l v ctx)                  = mergeBB (RBNode (RedNode l v l') v' r') ctx
mergeRB r                  (RBNode'R l v ctx)                  = mergeRB (RedNode (blacken l) v (blacken r)) ctx
mergeRB l                  (RedNode'L (RBNode'L ctx v' u) v r) = mergeRB (RedNode (blacken l) v (BBNode r v' u)) ctx
--mergeRB r                  (RBNode'R l v ctx)                  = mergeBB (RRNode l v r) ctx
--mergeRB l                  (RedNode'L (RBNode'L ctx v' u) v r) = mergeBB (RRNode l v (RedNode r v' u)) ctx
--mergeRB l                  (RedNode'L (RRNode'L ctx v' u) v r) = mergeRB (RedNode (RBNode l v r) v' (blacken u)) ctx
--mergeRB l                  (RedNode'L (RRNode'R u v' ctx) v r) = mergeRB (RedNode (blacken u) v' (RBNode l v r)) ctx
mergeRB (RedNode l' v' r') (RedNode'R l v ctx)                 = mergeRB (RedNode l v l') (RedNode'L ctx v' r')
</pre>
<p>Since it would be inconvenient for user to keep the height of tree on type level it is sufficient to provide him or her with opaque wrapper.</p>
<pre class="brush: plain; first-line: 151; title: ; notranslate">
data RBTree a where
  RBTree :: NatHelper t =&gt; BlackNode t a -&gt; RBTree a

empty :: RBTree a
empty = RBTree $ Nil

insert :: Ord a =&gt; a -&gt; RBTree a -&gt; RBTree a
insert v (RBTree t) = let (_, r) = insert' v t
                      in either RBTree RBTree r

contains :: Ord a =&gt; a -&gt; RBTree a -&gt; Bool
contains a (RBTree n) = find (\n' _ -&gt; case n' of
                                 Nil -&gt; False
                                 _ -&gt; True) (\_ _ -&gt; True) n a
</pre>
<p>While I can see that dynamic typing may have advantages in certain areas (say <a href="http://en.wikipedia.org/wiki/Monkey_patch" title="Monkey patch">monkey patching</a> plug-ins - like in <a href="https://extensions.gnome.org/" title="Gnome Shell Extensions">Gnome Shell</a> or <a href="http://www.mozilla.org/en-US/firefox/new/" title="Mozilla Firefox">Firefox</a> - although it have <a href="http://www.codinghorror.com/blog/2008/07/monkeypatching-for-humans.html" title="Monkeypatching For Humans">some drawbacks</a> too) static typing can be very useful too.</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/programming/'>Programming</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/haskell/'>haskell</a>, <a href='http://blog.piechotka.com.pl/tag/red-black-tree/'>red-black tree</a>, <a href='http://blog.piechotka.com.pl/tag/static-typing/'>static typing</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/116/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/116/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=116&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2013/04/10/statically-typed-red-black-trees/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
		<item>
		<title>(Rant) Difference between good and useful slides</title>
		<link>http://blog.piechotka.com.pl/2012/12/20/rant-difference-between-good-and-useful-slides/</link>
		<comments>http://blog.piechotka.com.pl/2012/12/20/rant-difference-between-good-and-useful-slides/#comments</comments>
		<pubDate>Thu, 20 Dec 2012 20:45:31 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[presentations]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=103</guid>
		<description><![CDATA[Fortunately or unfortunately the presentations tend to be more and more popular sources of information. Be it a new library, language or future direction of a project the only possible way is either attend some presentation or watch it later. At the same time people learn how to make good presentation. By good presentation it [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=103&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Fortunately or unfortunately the presentations tend to be more and more popular sources of information. Be it a new library, language or future direction of a project the only possible way is either attend some presentation or watch it later.</p>
<p><span id="more-103"></span></p>
<p>At the same time people learn how to make good presentation. By good presentation it is usually meant a presentation that keeps people engaged and interested. While the advice often vary from person to person some rules usually have similar direction.</p>
<ul>
<li>Avoid reading slides, use short sentences (or even not full sentences)</li>
<li>Avoid too many slides</li>
<li>Avoid too many data on one slide (in effect speak a lot more then there is on slides)</li>
<li>&#8230;</li>
</ul>
<p>Later on the presentation may be published on the internet for anyone to view, or even published as main or only documentation. Since bandwidth can be far from unlimited often only the slides will be uploaded&#8230; leading to situation when no one who hasn&#8217;t attended the original one has no chance of decrypting what the person meant. Yeah, sure it might have nice pictures and supplemented presentation well, keeping audience focused and entertained, but guessing what does a picture of a baby with title &#8220;Happy user of program X&#8221; actually mean is well beyond of my ability. If the slides are published the game changes &#8211; it is no longer the case that slides are supplemental but they become primary source and the presentation primary context is missing from &#8220;good presentation&#8221;.</p>
<p>Another popular method, which is used if allowed by bandwidth, is to upload video from presentation. If the presentation was &#8220;good&#8221; then it might have a better chance of being understood then slides alone. However this method is not without it&#8217;s own drawbacks as well. During search for something (be it a library, existing research etc.) the skim reading through slides takes 1 minute and gives at which point it can be decided if it is useful or not &#8211; task which is much longer during 2h presentation. Similarly listening is much longer tasks then reading, which makes it much more time wasting (it might also depend if someone is oriented on hearing or seeing). Finally the videos are not searchable with current technology. If I know that something was mentioned in the article searching is as easy as pressing <kbd>Ctrl+F</kbd> &#8211; this is not the case with videos which depend on remembering structure and searching for right moment. Even if the videos was divided into chapters, which is a rare case, this will not help find anything that was say a side remark (say how to set up the environment if it wasn&#8217;t mentioned in introduction).</p>
<p>It looks like that the problem is that the rules are meant to be used during good presentation and later on the slides are reused on a web. Given that they become de-facto documents it might be better to have slightly worse presentations if it means better documentation.</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/uncategorized/'>Uncategorized</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/internet/'>internet</a>, <a href='http://blog.piechotka.com.pl/tag/presentations/'>presentations</a>, <a href='http://blog.piechotka.com.pl/tag/rant/'>rant</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/103/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/103/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=103&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2012/12/20/rant-difference-between-good-and-useful-slides/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
		<item>
		<title>Scripting in GNOME</title>
		<link>http://blog.piechotka.com.pl/2012/05/23/scripting-in-gnome/</link>
		<comments>http://blog.piechotka.com.pl/2012/05/23/scripting-in-gnome/#comments</comments>
		<pubDate>Thu, 24 May 2012 06:45:06 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[GNOME]]></category>
		<category><![CDATA[dbus]]></category>
		<category><![CDATA[desktop environments]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=98</guid>
		<description><![CDATA[Every time now and then we want to automate tasks. Sometimes it is just a repetitive task and sometimes we want to do a complex task without having to remember each particular step. If the task is not general enough (say &#8211; applies to a single workflow) it does not have specialised GUI. On the [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=98&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Every time now and then we want to automate tasks. Sometimes it is just a repetitive task and sometimes we want to do a complex task without having to remember each particular step. If the task is not general enough (say &#8211; applies to a single workflow) it does not have specialised GUI. On the other hand if one of steps involve GUI it cannot be done from commandline (shell script) alone.</p>
<p>Currently various desktop environments provides their own scripting methods (<a href="http://technet.microsoft.com/en-us/library/bb978526.aspx" title="PowerShell">PowerShell</a>, <a href="http://developer.apple.com/applescript/" title="AppleScript">AppleScript</a>, <a href="http://kde.org" title="KDE">KJSEmbed</a>. It might be good to look if it fits <a href="http://gnome.org" title="GNOME">GNOME</a> as well.</p>
<p><span id="more-98"></span></p>
<h3>Requirements</h3>
<p>There are a few requirements I consider basic to operation of scripting in GNOME:</p>
<ul>
<li>Language agnostic. Person who writes script might now one language and (s)he might not want to learn another one. (S)he might have other scripts (s)he wants to integrate &#8211; if possible the scripting framework should not force the user to change the programming language. Such framework would allow to write even new, user-oriented languages or even &#8216;GUI&#8217; scripting (programming by blocks dragged&#8217;n'dropped instead of text)</li>
<li>Live &#8216;outside&#8217; program. It might be useful to script one application but the usecase I have in mind might involve more than one application. For example I might want to open an attachment from Evolution in Evince and print it.</li>
<li>Hide &#8216;memory problems&#8217;. Text editor might contain thousands of words in a single document &#8211; it&#8217;s bad idea to have one object per character or even per word even if we want the client to be able to operate on single characters or even ranges of characters. On the other hand we don&#8217;t want to leak objects just because someone have forgotten to unref object on client, client crashed or get into infinite loop.</li>
<li>Support hooks. For example I might want to run script when I receive an email or when battery is low.</li>
</ul>
<h3>Transport protocol</h3>
<p>It seems that it would be possible to build the system on top of <a href="http://www.freedesktop.org/wiki/Software/dbus" title="DBUS">DBUS</a>. It already have good cross language support, does not involve any other dependencies and with tricks can avoid mentioned before memory problems.</p>
<p>The biggest problem right now is that most binding support only export of heavy objects &#8211; i.e. general assumption is that a dbus object corresponds to language object (both in bindings as well as standard interfaces). Fortunately it is not an assumption made neither by dbus routing nor by dbus protocol (or in fact dbus). It is possible to register a wildcard handler in libdbus (but not, for example, in gdbus) to receive all messages that have not been received by anything else.</p>
<p>The last part is sending &#8211; such wildcard would require (from what I understand) to send to specific endpoint. It would not only be inconvenient for user but also seems to not be supported by many bindings. Again fortunately the dbus protocol supports filtering messages by beginning of path (for example all to <kbd>/org/gnome/Evolution/Script</kbd>).</p>
<h3>Solution?</h3>
<p>Well &#8211; to start with I haven&#8217;t written any prototype even &#8211; just read the documentation of dbus and libdbus. There are a few things omitted in the text &#8211; for example the script might be run in application or by daemon. Each approach have certain benefits/drawbacks.</p>
<p>Running in application might be faster if script just operate on objects in given application. On the other hand spawning a few VM in application might hurt the performance  (say we have one script in <a href="http://perl.org" title="Perl">perl</a> and one in <a href="http://python.org" title="Python">python</a> to run on each message). Also a script might crash/hang whole application</p>
<p>Daemon on the other hand might spawn a pool of VMs (if they are sandboxed) and respawn them if any crashes. The scripts might run asynchronously (at least to some extend) as well. However it makes the architecture a bit more complex and distinguish between one time scripts (which don&#8217;t use daemon) and hooks (running in daemon).</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/gnulinux/gnome/'>GNOME</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/dbus/'>dbus</a>, <a href='http://blog.piechotka.com.pl/tag/desktop-environments/'>desktop environments</a>, <a href='http://blog.piechotka.com.pl/tag/gnome-2/'>gnome</a>, <a href='http://blog.piechotka.com.pl/tag/scripting/'>scripting</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/98/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/98/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=98&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2012/05/23/scripting-in-gnome/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
		<item>
		<title>So the blog is on WordPress.com now</title>
		<link>http://blog.piechotka.com.pl/2012/02/06/so-the-blog-is-on-wordpress-com-now/</link>
		<comments>http://blog.piechotka.com.pl/2012/02/06/so-the-blog-is-on-wordpress-com-now/#comments</comments>
		<pubDate>Mon, 06 Feb 2012 19:49:04 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[move]]></category>

		<guid isPermaLink="false">http://mpiechotka.wordpress.com/?p=95</guid>
		<description><![CDATA[Unfortunately  the previous host was unreliable to say the least. During last crash I lost two posts (one note very interesting about libgee 0.7 and one about general thought on debugging). The recent security breach caused lost of trust into it from many users (including me) and caused the closure of project. Therefore the blog was moved [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=95&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Unfortunately  the previous host was unreliable to say the least. During last crash I lost two posts (one note very interesting about <a title="Libgee - GObject collection library" href="http://live.gnome.org/Libgee">libgee 0.7</a> and one about general thought on debugging). The recent security breach caused lost of trust into it from many users (including me) and caused the closure of project.</p>
<p>Therefore the blog was moved to <a title="Wordpress" href="http://wordpress.com">wordpress.com</a> - please wait until the change is propagated through DNSes.</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/blog/'>Blog</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/blog-2/'>blog</a>, <a href='http://blog.piechotka.com.pl/tag/move/'>move</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/95/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/95/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=95&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2012/02/06/so-the-blog-is-on-wordpress-com-now/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
		<item>
		<title>Hosting problems</title>
		<link>http://blog.piechotka.com.pl/2011/10/23/hosting-problems/</link>
		<comments>http://blog.piechotka.com.pl/2011/10/23/hosting-problems/#comments</comments>
		<pubDate>Sun, 23 Oct 2011 18:25:27 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[crash]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=93</guid>
		<description><![CDATA[I finally restored blog after my provider total RAID failure which resulted in xfs corruption of partition where the databases were located (as well as corruption of partition where the blog was). Unfortunately not all data was retrieved so there are a few things missing from previous blog (comments and users). Filed under: Blog Tagged: [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=93&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>I finally restored blog after my provider total RAID failure which resulted in xfs corruption of partition where the databases were located (as well as corruption of partition where the blog was). Unfortunately not all data was retrieved so there are a few things missing from previous blog (comments and users).</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/blog/'>Blog</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/blog-2/'>blog</a>, <a href='http://blog.piechotka.com.pl/tag/crash/'>crash</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/93/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/93/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=93&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2011/10/23/hosting-problems/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
		<item>
		<title>I&#039;m going to Desktop Summit</title>
		<link>http://blog.piechotka.com.pl/2011/08/05/im-going-to-desktop-summit/</link>
		<comments>http://blog.piechotka.com.pl/2011/08/05/im-going-to-desktop-summit/#comments</comments>
		<pubDate>Fri, 05 Aug 2011 00:30:09 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[GNOME]]></category>
		<category><![CDATA[conference]]></category>
		<category><![CDATA[desktop-summit]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[guadec]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=59</guid>
		<description><![CDATA[<div><a href="https://www.desktopsummit.org"><img alt="I&#039;m goint to Desktop Summit" src="https://www.desktopsummit.org/sites/www.desktopsummit.org/files/DS2011banner.png" title="Desktop Summit" class="alignnone" width="333" height="110" /></a></div>
<p>I'm going to Desktop Summit</p><img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=59&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<div><a href="https://www.desktopsummit.org"><img alt="I&#039;m goint to Desktop Summit" src="https://www.desktopsummit.org/sites/www.desktopsummit.org/files/DS2011banner.png" title="Desktop Summit" class="alignnone" width="333" height="110" /></a></div>
<p>I&#8217;m going to Desktop Summit</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/gnulinux/gnome/'>GNOME</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/conference/'>conference</a>, <a href='http://blog.piechotka.com.pl/tag/desktop-summit/'>desktop-summit</a>, <a href='http://blog.piechotka.com.pl/tag/gnome-2/'>gnome</a>, <a href='http://blog.piechotka.com.pl/tag/guadec/'>guadec</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=59&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2011/08/05/im-going-to-desktop-summit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>

		<media:content url="https://www.desktopsummit.org/sites/www.desktopsummit.org/files/DS2011banner.png" medium="image">
			<media:title type="html">Desktop Summit</media:title>
		</media:content>
	</item>
		<item>
		<title>I am not member of my generation</title>
		<link>http://blog.piechotka.com.pl/2011/02/06/i-am-not-member-of-my-generation/</link>
		<comments>http://blog.piechotka.com.pl/2011/02/06/i-am-not-member-of-my-generation/#comments</comments>
		<pubDate>Sun, 06 Feb 2011 18:42:28 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[General]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[revolution]]></category>
		<category><![CDATA[wikileaks]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=47</guid>
		<description><![CDATA[That&#8217;s not one of the promised posts but anyway I&#8217;d like to share a few thought after reading a series of articules about the internet and discovering what some people may think about the network. I am aware that the articles I&#8217;ve read are biased sample but nonetheless I belive that they still worth to [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=47&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>That&#8217;s not one of the promised posts but anyway I&#8217;d like to share a few thought after reading a series of articules about the internet and discovering what some people may think about the network. I am aware that the articles I&#8217;ve read are biased sample but nonetheless I belive that they still worth to read to find out what people may think about the internet.</p>
<p>I am sorry for lack of the exact quotes or references but I was unable to find them. They were spread over several weeks and I found only paid archives so I am not able to pinpoint exact newspapers.</p>
<p><span id="more-47"></span></p>
<p>One of the articles spoke about <a href="http://wikileaks.ch/">Wikileaks</a> and tried to compare the current situation to <a href="http://en.wikipedia.org/wiki/Protests_of_1968">1968</a> stating that the current internet is too one-contact-only to provide platform for revolution giving as an example a message from twitter which makes one time contact and that <q>the revolution needs continuity</q>.</p>
<p>I belive that there are 2 problems with such analysis. First of all I&#8217;m not quite sure how many contacts are one-time-only. Arguably one of the most popular site on the internet, <a href="http://facebook.com">Facebook</a>, is based rather on the continous contacts rather then one time. <a href="http://www.bbc.co.uk/news/science-environment-11321282">Some studies</a> indicates that the our core groups involve around 4-5 people. Setting aside the social networks any other communications involve known people &#8211; you relativly rarely send e-mail to stranger.</p>
<p>Secondly the internet is not homogenious. According to wikipedia <q cite="http://en.wikipedia.org/w/index.php?title=Protests_of_1968&amp;oldid=406860399">This was the first generation to grow up with television in their homes. (&#8230;) Chain stores and franchised restaurants were bringing shared shopping and dining experiences to people in different parts of the world. These factors all combined to create a generation that was more self-aware and more united as a group than the generations before it.</q> &#8211; in other words it was the beginning of the mass market. However the internet seems to be somehow the end of mass market in some sense as it allows the comeback of the niches.</p>
<p>While it may not unify the revolution it provides platforms for revolution as it connects similar-minded people. You can find communities of the conservatives, socialists, libertatian, anarchists of all kinds etc. For some ideologies it is primary platform of propagation. Recent events in Egypt and Algieria had shown that it is useful tool in this role.</p>
<p>I don&#8217;t want to imply that revolution will actually happen. The article was more interesting as what people think about the internet from outside then the revolution itself.</p>
<p><b>PS</b> I have writted main part of article on 14 of January. Therefore it speak about wikileaks as &#8220;recent events&#8221;. I decided eventually to post it now &#8211; especially in context of the events in Egypt and Algerial world. I don&#8217;t want to discuss what actually happened there and what are the consequences &#8211; the important part from this post POV is that internet proved to be useful as a platform.</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/general/'>General</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/internet/'>internet</a>, <a href='http://blog.piechotka.com.pl/tag/revolution/'>revolution</a>, <a href='http://blog.piechotka.com.pl/tag/wikileaks/'>wikileaks</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/47/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/47/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=47&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2011/02/06/i-am-not-member-of-my-generation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
		<item>
		<title>Gnome and gnome-shell</title>
		<link>http://blog.piechotka.com.pl/2010/12/28/gnome-and-gnome-shell/</link>
		<comments>http://blog.piechotka.com.pl/2010/12/28/gnome-and-gnome-shell/#comments</comments>
		<pubDate>Tue, 28 Dec 2010 18:48:37 +0000</pubDate>
		<dc:creator>Maciej Piechotka</dc:creator>
				<category><![CDATA[GNOME]]></category>
		<category><![CDATA[gnome]]></category>
		<category><![CDATA[gnome 3.0]]></category>
		<category><![CDATA[gnome-shell]]></category>

		<guid isPermaLink="false">http://blog.piechotka.com.pl/?p=29</guid>
		<description><![CDATA[Since some time I try to follow gnome 3.0 development and gnome-shell in particular. However I started to be growingly sceptical about 3.0 release (well &#8211; possibly again) and fear repeat of KDE 4.0. I hope I am wrong and I have hevily biased view. I don&#8217;t use the recommended by developers method of building [&#8230;]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=29&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></description>
				<content:encoded><![CDATA[<p>Since some time I try to follow <a title="Gnome 3.0" href="http://live.gnome.org/ThreePointZero">gnome 3.0</a> development and <a title="Gnome Shell" href="http://live.gnome.org/GnomeShell">gnome-shell</a> in particular. However I started to be growingly sceptical about 3.0 release (well &#8211; possibly again) and fear repeat of KDE 4.0. I hope I am wrong and I have hevily biased view.</q></p>
<p><span id="more-29"></span></p>
<p>I don&#8217;t use the <a title="Jhbuild" href="http://live.gnome.org/Jhbuild">recommended by developers method of building</a> for two reasons. First of all I have rather limited amount of disk space, especially on &#8216;/home&#8217;, and the duplication of many libraries and include files (I use <a href="http://gentoo.org" title="Gentoo Linux Distribution">Gentoo</a>) seems to not be an option for me. Secondly installing in <a title="Jhbuild" href="http://live.gnome.org/Jhbuild">Jhbuild</a> sandbox prevents from seeing overall impact of changes in <a href="http://gnome.org" title="Gnome Desktop Enviroment">Gnome</a> on system (like some packages, including <a href="http://firefox.org" title="Firefox">Firefox</a>, failing to build some time ago with new <a href="http://gtk.org" title="GTK+">gtk+</a> 2).</p>
<p>As a result it more often does not work then do. Excluding some &#8216;obvious&#8217; reasons <a href="https://bugzilla.gnome.org/show_bug.cgi?id=636764" title="Crash in mark and sweep GC">like</a> <a href="https://bugzilla.gnome.org/show_bug.cgi?id=636836" title='gnome-shell from git fails to start ("Crash in mark and sweep GC")'>crashes</a> it now requires new gnome-settings-daemon which requires libnotify 0.7, which changes abi and api breaking everything that uses libnotify on my system (mostly from Gnome so hopefully most are fixed but not only). Libnotify is not parallel installable so I can either move to <a title="Jhbuild" href="http://live.gnome.org/Jhbuild">JHbuild</a> or resign from using gnome-shell.</p>
<p>For gnome-shell language, <a href="https://developer.mozilla.org/en/About_JavaScript">JavaScript</a>, was chosen as easily embeddable and widely known. In addition it <a href="http://blog.fishsoup.net/2008/10/22/implementing-the-next-gnome-shell/" title="Implementing the next GNOME shell"><q cite="http://blog.fishsoup.net/2008/10/22/implementing-the-next-gnome-shell/">doesnâ€™t pull in another complicated platform</q></a> (and it allows to avoid &#8220;duplication&#8221; with glibraries). The problem pointed by <a href="http://blogs.gnome.org/pbor/2009/11/05/javascript-in-gnome/" title="JavaScript in Gnome">others</a>. I guess that most JavaScript use are through libraries like <a href="http://jquery.com/">JQuery</a>. Anyway the problem isn&#8217;t the language itself &#8211; when I tried to write simple plugin some time ago I found very little resources to get a hello-world example working. While <a href="http://en.wikipedia.org/wiki/Monkey_patch">mokey patching</a> may provide certain benefits crashing shell when one tries to find out how to add something to GUI is not preferable. Additionally it seems that <a href="http://mail.gnome.org/archives/desktop-devel-list/2010-December/msg00058.html">there are problems with embedding javascript anyway</a>.</p>
<p>Release late, release never. The gnome-shell seems to have some features present on screenshots and videos (including ones from GUADEC) that I could never found in one I get from git/tarballs &#8211; like multiple views in overview mode. On the other hand it constantly relies on git including sometimes releases of gnome-shell depending on gjs from git. Finding working configuration seems to be hard &#8211; while possibly it is made easier by <a title="Jhbuild" href="http://live.gnome.org/Jhbuild">JHbuild</a> I don&#8217;t want to use it for reasons above.</p>
<p>Last point is ongoing discussion about the gnome-shell hardware requirements. Contrary to gnome-panel and metacity gnome-shell requires 3D acceleration and while I&#8217;m &#8220;lucky&#8221; (I have new integrated intel card &#8211; not great for gaming but works on Linux) some reported issue on <a href="http://mail.gnome.org/archives/desktop-devel-list/2010-December/msg00147.html" title="Problems on NVidia cards">NVidia</a>. Even on intel card sometimes it seems that the system slows down during heavy loads (although it improved in 2.6.36 kernel).</p>
<p>Finally I&#8217;d like to remaind that the post is written from my own perspective and I may have biased view (including different method of installing and not being involved into design process). In some parts I exagareted (&#8220;Release late, release never&#8221;) for only reason of joking &#8211; and I hope noone will feel offended because of it. However I have my concerns about Gnome-Shell and Gnome 3.0 which, I hope, are invalid.</p>
<br />Filed under: <a href='http://blog.piechotka.com.pl/category/gnulinux/gnome/'>GNOME</a> Tagged: <a href='http://blog.piechotka.com.pl/tag/gnome-2/'>gnome</a>, <a href='http://blog.piechotka.com.pl/tag/gnome-3-0/'>gnome 3.0</a>, <a href='http://blog.piechotka.com.pl/tag/gnome-shell/'>gnome-shell</a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mpiechotka.wordpress.com/29/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mpiechotka.wordpress.com/29/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=blog.piechotka.com.pl&#038;blog=7088330&#038;post=29&#038;subd=mpiechotka&#038;ref=&#038;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://blog.piechotka.com.pl/2010/12/28/gnome-and-gnome-shell/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1e8f141e7857d397d8020ed3b759e88a?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">Maciej Piechotka</media:title>
		</media:content>
	</item>
	</channel>
</rss>
