<?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>eSCALAtion Blog</title>
	<atom:link href="http://dgronau.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://dgronau.wordpress.com</link>
	<description>Scala, Java, das Leben und der Rest</description>
	<lastBuildDate>Wed, 25 Jan 2012 19:08:30 +0000</lastBuildDate>
	<language>de</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='dgronau.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://0.gravatar.com/blavatar/4ba55d7a426562249aa1c698bbd052bd?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>eSCALAtion Blog</title>
		<link>http://dgronau.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://dgronau.wordpress.com/osd.xml" title="eSCALAtion Blog" />
	<atom:link rel='hub' href='http://dgronau.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Diamanten in Java</title>
		<link>http://dgronau.wordpress.com/2012/01/25/diamanten-in-java/</link>
		<comments>http://dgronau.wordpress.com/2012/01/25/diamanten-in-java/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 19:05:28 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Diamant-Problem]]></category>
		<category><![CDATA[Diamond Problem]]></category>
		<category><![CDATA[don't repeat yourself]]></category>
		<category><![CDATA[DRY]]></category>
		<category><![CDATA[inheritance]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Vererbung]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=780</guid>
		<description><![CDATA[Java verfügt weder über Mehrfach- noch über Mixin-Vererbung. Insofern erscheint eine Diskussion des Diamant-Problems reichlich müßig. Trotzdem bin ich gerade darüber gestolpert, und habe einen Ansatz entwickelt, der &#8211; allerdings auf Kosten der Übersichtlichkeit &#8211; Code-Duplizierung vermeidet. Nehmen wir an, folgende Interfaces seien gegeben: Die useXYZ-Methoden können allgemein unter Rückgriff auf die anderen Methoden des [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=780&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Java verfügt weder über Mehrfach- noch über Mixin-Vererbung. Insofern erscheint eine Diskussion des <a href="http://de.wikipedia.org/wiki/Diamond-Problem" target="_blank">Diamant-Problems</a> reichlich müßig. Trotzdem bin ich gerade darüber gestolpert, und habe einen Ansatz entwickelt, der &#8211; allerdings auf Kosten der Übersichtlichkeit &#8211; Code-Duplizierung vermeidet. Nehmen wir an, folgende Interfaces seien gegeben:</p>
<p><pre class="brush: java;">
public interface Base {
    public void base();
    public void useBase();
}

public interface Foo extends Base {
    public void foo();
    public void useFoo();
}

public interface Bar extends Foo {
    public void bar();
    public void useBar();
}

public interface FooBar extends Foo, Bar {
    public void useFooAndBar();
}
</pre></p>
<p>Die useXYZ-Methoden können allgemein unter Rückgriff auf die anderen Methoden des Interfaces oder der Super-Interfaces implementiert werden, und sollten deshalb in abstrakte Klassen ausgelagert werden. Natürlich kann die abstrakte Klasse für FooBar nur von einer der beiden in Frage kommenden abstrakten Klassen erben, sagen wir von der zu Foo. Dann haben wir folgendes Szenario:</p>
<p><pre class="brush: java;">
public abstract class BaseAbstract implements Base {
    public abstract void base();
    public void useBase() {
        System.out.println(&quot;using Base.base()&quot;);
        base();
    }
}

public abstract class FooAbstract extends BaseAbstract implements Foo {
    public abstract void foo();
    public void useFoo() {
        System.out.println(&quot;using Foo.foo() and Base.base()&quot;);
        foo();
        base();
    }
}

public abstract class BarAbstract extends BaseAbstract implements Bar {
    public abstract void bar();
    public void useBar() {
        System.out.println(&quot;using Bar.bar() and Base.base()&quot;);
        bar();
        base();
    }
}

public abstract class FooBarAbstract extends FooAbstract implements FooBar {
    public abstract void bar();
    //DUPLICATED
    public void useBar() {
        System.out.println(&quot;using Bar.bar() and Base.base()&quot;);
        bar();
        base();
    }
    public void useFooAndBar() {
        System.out.println(&quot;using everything&quot;);
        base();
        foo();
        bar();
    }
}
</pre></p>
<p>Wie man sieht, bleibt bei dieser Version nichts anderes übrig, als in FooBarAbstract den Inhalt von Bar zu wiederholen.</p>
<p>Mein Vorschlag, das Problem zu lösen, verletzt so einige OO-Prinzipien und wird dadurch unflexibel gegenüber nachträglichen Änderungen. Ich würde ihn nur empfehlen, wenn die Hierarchie wirklich feststeht und man sich damit erhebliche Code-Duplizierungen erspart (also wenn Anzahl und Umfang der useFoo()- und useBar()-Methoden recht groß ist. Der Trick beruht darauf, die Implementierung von useBar() schon in BaseAbstract zu erledigen. Dazu wird eine Hilfsmethode _bar() benötigt, die dort wo vorhanden (also in Bar und FooBar) einfach zum &#8222;echten&#8220; bar(), das ja vom Nutzer der abstrakten Klasse bereitgestellt werden muss, weiterleitet:</p>
<p><pre class="brush: java;">
public abstract class BaseAbstract implements Base {
    public abstract void base();

    public void useBase() {
        System.out.println(&quot;using Base.base()&quot;);
        base();
    }
    
    //Ersatz-Methode für bar()
    protected void _bar() {
       throw new UnsupportedOperationException(); 
    }
    
    //Code, der eigentlich in BarAbstract gehört
    public void useBar() {
        System.out.println(&quot;using Bar.bar() and Base.base()&quot;);
        _bar(); //benutzt die Ersatz-Methode
        base();
    }
}

public abstract class FooAbstract extends BaseAbstract implements Foo {
    public abstract void foo();
    public void useFoo() {
        System.out.println(&quot;using Foo.foo() and Base.base()&quot;);
        foo();
        base();
    }
}

public abstract class BarAbstract extends BaseAbstract implements Bar {
    public abstract void bar();

    //Delegation, sonst funktioniert useBar() nicht
    @Override protected void _bar() { bar(); }
}

public abstract class FooBarAbstract extends FooAbstract implements FooBar {
    public abstract void bar();

    //Delegation, sonst funktioniert useBar() nicht
    @Override protected void _bar() { bar(); }
    
    public void useFooAndBar() {
        System.out.println(&quot;using everything&quot;);
        base();
        foo();
        bar();
    }
}
</pre></p>
<p>Wie so oft wird mein Code keinen Schönheitspreis gewinnen, weil er mit den Beschränkungen von Java kämpft. Es ist ein Kompromiss, der zur Wahrung des <a href="http://de.wikipedia.org/wiki/DRY" target="_blank">DRY-Prinzips</a> andere Konventionen verletzt. Man sollte sich sehr genau überlegen, ob diese Technik an einer bestimmten Stelle wirklich sinnvoll ist, aber <em>wenn </em>sie es ist, kann sie einige Arbeit sparen.</p>
<p>Wie immer bin ich natürlich neugierig, ob jemand eine bessere Idee hat.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/780/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/780/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/780/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=780&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2012/01/25/diamanten-in-java/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>Schachteln für Fortgeschrittene</title>
		<link>http://dgronau.wordpress.com/2011/12/22/schachteln-fur-fortgeschrittene/</link>
		<comments>http://dgronau.wordpress.com/2011/12/22/schachteln-fur-fortgeschrittene/#comments</comments>
		<pubDate>Thu, 22 Dec 2011 09:59:05 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[implicit]]></category>
		<category><![CDATA[implizite Konvertierung]]></category>
		<category><![CDATA[implizite Konvertierungen]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=775</guid>
		<description><![CDATA[Angeregt von dieser Frage auf Stackoverflow will ich mich heute mit geschachtelten Listen beschäftigen: Kann man eine Methode schreiben, die sowohl eine Liste von Ints wie auch eine Liste von Int-Listen wie auch eine Liste von Listen von Int-Listen u.s.w. aufsummieren kann? Sicher, das geht auch in Java &#8211; allerdings nicht typsicher: Da es dort [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=775&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Angeregt von <a href="http://stackoverflow.com/questions/8593710/cubesumming-in-haskell" target="_blank">dieser Frage auf Stackoverflow</a> will ich mich heute mit geschachtelten Listen beschäftigen: Kann man eine Methode schreiben, die sowohl eine Liste von Ints wie auch eine Liste von Int-Listen wie auch eine Liste von Listen von Int-Listen u.s.w. aufsummieren kann? Sicher, das geht auch in Java &#8211; allerdings nicht <strong>typsicher</strong>: Da es dort keine Möglichkeit gibt, einen allgemeinen &#8222;Listen-Stapel-Typ&#8220; zu definieren, muss gecastet werden, und das wiederum heißt, das Laufzeitfehler auftreten können, wenn ein ungeeignetes Objekt (sagen wir eine String-Liste) übergeben wird.</p>
<p>Wie sieht die Haskell-Lösung aus? </p>
<p><pre class="brush: plain;">
class Summable a where
  total :: a -&gt; Int

instance Summable Int where
  total = id  

instance Summable x =&gt; Summable [x] where
  total = sum . map total  

total ([[[1,2,3],[4,5]],[[6],[7,8,9,10]]] :: [[[Int]]])
--55
</pre></p>
<p>Aha, Typklassen! Wir definieren eine Typklasse &#8222;Summable&#8220;, die eine Funktion &#8222;total&#8220; zum Aufsummieren enthält. Die Instanz für Int ist trivial: Wir geben einfach die Zahl selbst zurück (man hätte dafür auch total x = x schreiben können). Interessanter ist die Instanz für Listen, die eine sogenannte Context-Bound enthält: Wenn a in der Klasse Summable ist, dann ist auch eine Liste von a in der Klasse &#8211; genau die Art von &#8222;Rekursivität&#8220;, die wir brauchen. Deshalb darf man in der Definition von total auch die Funktion total auf die Elemente anwenden, da man ja weiß, dass sie auch Summable sind. In der letzten Zeile wird die Funktion ausprobiert (dass man u.U. die Typangabe :: [[[Int]]] braucht, hat nichts mit unseren Typklassen zu tun, sondern ist der &#8222;Monomorphismus-Restriktion&#8220; geschuldet, und wäre bei nicht-numerischen Typen nicht notwendig).</p>
<p>Wie setzt man das nun in Scala um? Ich habe mich zuerst mit einer typklassenartigen Implementierung versucht, bin aber nicht so recht weitergekommen. Am Ende hat dann eine etwas direktere Vorgehensweise zum Ziel geführt:</p>
<p><pre class="brush: scala;">
object nestedTest {
  
  case class Summable(total:Int)
   
  implicit def intSummable(i:Int) = Summable(i)
  
  implicit def listSummable[T &lt;% Summable](list:List[T]) = Summable(list.map(_.total).sum)
  
  def total[T &lt;% Summable](t:T) = t.total
  
  def main(args: Array[String]) {
    println(total(1))
    println(total(List(1,2,3)))
    println(total(List(List(1),List(2,3))))
    //println(total(List(List(&quot;a&quot;),List(&quot;b&quot;,&quot;c&quot;)))) 
    //--&gt; error: No implicit view available from List[List[java.lang.String]] =&gt; nestedTest.Summable.
  }
}
</pre></p>
<p>Summable ist jetzt keine Typklasse, sondern einfach ein Wrapper um Int. Dann definiere ich entsprechende Konvertierungen. Wieder ist die Umwandlung von Int nicht besonders spannend, dafür die Definition der List-Variante. Der entscheidende Trick ist die Verwendung einer View-Bound T &lt;% Summable. Das heißt, dass T in ein Summable &quot;umwandelbar&quot; sein muss, und genau das ist der Trick, um Scala die gewünschte &quot;Rekursivität&quot; beizubringen. Durch die Garantie der View-Bound ist es erlaubt, map(_.total) zu schreiben, denn wir wissen ja, dass T in ein Summable konvertiert werden kann, und Summable hat ein Feld namens total. Für die Bequemlichkeit definieren wir noch eine Top-Level-Funktion für total, um dem Anwender das Hantieren mit Summable zu ersparen. In der main-Methode werden nun verschiedene Varianten ausprobiert. Ein Aufruf mit einem unpassenden Argument scheitert, und das sogar mit einer recht verständlichen Fehlermeldung.</p>
<p>Ich hoffe, dass das Beispiel gezeigt hat, dass Scalas Typsystem dem von Java auch bei recht praktischen Aufgabestellungen überlegen ist, auch wenn man manchmal etwas frickeln muss. Haskell glänzt hier mit einer sehr einfachen Variante, aber es gibt auch Konstrukte, die sich besser mit Scala implementieren lassen (z.B. alles mit variabler Anzahl Argumente).</p>
<p>Ich fasse schon einmal den guten Vorsatz, das Blog nächstes Jahr nicht ganz so stiefmütterlich zu behandeln. An spannenden Themen soll es nicht mangeln: Da wäre das gerade frisch releaste <a href="http://ceylon-lang.org/blog/2011/12/20/ceylon-m1-newton/?utm_source=news&amp;utm_medium=web&amp;utm_content=newslink&amp;utm_campaign=1_0_M1release">Ceylon</a> (allerdings mit noch enttäuschenden Funktionsumfang), Bauarbeiten an Scala und Java, die tolle Sprache <a href="http://code.google.com/p/frege/" target="_blank">Frege</a>, die langsam erwachsen wird und ihr Vorbild Haskell, bei dem auch interessante Neuerungen anstehen, wenn man <a href="http://channel9.msdn.com/Blogs/Charles/YOW-2011-Simon-Peyton-Jones-Closer-to-Nirvana" target="_blank">Simon Peyton Jones</a> glaubt. </p>
<p>Dann wünsche ich allen ein Frohes Fest, einen Guten Rutsch und ein erfolgreiches 2012!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/775/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/775/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/775/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=775&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/12/22/schachteln-fur-fortgeschrittene/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>Extraktoren für Seq</title>
		<link>http://dgronau.wordpress.com/2011/11/16/extraktoren-fur-seq/</link>
		<comments>http://dgronau.wordpress.com/2011/11/16/extraktoren-fur-seq/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 10:26:55 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Extractors]]></category>
		<category><![CDATA[Extraktoren]]></category>
		<category><![CDATA[Patter Matching]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=771</guid>
		<description><![CDATA[Eine nützliche Funktion für Sequenzen ist indexOf, die die Position eines Elements innerhalb einer Sequenz bestimmt. Diese kann man in Extraktoren verpacken, z.B.: Nun kann man ein paar aus einer Sequenz und einem Element matchen: In der vorliegenden Form ist das vielleicht noch nicht sooo furchtbar nützlich, aber das Prinzip lässt sich gut verallgemeinern. Ich [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=771&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Eine nützliche Funktion für Sequenzen ist indexOf, die die Position eines Elements innerhalb einer Sequenz bestimmt. Diese kann man in Extraktoren verpacken, z.B.:</p>
<p><pre class="brush: scala;">
object IndexOf {
   def unapply[T](pair:(Seq[T],T)):Option[Int] = {
     val index = pair._1.indexOf(pair._2)  
     if (index == -1) None else Some(index)
   }
}

object ReverseIndexOf {
   def unapply[T](pair:(Seq[T],T)):Option[Int] = {
     val index = pair._1.indexOf(pair._2)  
     if (index == -1) None else Some(pair._1.size - index - 1)
   }
} 
</pre></p>
<p>Nun kann man ein paar aus einer Sequenz und einem Element matchen:</p>
<p><pre class="brush: scala;">
def testIndexOf(n:Int) = (List(1,2,3,4,5,6,7),n) match {
  case IndexOf(0) =&gt; println(&quot;first&quot;)
  case IndexOf(1) =&gt; println(&quot;second&quot;)
  case ReverseIndexOf(1) =&gt; println(&quot;second to last&quot;)  
  case ReverseIndexOf(0) =&gt; println(&quot;last&quot;)  
  case IndexOf(x) =&gt; println(&quot;indexOf==&quot; + x)
  case _ =&gt; println(&quot;not found&quot;)  
}

(1 to 8).foreach(testIndexOf(_))
//--&gt; first
//--&gt; second
//--&gt; indexOf==2
//--&gt; indexOf==3
//--&gt; indexOf==4
//--&gt; second to last
//--&gt; last
//--&gt; not found
</pre></p>
<p>In der vorliegenden Form ist das vielleicht noch nicht sooo furchtbar nützlich, aber das Prinzip lässt sich gut verallgemeinern. Ich finde es jedenfalls interessant, selbst Extraktoren zu schreiben, statt mich mit vorgefertigten oder durch Fallklassen autogenerierte Extraktoren zu begnügen.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/771/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/771/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/771/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/771/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/771/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/771/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/771/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/771/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/771/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/771/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/771/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/771/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/771/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/771/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=771&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/11/16/extraktoren-fur-seq/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>ScalaTest mit Maven</title>
		<link>http://dgronau.wordpress.com/2011/10/09/scalatest-mit-maven/</link>
		<comments>http://dgronau.wordpress.com/2011/10/09/scalatest-mit-maven/#comments</comments>
		<pubDate>Sun, 09 Oct 2011 11:52:03 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=764</guid>
		<description><![CDATA[Dies ist ein Gastbeitrag von 0x7F800000. Eine kürzere Version dieses Artikels gibt es auch auf englisch: You can find a shorter english version of this post here. Neuerdings wollte ich bei einem Scala-Projekt ScalaTest in Maven zum Laufen bringen, konnte aber kaum brauchbare Informationen darüber finden. So stößt man beim googlen nach &#8222;maven scalatest plugin&#8220; [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=764&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Dies ist ein Gastbeitrag von <a href="http://www.java-forum.org/members/16406.html" target="_blank">0x7F800000</a>. Eine kürzere Version dieses Artikels gibt es auch auf englisch: <strong>You can find a shorter english version of this post <a href="http://www.java-forum.org/scala-groovy-jython-javafx/125089-maven-scalatest-unnoetig-verbose-fehlermeldungen.html#post811647" target="_blank">here</a></strong>.</p>
<p>Neuerdings wollte ich bei einem Scala-Projekt <a href="http://www.scalatest.org/" target="_blank">ScalaTest</a> in <a href="http://maven.apache.org/">Maven</a> zum Laufen bringen, konnte aber kaum brauchbare Informationen darüber finden. </p>
<p>So stößt man beim googlen nach &#8222;maven scalatest plugin&#8220; hauptsächlich auf Diskussionen, die darauf hinauslaufen, dass man eine @RunWith &#8211; Annotation an die ScalaTest-Suites anhängen und weiterhin mit JUnitRunner leben soll, etwa so:</p>
<p><pre class="brush: scala;">
import org.scalatest.junit.JUnitRunner
import org.junit.runner.RunWith
import org.scalatest.Spec
import org.scalatest.matchers.ShouldMatchers
 
@RunWith(classOf[JUnitRunner])
class MySpec extends Spec {
    // ScalaTest spec code here
}
</pre><br />
(siehe beispielsweise <a href="http://jpz-log.info/archives/2009/09/29/scalatest-in-maven/" target="_blank">JPz&#8217;log</a>, <a href="http://stackoverflow.com/questions/1093520/is-there-a-scala-unit-test-tool-that-integrates-well-with-maven" target="_blank">stack-overflow</a> oder <a href="http://groups.google.com/group/scalatest-users/browse_thread/thread/7e212267270dcd8e" target="_blank">scalatest-users google groups</a>)</p>
<p>Das ganze wird dann einfach vom <strong>maven-surefire-plugin</strong> aufgegriffen, und als ein klassischer JUnit-Test ausgeführt. Das funktioniert zwar einigermaßen, aber es liefert nicht wirklich die erhoffte übersichliche Liste mit Testergebnissen wie <a href="http://www.scalatest.org/" target="_blank">hier</a> angepriesen. Daraus ergibt sich die Frage: Wie bringt man Maven dazu, den <strong>org.scalatest.tools.Runner</strong> für die Scala-Suites und Specs zu verwenden?</p>
<p>Die Antwort lautet: Das <strong>maven-scalatest-plugin</strong> statt <strong>maven-surefire-plugin</strong> nutzen. Dies ist ein erst vor kurzem von <a href="https://github.com/teigen" target="_blank">Jon-Anders Teigen</a> entwickeltes Maven-Plugin, und kann (noch) nicht aus den maven-repositories heruntergeladen werden: Man muss es stattdessen direkt von Teigens Seite herunterladen und installieren. Dies bewerkstelligt man, indem man den <a href="https://github.com/teigen/maven-scalatest-plugin" target="_blank">Installationsanweisungen</a> auf der Projektseite folgt, also:</p>
<ol>
<li> Man stelle sicher, dass man über eine funktionsfähige Version von <a href="http://git-scm.com/" target="_blank">git</a> verfügt</li>
<li> Man klone das angegebene Repository. Teigen selbst empfiehlt <a href="http://scalatest.googlecode.com/svn/branches/trenchguinea/maven-scalatest-plugin/" target="_blank">Sean Griffins Repository</a>. Ich habe es mit Teigens Version riskiert, und es scheint zu funktionieren.</li>
<li>Man installiere das Plugin, wie in der Anleitung beschrieben (ebenfalls nur ein kurzer Maven Befehl)</li>
</ol>
<p>Wie verwendet man es nun in dem eigenen Projekt? Ich will es direkt an einem kleinen Beispielprojekt demonstrieren. Dazu lassen wir uns zuerst ein Archetyp-Projekt von maven erzeugen:<br />
<pre class="brush: plain;">
&gt; mvn archetype:generate
[...fürchterlich lange liste mit allen möglichen Archetypen, sorgt dafür dass eure Konsole die letzten paar Tausend Zeilen anzeigen kann...]
Choose a number: 139: 446
Choose version:
1: 1.0
2: 1.1
3: 1.2
4: 1.3
Choose a number: 4:
Define value for property 'groupId': : blog.escalation
Define value for property 'artifactId': : example
Define value for property 'version':  1.0-SNAPSHOT: :
Define value for property 'package':  blog.escalation: :
Confirm properties configuration:
groupId: blog.escalation
artifactId: example
version: 1.0-SNAPSHOT
package: blog.escalation
 Y: : Y
</pre></p>
<p>Nun erstellen wir ein paar Source-Dateien, eine primitive Applikation im main-Ordner, und eine ScalaTest-Suite im test-Ordner:</p>
<p>So sollte die Struktur des Projektes aussehen:<br />
<pre class="brush: plain;">
--example
  |--.gitignore
  |--pom.xml
  `--src
     |--main
     |  `--scala
     |     `--blog
     |        `--escalation
     |           `--App.scala
     `--test
        `--scala
           `--mytestpackage
              `--MyAppSuite.scala
</pre></p>
<p>Die ersten beiden Dateien wurden von <strong>archetype</strong> erzeugt, der src-Ordner wurde ebenfalls automatisch angelegt. Den mytestpackage-Ordner muss man extra erzeugen: Das soll nur zeigen, dass man seine Tests so ordnen kann, wie man will.</p>
<p>So könnten die beiden Scala-Dateien aussehen:<br />
<pre class="brush: scala;">
package blog.escalation

object App {
  
  def foo(x : Array[String]) = x.foldLeft(&quot;&quot;)((a,b) =&gt; a + b)
  
  def main(args : Array[String]) {
    println(&quot;Hello World!&quot;)
    println(&quot;concat arguments = &quot; + foo(args))
  }
}
</pre></p>
<p><pre class="brush: scala;">
package mytestpackage

import org.scalatest.FunSuite
import org.scalatest.matchers.ShouldMatchers
import blog.escalation.App._

class MyAppSuite extends FunSuite with ShouldMatchers{
  
  test(&quot;concatenate words&quot;){
    foo(Array(&quot;hello&quot;, &quot;world&quot;)) should equal (&quot;helloworld&quot;)
  }
  
  test(&quot;reverse hello world&quot;){
    &quot;dlrow olleh&quot;.reverse should equal (&quot;hello world&quot;)
  }
  
  test(&quot;relativity theory test&quot;){
    val E = 90
	val m = 10
    val c = 3
	E should equal (m * c * c)
  }
  
  test(&quot;string theory test&quot;)(pending)
}
</pre></p>
<p>Nun der wichtigste Schritt: pom.xml anpassen. Bevor wir ins Detail gehen, hier die gesamte POM:<br />
<pre class="brush: xml;">
&lt;project xmlns=&quot;http://maven.apache.org/POM/4.0.0&quot; xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot; xsi:schemaLocation=&quot;http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd&quot;&gt;
  &lt;modelVersion&gt;4.0.0&lt;/modelVersion&gt;
  &lt;groupId&gt;blog.escalation&lt;/groupId&gt;
  &lt;artifactId&gt;example&lt;/artifactId&gt;
  &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt;
  &lt;name&gt;${project.artifactId}&lt;/name&gt;
  &lt;description&gt;My wonderfull scala app&lt;/description&gt;
  &lt;inceptionYear&gt;2010&lt;/inceptionYear&gt;
  &lt;licenses&gt;
    &lt;license&gt;
      &lt;name&gt;My License&lt;/name&gt;
      &lt;url&gt;http://....&lt;/url&gt;
      &lt;distribution&gt;repo&lt;/distribution&gt;
    &lt;/license&gt;
  &lt;/licenses&gt;

  &lt;properties&gt;
    &lt;maven.compiler.source&gt;1.5&lt;/maven.compiler.source&gt;
    &lt;maven.compiler.target&gt;1.5&lt;/maven.compiler.target&gt;
    &lt;encoding&gt;UTF-8&lt;/encoding&gt;
    &lt;scala.version&gt;2.9.0&lt;/scala.version&gt;
  &lt;/properties&gt;

  &lt;repositories&gt;
    &lt;repository&gt;
      &lt;id&gt;scala-tools.org&lt;/id&gt;
      &lt;name&gt;Scala-Tools Maven2 Repository&lt;/name&gt;
      &lt;url&gt;http://scala-tools.org/repo-releases&lt;/url&gt;
    &lt;/repository&gt;
  &lt;/repositories&gt;

  &lt;pluginRepositories&gt;
    &lt;pluginRepository&gt;
      &lt;id&gt;scala-tools.org&lt;/id&gt;
      &lt;name&gt;Scala-Tools Maven2 Repository&lt;/name&gt;
      &lt;url&gt;http://scala-tools.org/repo-releases&lt;/url&gt;
    &lt;/pluginRepository&gt;
  &lt;/pluginRepositories&gt;

  &lt;dependencies&gt;
  
    &lt;!-- necessary for compilation of scala code --&gt;
    &lt;dependency&gt;
      &lt;groupId&gt;org.scala-lang&lt;/groupId&gt;
      &lt;artifactId&gt;scala-library&lt;/artifactId&gt;
      &lt;version&gt;${scala.version}&lt;/version&gt;
    &lt;/dependency&gt;

    &lt;!-- IMPORTANT: add dependencies that are necessary for testing --&gt;  
    &lt;dependency&gt;
      &lt;groupId&gt;org.scalatest&lt;/groupId&gt;
      &lt;artifactId&gt;scalatest_2.9.0&lt;/artifactId&gt;
      &lt;version&gt;1.6.1&lt;/version&gt;
      &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
	
	&lt;!-- if you don't need junit, you can leave this dependency out, but maven will download it anyway
	&lt;dependency&gt;
      &lt;groupId&gt;junit&lt;/groupId&gt;
      &lt;artifactId&gt;junit&lt;/artifactId&gt;
      &lt;version&gt;4.8.1&lt;/version&gt;
      &lt;scope&gt;test&lt;/scope&gt;
    &lt;/dependency&gt;
    --&gt;
	
  &lt;/dependencies&gt;

  &lt;build&gt;
    &lt;sourceDirectory&gt;src/main/scala&lt;/sourceDirectory&gt;
    &lt;testSourceDirectory&gt;src/test/scala&lt;/testSourceDirectory&gt;
    
	&lt;!-- IMPORTANT: add this pluginManagement-tag to your POM --&gt;
	&lt;pluginManagement&gt;
	  &lt;plugins&gt;
	    &lt;plugin&gt;
	      &lt;groupId&gt;com.jteigen&lt;/groupId&gt;
	      &lt;artifactId&gt;maven-scalatest-plugin&lt;/artifactId&gt;
	      &lt;version&gt;1.1-SNAPSHOT&lt;/version&gt;
	    &lt;/plugin&gt;
	  &lt;/plugins&gt;
	&lt;/pluginManagement&gt;
	      
	&lt;plugins&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.scala-tools&lt;/groupId&gt;
        &lt;artifactId&gt;maven-scala-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.15.0&lt;/version&gt;
        &lt;executions&gt;
          &lt;execution&gt;
            &lt;goals&gt;
              &lt;goal&gt;compile&lt;/goal&gt;
              &lt;goal&gt;testCompile&lt;/goal&gt;
            &lt;/goals&gt;
            &lt;configuration&gt;
              &lt;args&gt;
                &lt;arg&gt;-make:transitive&lt;/arg&gt;
                &lt;arg&gt;-dependencyfile&lt;/arg&gt;
                &lt;arg&gt;${project.build.directory}/.scala_dependencies&lt;/arg&gt;
				&lt;arg&gt;-deprecation&lt;/arg&gt;
              &lt;/args&gt;
            &lt;/configuration&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
      &lt;/plugin&gt;
	  
	  &lt;plugin&gt;
        &lt;groupId&gt;org.apache.maven.plugins&lt;/groupId&gt;
        &lt;artifactId&gt;maven-surefire-plugin&lt;/artifactId&gt;
        &lt;version&gt;2.6&lt;/version&gt;
        &lt;configuration&gt;
          &lt;useFile&gt;true&lt;/useFile&gt;
          &lt;disableXmlReport&gt;true&lt;/disableXmlReport&gt;
          &lt;includes&gt;
            &lt;include&gt;**/*Test.*&lt;/include&gt;
            &lt;include&gt;**/*Suite.*&lt;/include&gt;
			&lt;include&gt;**/*Spec.*&lt;/include&gt;
          &lt;/includes&gt;
		  &lt;!-- IMPORTANT: if you want to deactivate tests run by surefire-plugin, add this tag: --&gt;
		  &lt;skipTests&gt;true&lt;/skipTests&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
	  
	  &lt;!-- IMPORTANT: this is the plugin we want to use --&gt;
      &lt;plugin&gt;
	    &lt;groupId&gt;com.jteigen&lt;/groupId&gt;
	    &lt;artifactId&gt;maven-scalatest-plugin&lt;/artifactId&gt;
	    &lt;version&gt;1.1-SNAPSHOT&lt;/version&gt;
		&lt;executions&gt;
          &lt;execution&gt;
            &lt;goals&gt;
              &lt;goal&gt;test&lt;/goal&gt;
            &lt;/goals&gt;
          &lt;/execution&gt;
        &lt;/executions&gt;
		&lt;!-- this is the standard way to configure maven-plugins: by adding &quot;configuration&quot;-tag --&gt;
        &lt;configuration&gt;
		  
		  &lt;!-- tell the plugin where your classes are --&gt;
		  &lt;runpath&gt;target/test-classes,target/classes&lt;/runpath&gt;
		  
		  &lt;!-- this just finds all Suites in mytestpackage-package of your test-classes --&gt;
		  &lt;wildcards&gt;mytestpackage&lt;/wildcards&gt;
		  
		  &lt;!-- &quot;W&quot; means &quot;Without color&quot;, it removes the ANSI-color-chars from the output --&gt;
		  &lt;stdout&gt;WD&lt;/stdout&gt;
		  
        &lt;/configuration&gt;		
	  &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/build&gt;
  
  
  &lt;reporting&gt;
    &lt;!-- This is necessary for creating scaladoc --&gt;
    &lt;plugins&gt;
      &lt;plugin&gt;
        &lt;groupId&gt;org.scala-tools&lt;/groupId&gt;
        &lt;artifactId&gt;maven-scala-plugin&lt;/artifactId&gt;
		&lt;version&gt;2.15.0&lt;/version&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;
  &lt;/reporting&gt;
&lt;/project&gt;
</pre></p>
<p>Diese pom.xml unterscheidet sich von der ursprünglichen an vielen Stellen, hier die wichtigsten Punkte:</p>
<ol>
<li>scala.version ist auf 2.9.0 hochgesetzt</li>
<li>scalatest-dependencies sind hinzugefügt</li>
<li>pluginmanagement-Tag im build-Tag hinzugefügt</li>
<li>maven-surefire-plugin mit dem skipTests-Tag deaktiviert.</li>
<li>maven-scalatest-plugin hinzugefügt und konfiguriert.</li>
</ol>
<p>An dieser Stelle einige Worte zur Konfiguration des Plugins. Leider scheint noch keine Beschreibung zu existieren, aber man kann alles nötige aus dem Source-Code herleiten. Beachte dazu folgendes:</p>
<ol>
<li>Die Konfiguration des <strong>maven-scalatest-plugin</strong>s sieht komplett anders aus, als die Konfiguration des Surefire-Plugins, copy-paste ist zwecklos.</li>
<li> Letztendlich leitet das Plugin alle Parameter an <a href="http://www.scalatest.org/scaladoc-1.6.1/#org.scalatest.tools.Runner$" target="_blank">org.scalatest.tools.Runner</a> weiter, deshalb ist es empfehlenswert, sich die Dokumentation anzusehen, damit man weiß, was man alles überhaupt konfigurieren kann.</li>
<li>Alle child-Tags des configuration-Tags werden wie <a href="http://maven.apache.org/guides/mini/guide-configuring-plugins.html#Generic_Configuration" target="_blank">hier</a> beschrieben 1:1 auf Member-Variablen des Plugins gemappt.</li>
<li>Informationen über die relevanten Member-Variablen kann man meiner Meinung nach am besten direkt aus dem <a href="https://github.com/teigen/maven-scalatest-plugin/blob/master/src/main/java/org/scalatest/tools/maven/AbstractScalaTestMojo.java" target="_blank">Source-Code des Plugins</a> ablesen.</li>
</ol>
<p>Einige Beispiele:<br />
1) <strong>runpath</strong><br />
<pre class="brush: xml;">
&lt;runpath&gt;target/test-classes,target/classes&lt;/runpath&gt;
</pre><br />
setzt die runpath-Variable so, dass das Plugin weiss, wo er nach class-Dateien zu suchen hat. Den Kommentaren im Source-Code entnimmt man unter anderem, dass die einzelnen Einträge durch Kommata getrennt werden müssen (und nicht etwa durch Semikolons, oder gar separate Tags).</p>
<p>2) <strong>stdout</strong><br />
<pre class="brush: xml;">
&lt;stdout&gt;WD&lt;/stdout&gt;
</pre><br />
Ausgabe-Optionen (mehr dazu unter <a href="http://www.scalatest.org/scaladoc-1.6.1/#org.scalatest.tools.Runner$" target="_blank">Configuring reporters</a>). Das &#8222;W&#8220; (&#8222;without colors&#8220;) schaltet beispielsweise die Farben aus, die nicht überall funktionieren, und mit &#8222;D&#8220; kann man die &#8222;durations&#8220; ausgeben lassen.</p>
<p>3) <strong>wildcards </strong>und <strong>members</strong><br />
<pre class="brush: xml;">
&lt;suites&gt;mytestpackage.MyAppSuite&lt;/suites&gt;
&lt;members&gt;mytestpackage&lt;/members&gt;
&lt;wildcards&gt;mytestpackage,otherpackage.with.subpackage&lt;/wildcards&gt;
</pre></p>
<p>Damit kann man auswählen, wo nach Suites gesucht werden soll. Mit <strong>suites</strong> kann man eine kommagetrennte Liste von ganz konkreten Suites angeben, was besonders nützlich ist, wenn man <a href="http://www.scalatest.org/scaladoc-1.6.1/#org.scalatest.Suites" target="_blank">die Suites so gruppiert</a>. Mit dem members-Tag kann man eine kommagetrennte Liste von Packages angeben, in der nach Suites gesucht wird. Das wildcards-Tag ist ähnlich, durchsucht aber auch Subpackages, mehr dazu unter <a href="http://www.scalatest.org/scaladoc-1.6.1/#org.scalatest.tools.Runner$" target="_blank">Specifying &#8222;members-only&#8220; and &#8222;wildcard&#8220; Suite paths</a>.</p>
<p>Jetzt, wo die POM fertig ist, können wir beispielsweise alles compilieren und testen:<br />
<pre class="brush: plain;">
&gt;mvn test
</pre><br />
&#8230;was uns die gewünschte Ausgabe liefert:<br />
<pre class="brush: plain;">
Run starting. Expected test count is: 4
DiscoverySuite:
MyAppSuite:
- concatenate words (14 milliseconds)
- reverse hello world (2 milliseconds)
- relativity theory test (1 millisecond)
- string theory test (pending)
Run completed in 364 milliseconds.
Total number of tests run: 3
Suites: completed 2, aborted 0
Tests: succeeded 3, failed 0, ignored 0, pending 1
All tests passed.
</pre></p>
<p>Wer möchte, kann auch gleich alles verpacken:<br />
<pre class="brush: plain;">
&gt;mvn package
</pre><br />
oder beispielsweise eine schicke (bei dem Projekt natürlich erbärmlich kleine) Dokumentation erstellen:<br />
<pre class="brush: plain;">
&gt;mvn scala:doc
</pre><br />
&#8230;die dann im site-Ordner abgelegt wird.</p>
<p>Ich bin jetzt mit dem Zusammenspiel von Scala und Maven vorerst zufrieden, und hoffe, dass dieser Beitrag sich für jemanden als hilfreich erweist.</p>
<p>Grüße, 0x7F800000</p>
<p>Hier nach das <a href="http://www.filesavr.com/NVXLHK4UDUIH4JA" target="_blank">Beispielprojekt </a>zum Download, das jar kann mit<br />
<pre class="brush: plain;">jar -xf example.jar</pre><br />
entpackt werden.</p>
<p>Der Autor weist noch darauf hin, dass es wahrscheinlich schon bald (vielleicht in ein paar Wochen) bessere Lösungen geben wird. Ich möchte mich für die Erlaubnis bedanken, diesen Artikel hier veröffentlichen zu dürfen. Wie immer sind Kritik und Verbesserungsvorschläge jederzeit willkommen. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/764/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/764/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/764/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/764/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/764/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/764/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/764/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/764/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/764/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/764/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/764/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/764/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/764/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/764/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=764&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/10/09/scalatest-mit-maven/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>Multiples Pattern-Matching</title>
		<link>http://dgronau.wordpress.com/2011/09/27/multiples-pattern-matching/</link>
		<comments>http://dgronau.wordpress.com/2011/09/27/multiples-pattern-matching/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 09:45:22 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Pattern Matching]]></category>
		<category><![CDATA[Patternmatching]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Trick]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=752</guid>
		<description><![CDATA[Auf Stackoverflow habe ich schon häufiger die Frage gelesen, wie man es anstellt, dass beim Pattern-Matching nicht nur der erste passende Fall berücksichtigt werden, sondern alle passenden Fälle. Eingebaut gibt es das leider nicht, es ist aber auch nicht schwer zu realisieren. Hier eine recht elegante Version von Philippe: Und die Anwendung: Ich denke, dass [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=752&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Auf Stackoverflow habe ich schon häufiger die Frage gelesen, wie man es anstellt, dass beim Pattern-Matching nicht nur der <em>erste</em> passende Fall berücksichtigt werden, sondern <em>alle</em> passenden Fälle. Eingebaut gibt es das leider nicht, es ist aber auch nicht schwer zu realisieren. Hier eine recht elegante <a href="http://stackoverflow.com/questions/7565599/pattern-matching-with-more-than-one-match" target="_blank">Version von Philippe</a>:</p>
<p><pre class="brush: scala;">
class MatchAll[S](scrutinee : =&gt;S) {
  def matchAll[R](patterns : PartialFunction[S,R]*) : Seq[R] = {
    val evald : S = scrutinee
    patterns.flatMap(_.lift(evald))
  }
}

implicit def anyToMatchAll[S](scrut : =&gt;S) : MatchAll[S] = new MatchAll[S](scrut)
</pre></p>
<p>Und die Anwendung:</p>
<p><pre class="brush: scala;">
(2,4) matchAll (
  { case (2,_) =&gt; &quot;starts with two&quot; },
  { case (3,_) =&gt; &quot;starts with three&quot; },
  { case (_,4) =&gt; &quot;ends with four&quot; },
  { case (a,b) if a + b == 6 =&gt; &quot;adds up to six&quot; }
)

//--&gt; ArrayBuffer(starts with two, ends with four, adds up to six)
</pre></p>
<p>Ich denke, dass man mit der im Vergleich zu match leicht veränderten Syntax gut leben kann, und fände es gut, wenn dieses Konstrukt auch in die Scala-Bibliotheken aufgenommen würde.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/752/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/752/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/752/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/752/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/752/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/752/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/752/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/752/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/752/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/752/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/752/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/752/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/752/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/752/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=752&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/09/27/multiples-pattern-matching/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>Frege &#8211; funktionale Programmierung auf der JVM</title>
		<link>http://dgronau.wordpress.com/2011/09/24/frege-funktionale-programmierung-auf-der-jvm/</link>
		<comments>http://dgronau.wordpress.com/2011/09/24/frege-funktionale-programmierung-auf-der-jvm/#comments</comments>
		<pubDate>Sat, 24 Sep 2011 18:17:28 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Frege]]></category>
		<category><![CDATA[Funktionale Programmierung]]></category>
		<category><![CDATA[Haskell]]></category>
		<category><![CDATA[JVM]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=747</guid>
		<description><![CDATA[Gottlob Frege war ein deutscher Mathematiker und Logiker, der lange vor Alonzo Church über Funktionen mit Funktionen als Argumente nachdachte. Ein schöner Name für eine funktionale Programmiersprache. Die Sprache Frege lehnt sich stark an Haskell an, nutzt aber nach Möglichkeit die Gegebenheiten der JVM aus. Interessanterweise folgt Frege nicht dem üblichen Ansatz, direkt zu Bytecode [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=747&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://de.wikipedia.org/wiki/Gottlob_Frege">Gottlob Frege</a> war ein deutscher Mathematiker und Logiker, der lange vor Alonzo Church über Funktionen mit Funktionen als Argumente nachdachte. Ein schöner Name für eine funktionale Programmiersprache.</p>
<p>Die Sprache <a href="http://code.google.com/p/frege/">Frege</a> lehnt sich stark an Haskell an, nutzt aber nach Möglichkeit die Gegebenheiten der JVM aus. Interessanterweise folgt Frege nicht dem üblichen Ansatz, direkt zu Bytecode zu compilieren, es erstellt stattdessen erst Java-Klassen (die allerdings weniger zur Abendlektüre geeignet sind) und ruft für diese den Java-Compiler auf. </p>
<p>Die auffälligsten <a href="http://frege.googlecode.com/files/differences-166.pdf" target="_blank">Unterschiede zu Haskell</a> sind die Übernahme des Package-Prinzips und von Private-Modifiern (statt Exportlisten) sowie die Nutzung nativer Strings und Primitive. Einige syntaktische Seltsamkeiten von Haskell wurden gestrichen, aber insgesamt fallen die Unterschiede gering aus. </p>
<p>Die Auswahl an Bibliotheken ist überschaubar und auch das Prelude (das Analogon zum Package java.lang) weist noch einige Lücken auf. Trotzdem macht das Vorhandene einen recht soliden Eindruck, es ist genug Dokumentation zum Loslegen vorhanden und es macht Spaß, ein wenig mit Frege herumzuspielen. Wenn die Kernsprache erst einmal stabil ist, sollte es kein Problem sein, geeignete Haskell-Bibliotheken mit geringen Anpassungen zu übernehmen. Außerdem ist auch der Zugriff auf Java-Bibliotheken ebenfalls recht unkompliziert möglich. </p>
<p>Die vorhandenen Ansätze lassen einen umsichtigen Umgang  mit Typklassen erkennen (z.B. werden Funktionen wie null oder length verallgemeinert, so dass sie nicht nur auf Listen arbeiten). Das lässt darauf hoffen, dass bei künftigen Erweiterungen der Typklassen-Hierarchie einige von Haskells Fehlern vermieden werden.</p>
<p>Frege ist eine interessante Alternative zu den anderen JVM-Sprachen, deshalb hoffe ich sehr, dass dieses ambitionierte Projekt vorankommt und sich eine Community herausbildet. </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/747/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/747/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/747/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/747/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/747/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/747/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/747/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/747/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/747/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/747/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/747/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/747/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/747/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/747/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=747&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/09/24/frege-funktionale-programmierung-auf-der-jvm/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>Scala für Android mit Eclipse leicht gemacht</title>
		<link>http://dgronau.wordpress.com/2011/08/20/scala-fur-android-mit-eclipse-leicht-gemacht/</link>
		<comments>http://dgronau.wordpress.com/2011/08/20/scala-fur-android-mit-eclipse-leicht-gemacht/#comments</comments>
		<pubDate>Fri, 19 Aug 2011 22:02:22 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Setup]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=739</guid>
		<description><![CDATA[Ich habe bisher keine Android-Ambitionen, aber sicher einige von euch, und so habe ich diesen sehr ausführlichen Beitrag mit Erlaubnis des Autors Yves für euch übersetzt. Da ich die Anleitung nicht selbst nachvollzogen habe, kann es eventuell zu Ungenauigkeiten gekommen sein, also korrigiert mich bitte, wenn euch etwas auffällt. Scala für Android mit Eclipse leicht [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=739&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ich habe bisher keine Android-Ambitionen, aber sicher einige von euch, und so habe ich <a href="http://scala-forum.org/read.php?4,503,503#msg-503" target="_blank">diesen sehr ausführlichen Beitrag</a> mit Erlaubnis des Autors Yves für euch übersetzt. Da ich die Anleitung nicht selbst nachvollzogen habe, kann es eventuell zu Ungenauigkeiten gekommen sein, also korrigiert mich bitte, wenn euch etwas auffällt.</p>
<p><strong>Scala für Android mit Eclipse leicht gemacht</strong></p>
<p>Man kann mit Scala auf Android entwickeln, und es ist nicht besonders schwierig. Trotzdem habe ich ein paar Tage gebraucht um alle relevanten Informationen zu sammeln, und eine Konfiguration zum Laufen zu bringen. Ich denke, dass euch das interessieren könnte, insbesondere weil man nicht einmal 15 Minuten braucht, um eine Umgebung aufzusetzen.</p>
<p>Ich bin der Ansicht, dass man als Entwickler die Möglichkeit haben sollte, so oft compilieren und testen zu können wie nötig. Alles, was einen ausbremst, wie zusätzliche Schritte im Build-Prozess (Treeshaker, ProGuard mit einem Ant-Build), sollte vermieden werden. Ich gehe davon aus, dass während des Entwicklungsprozesses vorwiegend das Android Virtual Device anstatt das tatsächlichen Gerätes verwendet wird. Weiterhin setze ich voraus, dass du kein Ant verwenden willst, sondern wie ich den integrierten Eclipse-Buildprozess.</p>
<p>Wenn Android neu für dich ist (wie es für mich war), kann es nicht schaden, ein paar Grundlagen zu kennen (für Android SDK 12):</p>
<ul>
<li>Eine Eclipse-Umgebung für Android aufzusetzen ist nicht schwer. Das ADT-Plugin ist einfach zu installieren und zu benutzen.</li>
<li>Wahrscheinlich möchtest du wenigstens ein Android Virtual Device (AVD) aufsetzen, um dein Programm testen zu können (wenn du auf einem echten Gerät testen willst, gilt dieser Tipp nicht für dich)</li>
<li> Eine Android-Anwendung ist eine einzelne .apk-Datei, und diese kann keine Bibliotheken außer denen von Android verwenden. Das heißt, dass die Anwendung alle Bibliotheken enthalten muss, die man verwenden will. Oder man kann das Gerät so manipulieren, dass es zusätzliche Bibliotheken lädt, aber das ist natürlich keine Lösung für Anwendungen, die verteilt werden sollen.</li>
<li> Man verwendet Java/Scala zur Entwicklung, aber Android benutzt eine eigene, spezielle VM (Dalvik), und der Code muss von .class-Dateien zu Plattform-Code compiliert werden. Das wird vom dx-Compiler erledigt (man kann ihn direkt in den SDK-Tools aufrufen, aber das ist normalerweise unnötig), der eine classes.dex-Datei erzeugt. Diese Datei enthält alle Klassen der Applikation, ähnlich wie ein Jar. Das dx-Tool und die Dalvik-Plattform akzeptieren nicht alles: Einige Klassen compilieren mit dx, werden aber nicht korrekt von Dalvik geladen, und das dx-Tool ist ziemlich beschränkt bezüglich der Menge an Code, mit der es zurechtkommt. Man verwendet Werkzeuge, um den Code und die Bibliotheken auf das absolute Minimum abzuspecken (Treeshaker, ProGuard.). Insbesondere kann dx nicht die vollständige Scala-Bibliothek verarbeiten (zu groß), und Dalvik kommt nicht mit Version 2.9.0 zurecht (es scheitert beim Laden).</li>
<li>Das SDK enthält einige nützliche Werkzeuge, besonders adb, womit man bestimmte Befehle an ein laufendes virtuelles Gerät senden kann (und wahrscheinlich auch an ein echtes, aber das habe ich nicht probiert). Insbesondere kann man mit dem &#8222;adb shell&#8220;-Kommando einige eingeschränkte Unix-Befehle senden. Die Details sind im SDK beschrieben. Aber vermutlich wirst du damit nicht allzuviell zu tun haben.</li>
</ul>
<p>Demnach ist das Problem, was wir mit Scala haben, dass wir alles von uns benötigte aus der Scala-Bibliothek in die Android-Anwendung packen müssen, aber das funktioniert nicht, weil das Ergebnis zu groß für dx ist. Die normale Lösung ist, dem Build einen Schritt zum Zurechtstutzen des Codes hinzuzufügen, aber das erfordert die Verwendung einen eigenen Ant-Builds. Das beim ADT mitgelieferte ProGuard läuft nur, wenn man tatsächlich die Applikation auf ein Gerät exportiert, um sie dort auszuführen, aber nicht bei normalen Durchläufen, und selbst wenn das möglich wäre, würde natürlich der Schrumpf-Schritt jedesmal ausgeführt werden, wenn man speichert und neu compiliert. Das wollen wir nicht.</p>
<p>Stattdessen muss die Umgebung, die wir haben wollen, die Scala-Bibliotheken innerhalb des virtuellen Gerätes bereitstellen (so dass dem Build-Prozess entgehen). Dazu bedienen wir uns Tipps von folgenden Seiten:</p>
<ul>
<li>(A) <a href="http://lamp.epfl.ch/~michelou/android/emulator-android-sdk.html" target="_blank">Tweaking the Android Emulator</a></li>
<li>(B) <a href="http://lamp.epfl.ch/~michelou/android/" target="_blank">Exploring Android</a></li>
</ul>
<p>Die erste Seite verlinkt eine Liste vorcompilierter Ramdisks für Android. Ich nehme api_10, aber du kannst auch andere verwenden. Die zweite Seite verweist auf einige vorcompilierte Jars für Android. Dazu später mehr.</p>
<p>Selbstverständlich wollen wir die aktuellsten verfügbaren Werkzeuge:</p>
<ul>
<li><a href="http://www.eclipse.org/downloads/" target="_blank">Eclipse 3.7 (Indigo)</a></li>
<li><a href="http://developer.android.com/sdk/index.html" target="_blank">Android SDK release 12</a></li>
<li><a href="https://dl-ssl.google.com/android/eclipse" target="_blank">ADT Plugin</a></li>
<li>Scala 2.9.0; allerdings sind wir hier aufgeschmissen, weil diese Version von Scala nach dem Compilieren für Android nicht richtig lädt (es gibt ein Problem in den Collections-Packages), deshalb verwenden wir Scala 2.8.1, das funktioniert. Und da wir ein Plugin benötigen, das unter Eclipse 3.7 arbeitet, werden wir das experimentelle 2.8.2 Release verwenden (<a href="http://download.scala-ide.org/nightly-update-wip-experiment-2.8.2-SNAPSHOT" target="_blank">Update-Seite</a>)</li>
</ul>
<p>Nun zum Kern der Sache:</p>
<ul>
<li>Lade Eclipse Indigo (3.7) herunter und installiere es</li>
<li>Lade das Android SDK 12 herunter und installiere es</li>
<li>Installiere das Android ADT Plugin</li>
<li>Setze den SDK-Pfad in Einstellungen =&gt; Android</li>
<li>Lade das Android Ramdisk Image von (A) für die von dir gewünschte(n) Version(en) herunter</li>
<li>Suche darin die für dich passende ramdisk.img-Datei und kopiere sie ins Verzeichnis {android-sdk}/platforms/android-XX/images (du solltest vorher eine Kopie der ursprünglichen ramdisk.img-Datei sichern)</li>
<li>Erstelle ein virtuelles Gerät entsprechen der gerade von dir geänderten Verion. Du kannst dazu den AVD-Manager verwenden, der in Eclipse integriert ist, nacdem das ADT-Plugin installiert wurde.</li>
<li>Starte das virtuelle Gerät. Das wird etwas dauern. Nutze die Zeit für die folgenden drei Schritte.</li>
<li>Installiere das Scala-Plugin für Version 2.8.2</li>
<li>Lade von (B) die vorbereiteten Scala-Bibliotheken mit Version 2.8.1 herunter (nciht vergessen, 2.9.0 lädt nicht korrekt in Android!)</li>
<li>Entpacke sie und öffne eine Shell (cmd unter Windows), und gehe dann in das Verzeichnis, in das du die 5 Scala Jars entpackt hast.</li>
<li>Nachdem das virtuelle Gerät bereit ist, sende die folgenden Befehle in der Shell:
<ul>
<li> {android-sdk}/platform-tools/adb shell mkdir -p /data/framework (wenn das nicht klappt, hast du etwas in einem der vorherigen Schritte vergessen)</li>
<li> {android-sdk}/platform-tools/adb push scala-library.jar /data/framework</li>
<li> {android-sdk}/platform-tools/adb push scala-collection.jar /data/framework</li>
<li> {android-sdk}/platform-tools/adb push scala-immutable.jar /data/framework</li>
<li> {android-sdk}/platform-tools/adb push scala-mutable.jar /data/framework</li>
<li> {android-sdk}/platform-tools/adb push scala-actors.jar /data/framework</li>
<li> {android-sdk}/platform-tools/adb shell sync</li>
</ul>
</li>
<li>Schließe das virtuelle Geräte und starte es neu (ich bin nicht sicher, ob das erforderlich ist)</li>
<li>Erstelle ein neues Android-Projekt in Eclipse</li>
<li>Füge irgendwo eine Scala-Datei hinzu, und rechts-klicke dann auf das Projekt: Konfiguration =&gt; Scala Natur hinzufügen</li>
</ul>
<p>Fertig! Du kannst nun sowohl in Java wie auch in Scala entwickeln. Ich würde dringend davon abraten die Android Activity-Klasse zu &#8222;scalafizieren&#8220;, die für dich erstellt wurde. Speichern und Kompilieren ist so schnell wie man es sich wünscht. Der Programmablauf ist nur durch die Art des Emulators beschränkt, nicht durch die Verwendung von Scala.</p>
<p>Ich überlasse euch selbst den letzten, ultimativen Schritt der Verteilung der Anwendung auf ein Gerät. Wenn ihr das Projekt korrekt konfiguert habt, denke ich aber, dass das ProGuard (der dann und nur dann verwendet wird, wenn die Anwendung wirklich exportiert wird) problemlos erledigen wird.</p>
<p>Yves</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/739/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/739/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/739/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/739/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/739/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/739/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/739/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/739/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/739/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/739/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/739/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/739/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/739/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/739/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=739&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/08/20/scala-fur-android-mit-eclipse-leicht-gemacht/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>Resteverwertung</title>
		<link>http://dgronau.wordpress.com/2011/07/25/resteverwertung/</link>
		<comments>http://dgronau.wordpress.com/2011/07/25/resteverwertung/#comments</comments>
		<pubDate>Mon, 25 Jul 2011 16:42:40 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Extraktoren]]></category>
		<category><![CDATA[Pattern Matching]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=732</guid>
		<description><![CDATA[Als Ergänzung zu meinem Pattern-Matching-Artikel heute ein kleiner Trick, der mir eher zufällig über den Weg gelaufen ist. Ich hatte dazumal folgendes Codebeispiel gebracht, um zu zeigen, wie man die restlichen Elemente einer Collection beim Pattern Matching erfolgreich ignorieren kann: Jetzt fragt man sich natürlich, wie man vorgehen muss, wenn man den Rest eben nicht [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=732&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Als Ergänzung zu meinem <a href="http://dgronau.wordpress.com/2010/04/29/musterlosung-patternmatching/" title="Musterlösung Pattern Matching">Pattern-Matching-Artikel</a> heute ein kleiner Trick, der mir eher zufällig über den Weg gelaufen ist. </p>
<p>Ich hatte dazumal folgendes Codebeispiel gebracht, um zu zeigen, wie man die restlichen Elemente einer Collection beim Pattern Matching erfolgreich ignorieren kann:</p>
<p><pre class="brush: scala;">
def test(list: List[String]) = list match {
  case List(&quot;1&quot;,&quot;2&quot;, _*) =&gt; &quot;one, two ...&quot;
  case _ =&gt; &quot;dunno&quot;
}
</pre></p>
<p>Jetzt fragt man sich natürlich, wie man vorgehen muss, wenn man den Rest eben <strong>nicht</strong> ignorieren will, sondern auch diesen an eine Variable gebunden haben möchte. Die &#8222;naive&#8220; Lösung mit etwas wie rest* funktioniert jedenfalls schon einmal nicht. Aber es geht trotzdem, und zwar dank Klammeraffen:</p>
<p><pre class="brush: scala;">
def test(list: List[String]) = list match {
  case List(&quot;1&quot;,&quot;2&quot;, rest @ _*) =&gt; &quot;one, two with rest &quot; + rest
  case _ =&gt; &quot;dunno&quot;
}

test(List(&quot;1&quot;,&quot;2&quot;,&quot;3&quot;,&quot;4&quot;))
//--&gt; java.lang.String = one, two with rest List(3, 4)
</pre></p>
<p>Achtung, der Rest kann natürlich auch eine leere Liste sein. Für Listen ist dieser Trick eigentlich unnötig, denn hier hat man ja schon den Extraktor ::, aber das Ganze funktioniert natürlich auch für andere Extraktoren mit variabler Argumentanzahl, wie z.B. Seq.</p>
<p>So, dann wünsche ich fröhliches Extrahieren, vor allem meinen Erstlesern bei <a href="http://codekicker.de/" title="Codekicker" target="_blank">codekicker.de</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/732/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/732/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/732/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=732&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/07/25/resteverwertung/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>Wasch mich, aber mach mich nicht nass!</title>
		<link>http://dgronau.wordpress.com/2011/07/20/wasch-mich-aber-mach-mich-nicht-nass/</link>
		<comments>http://dgronau.wordpress.com/2011/07/20/wasch-mich-aber-mach-mich-nicht-nass/#comments</comments>
		<pubDate>Wed, 20 Jul 2011 21:09:55 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Ceylon]]></category>
		<category><![CDATA[Gosu]]></category>
		<category><![CDATA[Kotlin]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=728</guid>
		<description><![CDATA[Es ist kein Geheimnis: Java macht keinen richtigen Spaß mehr, wenn man es mit anderen modernen Sprachen vergleicht. Was macht man, wenn man weiter die JVM und die unzähligen Java-Bibliotheken nutzen will? Richtig, man schaut kräftig beim Marktführer Scala ab, und schreibt eine eigene Sprache. Die natürlich besser ist. So geschehen bei Gosu, RedHat&#8217;s Ceylon [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=728&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Es ist kein Geheimnis: Java macht keinen richtigen Spaß mehr, wenn man es mit anderen modernen Sprachen vergleicht. Was macht man, wenn man weiter die JVM und die unzähligen Java-Bibliotheken nutzen will? Richtig, man schaut kräftig beim Marktführer Scala ab, und schreibt eine eigene Sprache. Die natürlich besser ist. So geschehen bei <a href="http://gosu-lang.org/" title="Gosu" target="_blank">Gosu</a>,  RedHat&#8217;s <a href="http://en.wikipedia.org/wiki/Ceylon_Project" title="Ceylon" target="_blank">Ceylon</a> und nun JetBrain&#8217;s <a href="http://confluence.jetbrains.net/display/Kotlin/Welcome" title="Kotlin" target="_blank">Kotlin</a>.</p>
<p>Ich finde das traurig. Richtig, es heißt &#8222;Konkurrenz belebt das Geschäft&#8220;, aber diese drei Sprachen sind unnötig wie ein Kropf. Es stimmt, Scala kann kompliziert sein und hat auch einige weniger schöne Stellen. Auf der anderen Seite ist es einsteigerfreundlich, innovativ und mächtig, aber vor allem ist es <strong>da</strong>. Es hat lange gebraucht, um wirklich Bewegung in die Sache zu bringen, eine Community aufzubauen, Tool-Support zu organisieren, ja überhaupt wahrgenommen zu werden. Was inzwischen fast wie ein Selbstläufer aussieht, ist das Ergebnis langer, harter Arbeit. Ich denke, die neuen Sprachschöpfer unterschätzen diesen Aspekt einer Sprache ganz gewaltig.</p>
<p>Viel eigene Innovation ist bei keinem der Kandidaten zu sehen. Aber was mich wirklich stört, ist der Versuch, sich nur die Rosinen aus dem Kuchen zu picken. Das ist nämlich die Art von Geisteshaltung, die Java&#8217;s Stillstand erst verursacht hat. Eine gute Sprache ist offen für neue Entwicklungen, und lenkt diese in geordnete Bahnen. Gerade diese Offenheit macht Scala so attraktiv. Doch die Strategie der neuen Sprachen ist die gleiche wie Java: Wasch mich, aber mach mich nicht nass! Features, die &#8222;zu kompliziert&#8220; sind oder eventuell missbraucht werden können, werden abgelehnt. In Java waren das etwa Operator-Überladungen, Closures oder Konzepte zur Erweiterung von Interfaces (wie Extensionsmethoden oder Mixins). Jetzt werden aus den gleichen fadenscheinigen Gründen Dinge wie implizite Umwandlungen, abstrakte Typ-Member oder Typpolymorphismus höherer Ordnung abgelehnt &#8211; obwohl diese Ideen längst den Praxistest bestanden haben. Was immer wieder übersehen wird ist, dass viele Features, die für die tägliche Arbeit unnötig scheinen, in Bibliotheken und Frameworks essentiell sein können: Jeder, der in Scala eine Liste mapped, verwendet dabei Typpolymorphismus höherer Ordnung &#8211; aber er muss dazu nicht einmal wissen, was das ist.</p>
<p>Ich denke dass für viele Detail-Lösungen der neuen Sprachen auch Platz in Scala gewesen wäre, wenn die Macher auf Kooperation gesetzt hätten. Aber jetzt wird viel Arbeit und Gehirnschmalz in Dinge investiert, die es zum größten Teil schon gibt, und Projekte gestartet, die keinen Erfolg haben können. Ein Blick in die Geschichte zeigt, was mit gut gemeinten, aber zu konservativen Ansätzen passiert: <a href="//sourceforge.net/projects/nice/forums/forum/40268" title="Nice" target="_blank">Nice</a> hatte viele gute Ideen und nette Details, aber nicht genug, um die Java-Community wirklich zu begeistern, und neue Perspektiven zu eröffnen. </p>
<p>Ich will kein aufgehübschtes Java, und auch kein weichgespültes Scala. Sicher ist es nett, wenn hier und da eine Syntax-Kante geglättet wird. Aber wenn mir am Ende die Ausdrucksstärke fehlt, um meine Gedanken in Code umzusetzen, nützt mir das alles nichts. Ich will keine Sprache zwischen Java und Scala &#8211; wenn überhaupt, dann zwischen Scala und Haskell, mit mehr Abstraktionsmöglichkeiten, nicht weniger. Scala ist sicher nicht der Endpunkt der Entwicklung, aber es schwimmt in die richtige Richtung. Nass, aber sauber. </p>
<p><strong>Update</strong></p>
<p>Hier noch ein interessanter Blog-Post, der in die gleiche Richtung und dabei etwas mehr ins Detail geht: <a href="http://ochsenreither.posterous.com/scala-kotlin-ceylon-lets-start-by-being-hones" title="Scala, Kotlin, Ceylon... let's start by being honest" target="_blank">Scala, Kotlin, Ceylon&#8230; let&#8217;s start by being honest</a>.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/728/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/728/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/728/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=728&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/07/20/wasch-mich-aber-mach-mich-nicht-nass/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
		<item>
		<title>Interview</title>
		<link>http://dgronau.wordpress.com/2011/07/16/interview/</link>
		<comments>http://dgronau.wordpress.com/2011/07/16/interview/#comments</comments>
		<pubDate>Sat, 16 Jul 2011 19:50:08 +0000</pubDate>
		<dc:creator>dgronau</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Interview]]></category>
		<category><![CDATA[Martin Odersky]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://dgronau.wordpress.com/?p=725</guid>
		<description><![CDATA[Normalerweise poste ich nicht einfach nur Links, das kann Planet Scala besser. Aber beim Interview von Martin Odersky auf Dr. Dobbs mache ich eine Ausnahme: Es ist wirklich lesenswert, weil es hier nicht nur um aktuelle Probleme, sondern auch die allgemeine Richtung geht, die die Sprache in der Zukunft nehmen soll.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=725&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Normalerweise poste ich nicht einfach nur Links, das kann <a href="http://planetscala.com/" target="_blank">Planet Scala</a> besser. Aber beim <a href="http://drdobbs.com/231001802?pgno=2" target="_blank">Interview von Martin Odersky auf Dr. Dobbs</a> mache ich eine Ausnahme: Es ist wirklich lesenswert, weil es hier nicht nur um aktuelle Probleme, sondern auch die allgemeine Richtung geht, die die Sprache in der Zukunft nehmen soll.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/dgronau.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/dgronau.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/dgronau.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/dgronau.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/dgronau.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/dgronau.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/dgronau.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/dgronau.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/dgronau.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/dgronau.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/dgronau.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/dgronau.wordpress.com/725/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/dgronau.wordpress.com/725/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/dgronau.wordpress.com/725/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=dgronau.wordpress.com&amp;blog=8670383&amp;post=725&amp;subd=dgronau&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://dgronau.wordpress.com/2011/07/16/interview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/f3d9d9e9af7ac805975b66d4a028fc18?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">dgronau</media:title>
		</media:content>
	</item>
	</channel>
</rss>
