<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><atom:link rel="hub" href="http://tumblr.superfeedr.com/" xmlns:atom="http://www.w3.org/2005/Atom"/><description>on programming and related topics</description><title>ingo_schramm() Tech</title><generator>Tumblr (3.0; @ingoschramm)</generator><link>http://ingoschramm.tumblr.com/</link><item><title>Languages Are Overrated</title><description>&lt;p&gt;By many people I met over the years of my professional career as a software engineer, programming languages seem to be vastly overrated. Every now and then I see a battle of this language against that language and a flame war and a shit storm. To what extend - I don&amp;#8217;t know.&lt;/p&gt;
&lt;p&gt;For me, languages are tools, no more no less. They are tools for humans to formulate repeatable problem solutions in a way a computer &lt;em&gt;and&lt;/em&gt; other humans can deal with. Some languages fit better to that solution and some to another. Some ecosystems have that benefit and that drawback, some another. But, no single language supports you in finding the solution for the problem in question. And that&amp;#8217;s the crucial point of engineering, to find solutions. Programming, in essence, is selection or creation of Algorithms, and not simply coding.&lt;/p&gt;
&lt;p&gt;I never made a big deal about the language I use, and I used a lot. If I have to learn another, I do it, simple as that. Sure, I have a sense of beauty or smartness of a particular language, but in the end of the day I try to choose the right tool for my particular solution. And that&amp;#8217;s what I care about the most, the solution, the algorithm. Moreover, this is the right starting point for optimizations by the way. I even helped optimizing code in languages I never used before just by analyzing the algorithmic complexity of the particular solution, an approach many programmers obviously have forgotten while discussing questions like: which language is the fastest.&lt;/p&gt;
&lt;p&gt;It&amp;#8217;s rather similar to what Nietzsche once said - who spoke a number of contemporary and ancient languages fluently -: it does not count how many languages you do know or do not know, what counts is if you have something to say in the first place. This is why I spent more time reading papers or books about algorithms instead of the most fancy &amp;#8220;Programming in XYZ&amp;#8221;. If one has something to say, he or she will find a way to say it. If one has not - no language can help.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/40004829636</link><guid>http://ingoschramm.tumblr.com/post/40004829636</guid><pubDate>Tue, 08 Jan 2013 11:12:39 +0100</pubDate><category>programming</category><category>programming languges</category></item><item><title>Jun Fukuyama's P≠NP Page</title><description>&lt;a href="http://junfukuyama.wordpress.com/"&gt;Jun Fukuyama's P≠NP Page&lt;/a&gt;</description><link>http://ingoschramm.tumblr.com/post/37704949758</link><guid>http://ingoschramm.tumblr.com/post/37704949758</guid><pubDate>Tue, 11 Dec 2012 10:04:30 +0100</pubDate><category>computer science</category><category>mathematics</category></item><item><title>Go Standard Library Web Server Rocks</title><description>&lt;p&gt;These days I&amp;#8217;m doing my first steps in the Go programming language. Today I wrote my web server hello world and I&amp;#8217;m really excited. All I had to do was to write these lines of code.&lt;/p&gt;
&lt;pre&gt;package main

import (
	"runtime"
	"fmt"
	"flag"
	"net/http"
	"strconv"
)

func main() {
	// command line argments
	port     := flag.Int("port", 8000, "http port")
	maxprocs := flag.Int("maxprocs", 1, "GOMAXPROCS")
	flag.Parse()

	// setup processor usage
	runtime.GOMAXPROCS(*maxprocs)

	// http handler
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		fmt.Fprintf(w, "Hello, %s", "world")
	})

	// http server
	s := &amp;amp;http.Server{
		Addr: ":" + strconv.Itoa(*port),
	}
	s.ListenAndServe()
}
&lt;/pre&gt;
&lt;p&gt;Compilation took less than a second, then I could start the server:&lt;/p&gt;
&lt;p&gt;  $ bin/web -port=8000 -maxprocs=4&lt;/p&gt;
&lt;p&gt;send some requests:&lt;/p&gt;
&lt;p&gt;  $ ab -c 100 -n 1000000 http://localhost:8000/&lt;/p&gt;
&lt;p&gt;and this is what ab told me about performance:&lt;/p&gt;
&lt;p&gt;  Requests per second:    23454.77 [#/sec] (mean)&lt;/p&gt;
&lt;p&gt;During that quick test, the web server allocated about 8MB of resident memory, while ab needed 34MB.&lt;/p&gt;
&lt;p&gt;Sure, this thing does nothing useful. And also sure, I can reach similar numbers with an embedded Jetty or a POCO C++ embedded web server, but all I had to do to get this to work was to install Go, write that small code snippet and compile. No Maven XML, no painful dependency resolution, just some calls into the standard library and that&amp;#8217;s it. Moreover, I have a single statically linked binary, 3.8MB in size, that I could deploy to whatever 64bit-Linux box I want.&lt;/p&gt;
&lt;p&gt;This is practically amazing.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/28568862936</link><guid>http://ingoschramm.tumblr.com/post/28568862936</guid><pubDate>Thu, 02 Aug 2012 20:35:00 +0200</pubDate><category>programming</category><category>go</category><category>performance</category></item><item><title>MVC, MOVE - Or Simply A State Machine?</title><description>&lt;p&gt;In a blog I recently read, Conrad Irwin extends the well known MVC pattern to a MOVE pattern (&lt;a href="http://cirw.in/blog/time-to-move-on" target="_blank"&gt;&lt;a href="http://cirw.in/blog/time-to-move-on" target="_blank"&gt;http://cirw.in/blog/time-to-move-on&lt;/a&gt;&lt;/a&gt;). While his critics of MVC meets the right point (&amp;#8220;&amp;#8230; but the problem with MVC as given is that you end up stuffing too much code into your controllers &amp;#8230;&amp;#8221;) I cannot see what MOVE does better. It seems to be slightly more complex - and that&amp;#8217;s what I would criticize.&lt;/p&gt;
&lt;p&gt;What if we simplify things? All we need to get a separation of UI from data and processing in a stateful application are Views and a State Machine. And that&amp;#8217;s all what MVC already is in its very core. We have a state machine with transitions initiated by events from the outside world and some kind of frontier or surface or membrane between that world and the state machine. That surface is what we know as View.&lt;/p&gt;
&lt;p&gt;The view is a window into state with a given perspective. Not all may be visible through a given window, some state may be hidden, but moving over the surface will expose all state eventually. At some points at the surface we have sensory cells (those buttons) firing events into the state machine when touched, causing transition. And that&amp;#8217;s what most MVC applications already do.&lt;/p&gt;
&lt;p&gt;The perception of burdened controllers (and often views as well) is in essence caused by the fact that they simply doesn&amp;#8217;t exist. Partly they are elements of the &amp;#8220;M&amp;#8221; - for Machine, partly elements of the &amp;#8220;V&amp;#8221; for View. And if you want a clean architecture based on a well understood computational structure, all you have to do is to accept the fact of having a State Machine and Views of state and nothing more.&lt;/p&gt;
&lt;p&gt;BTW I willingly omitted the &amp;#8220;F&amp;#8221; of the (F)SM since this might be subject of discussion here, despite the fact that &amp;#8220;infinite&amp;#8221; is really huge in the world of computation.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/26409997578</link><guid>http://ingoschramm.tumblr.com/post/26409997578</guid><pubDate>Tue, 03 Jul 2012 10:32:00 +0200</pubDate><category>patterns</category><category>architecture</category></item><item><title>Hardware Neural Networks: Future Of Computing?</title><description>&lt;a href="http://arxiv.org/abs/1206.3227"&gt;Hardware Neural Networks: Future Of Computing?&lt;/a&gt;</description><link>http://ingoschramm.tumblr.com/post/25353874268</link><guid>http://ingoschramm.tumblr.com/post/25353874268</guid><pubDate>Mon, 18 Jun 2012 10:46:05 +0200</pubDate></item><item><title>Making a singular matrix non-singular</title><description>&lt;a href="http://www.johndcook.com/blog/2012/06/13/matrix-condition-number/"&gt;Making a singular matrix non-singular&lt;/a&gt;</description><link>http://ingoschramm.tumblr.com/post/25091193252</link><guid>http://ingoschramm.tumblr.com/post/25091193252</guid><pubDate>Thu, 14 Jun 2012 16:33:17 +0200</pubDate></item><item><title>Handle Huge Data With C++ and STXXL</title><description>&lt;p&gt;If you ever have to deal with really huge data that does not fit in RAM  anymore, but you still need a consistent interface and efficient  handling - and you have not the time to write it yourself, as usual -  have a look at STXXL. It has some downsides, but after all it works well  and efficiently. For me it was the fastest way - both in runtime and  implementation time - to deal with data in the TB range.&lt;/p&gt;
&lt;p&gt;You may find it here: &lt;a href="http://stxxl.sourceforge.net/" title="http://stxxl.sourceforge.net " target="_blank"&gt;&lt;a href="http://stxxl.sourceforge.net" target="_blank"&gt;http://stxxl.sourceforge.net&lt;/a&gt;&lt;/a&gt;&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/15717160222</link><guid>http://ingoschramm.tumblr.com/post/15717160222</guid><pubDate>Thu, 12 Jan 2012 10:24:00 +0100</pubDate><category>programming</category><category>c++</category><category>big data</category></item><item><title>Clustering RabbitMQ</title><description>&lt;p&gt;Clustering RabbitMQ is very easy - if you know how. Unfortunately, the documentation on this topic is good but not good enough (cf. &lt;a href="http://www.rabbitmq.com/clustering.html" title="RabbitMQ Clustering" target="_blank"&gt;RabbitMQ Clustering&lt;/a&gt;). If you try to do it, you may get lost on the track until you find some insightful posts on the mailing list. This is why I summarize here how I got it to work.&lt;/p&gt;
&lt;p&gt;Say, you want to create a cluster having two disc nodes and two ram nodes. If you do this on at least two machines, each having a disc and a ram node you achieve good fault tolerance and good scalability both with one setup. Your clients may connect to the ram nodes only or these are balanced by an additional load balancer.&lt;/p&gt;
&lt;p&gt;But, how do I make a node a disc node and another node a ram node?&lt;/p&gt;
&lt;p&gt;There&amp;#8217;s no such command like &amp;#8220;rabbitmqctl mkdisc&amp;#8221; and there is no related configuration option. On one hand, this is a little counter intuitive, on the other hand this adds a lot of flexibility since you may alter the roles of nodes and restructure your cluster on the fly whenever necessary.&lt;/p&gt;
&lt;p&gt;The rules are assigned by the way you call the &amp;#8220;rabbitmqctl cluster&amp;#8221; command. In our scenario, we have multiple nodes on the same host, so we need to wrap the calls to &amp;#8220;rabbitmqctl&amp;#8221; into shellscripts setting some environment variables (cf. &lt;a href="http://www.rabbitmq.com/configure.html" title="RabbitMQ Configuration" target="_blank"&gt;RabbitMQ Configuration&lt;/a&gt;). If this has been done, you ensure all nodes of the cluster are running. Afterwards you execute a sequence of &amp;#8220;stop_app&amp;#8221;, &amp;#8220;reset&amp;#8221;, &amp;#8220;cluster&amp;#8221;, &amp;#8220;start_app&amp;#8221; commands for all nodes. If it comes to the &amp;#8220;cluster&amp;#8221; command, you add a space separated list of all disc nodes you want to create to the &amp;#8220;cluster&amp;#8221; command executed for each node. My mnemonic for this is that you &lt;em&gt;copy&lt;/em&gt; the current node to all disc nodes. The whole sequence may look like this, with &amp;#8220;rbctl.*&amp;#8221; being your wrapper scripts:&lt;/p&gt;
&lt;p&gt;  host-of-disc1$ rbctl.disc1 stop_app &lt;br/&gt;  host-of-disc1$ rbctl.disc1 reset&lt;br/&gt;  host-of-dics1$ rbctl.disc1 cluster disc1@host-of-disc1 disc2@host-of-disc2&lt;br/&gt;  host-of-disc1$ rbctl.disc1 start_app&lt;br/&gt;&lt;br/&gt;  host-of-ram1$ rbctl.ram1 stop_app&lt;br/&gt;  host-of-ram1$ rbctl.ram1 reset&lt;br/&gt;  host-of-ram1$ rbctl.ram1 cluster disc1@host-of-disc1 disc2@host-of-disc2&lt;br/&gt;  host-of-ram1$ rbctl.ram1 start_app&lt;br/&gt;&lt;br/&gt;  host-of-ram2$ rbctl.ram1 stop_app&lt;br/&gt;  host-of-ram2$ rbctl.ram1 reset&lt;br/&gt;  host-of-ram2$ rbctl.ram1 cluster disc1@host-of-disc1 disc2@host-of-disc2&lt;br/&gt;  host-of-ram2$ rbctl.ram1 start_app&lt;br/&gt;&lt;br/&gt;  host-of-disc2$ rbctl.disc2 stop_app&lt;br/&gt;  host-of-disc2$ rbctl.disc2 reset&lt;br/&gt;  host-of-disc2$ rbctl.disc2 cluster disc1@host-of-disc1 disc2@host-of-disc2&lt;br/&gt;  host-of-disc2$ rbctl.disc2 start_app&lt;/p&gt;
&lt;p&gt;If you have to add users, vhost and permissions, you better do it at the end of this procedure, otherwise the &amp;#8220;reset&amp;#8221; will delete all of this information. Also, if you want to change the cluster setup later, you should be careful with &amp;#8220;reset&amp;#8221;, omitting it for one disc node at least.&lt;/p&gt;
&lt;p&gt;Another weak point with the whole clustering stuff is the location of the &amp;#8220;.erlang.cookie&amp;#8221; file. This file is essential for clustering and must have the same content for all nodes in the cluster. Documentation says RabbitMQ looks at &amp;#8220;&lt;span class="code "&gt;/var/lib/rabbitmq/.erlang.cookie&lt;/span&gt;&amp;#8221; but I found this not always true. Supposed RABBIT_HOME points to the directory where the rabbit distribution is located, I copied the file to &amp;#8220;$RABBIT_HOME/../.erlang.cookie&amp;#8221; and RabbitMQ used this one. I&amp;#8217;m not quite sure if this is a general rule.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/13293831388</link><guid>http://ingoschramm.tumblr.com/post/13293831388</guid><pubDate>Fri, 25 Nov 2011 10:41:00 +0100</pubDate><category>amqp</category><category>cluster</category><category>distributed computing</category><category>rabbitmq</category><category>erlang</category></item><item><title>Technical Quality is an Insurance Policy</title><description>&lt;a href="http://www.modernperlbooks.com/mt/2011/11/technical-quality-is-an-insurance-policy.html"&gt;Technical Quality is an Insurance Policy&lt;/a&gt;</description><link>http://ingoschramm.tumblr.com/post/13198338697</link><guid>http://ingoschramm.tumblr.com/post/13198338697</guid><pubDate>Wed, 23 Nov 2011 09:39:29 +0100</pubDate><category>programming</category><category>project magagement</category><category>agile</category></item><item><title>Analysis of Facebook Graph</title><description>&lt;p&gt;Very interesting paper: &lt;a href="http://arxiv.org/abs/1111.4503" title="The Anatomy of the Facebook Social Graph" target="_blank"&gt;The Anatomy of the Facebook Social Graph&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Reading this very interesting analysis of the structure of the Facebook  graph I come to the conclusion that the main features qualitatively may  be common to all graphs of social networks. For example, I&amp;#8217;ve seen  another social graph one order of magnitude smaller having very similar  features. It would be really interesting to compare such graphs to other  graphs, especially directed social graphs like Twitter or Google+ in  terms of different measures. It would also be interesting to compare  these graphs to offline social networks. Another interesting  question could be to analyze the evolution of such graphs over time, for  example using methods of the theory of random graphs.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/13152460492</link><guid>http://ingoschramm.tumblr.com/post/13152460492</guid><pubDate>Tue, 22 Nov 2011 10:03:15 +0100</pubDate><category>graph</category></item><item><title>Velocity is Killing Agility!</title><description>&lt;a href="http://jimhighsmith.com/2011/11/02/velocity-is-killing-agility/"&gt;Velocity is Killing Agility!&lt;/a&gt;</description><link>http://ingoschramm.tumblr.com/post/12919993369</link><guid>http://ingoschramm.tumblr.com/post/12919993369</guid><pubDate>Thu, 17 Nov 2011 09:58:02 +0100</pubDate><category>agile</category><category>programming</category><category>project management</category></item><item><title>If I had more time I would have written less code</title><description>&lt;a href="http://blog.activelylazy.co.uk/2011/02/09/if-i-had-more-time-i-would-have-written-less-code/"&gt;If I had more time I would have written less code&lt;/a&gt;</description><link>http://ingoschramm.tumblr.com/post/12919977054</link><guid>http://ingoschramm.tumblr.com/post/12919977054</guid><pubDate>Thu, 17 Nov 2011 09:56:48 +0100</pubDate><category>agile</category><category>programming</category></item><item><title>I Regret</title><description>&lt;p&gt;I regret. Before I learned to think and to act functional, I proclaimed X=X+1 for years. Have mercy!&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/12919946307</link><guid>http://ingoschramm.tumblr.com/post/12919946307</guid><pubDate>Thu, 17 Nov 2011 09:54:34 +0100</pubDate><category>Functional</category><category>programming</category><category>erlang</category><category>scala</category></item><item><title>Why Functional: One Reason</title><description>&lt;p&gt;Why functional is better? So many reasons, one comes here: Programming  languages are not made for computers, they are for humans to formulate  generic solutions computers can solve faster in the details. The  imperative style formulates the steps the computer has to follow, the  functional style formulates the generic solution as such. Imperative  style wants you to act like a machine, functional style allows you to  think like a human.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/12919931100</link><guid>http://ingoschramm.tumblr.com/post/12919931100</guid><pubDate>Thu, 17 Nov 2011 09:53:22 +0100</pubDate><category>programming</category><category>Functional</category><category>scala</category><category>erlang</category></item><item><title>Name Dropping Consultants</title><description>&lt;p&gt;I don&amp;#8217;t like name dropping consultants. Name dropping transports no  knowledge at all, just obfuscates what is needed to find a decision. A  little better is concept dropping, but only a little. What I expect of a  consultant is, that she or he asks a lot of questions about my problem  and afterwards shows two or three possible solutions for that particular  problem, combined with an estimation of the costs.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/12919915953</link><guid>http://ingoschramm.tumblr.com/post/12919915953</guid><pubDate>Thu, 17 Nov 2011 09:52:11 +0100</pubDate><category>agile</category><category>project management</category><category>programming</category></item><item><title>The Measure Of Agile Is Quality</title><description>&lt;p&gt;In agile, I guess, it&amp;#8217;s all about quality, not quantity. Quality of  code, quality of user experience, quality of customer satisfaction. It&amp;#8217;s  about maintaining quality in a world of change. It&amp;#8217;s not at all about  being as fast as possible, but as good as possible -  while everything  around us is changing constantly. It&amp;#8217;s about being smart, not being  &amp;#8220;schneller&amp;#8221;.&lt;/p&gt;
&lt;p&gt;Remark: &amp;#8220;schneller&amp;#8221; is German for &amp;#8220;faster, now&amp;#8221;.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/12919902311</link><guid>http://ingoschramm.tumblr.com/post/12919902311</guid><pubDate>Thu, 17 Nov 2011 09:51:10 +0100</pubDate><category>agile</category><category>programming</category><category>project management</category></item><item><title>Tumblr Sucks When Posting Code</title><description>&lt;p&gt;Tumblr really sucks when you try to post code snippets. You can edit your posts using HTML but when you save or when you edit again in fancy mode and save, a lot of extra HTML is added to your posts which often makes the code snippets unreadable. I reported this to be a bug a long time ago - a year or so - but it is still not fixed. Solution would be either to add a &amp;#8220;pre&amp;#8221; or &amp;#8220;code&amp;#8221; formatting to the HTML editor or to parse the input with some more intelligence.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/12639045307</link><guid>http://ingoschramm.tumblr.com/post/12639045307</guid><pubDate>Fri, 11 Nov 2011 13:58:45 +0100</pubDate><category>tumblr</category><category>code</category></item><item><title>Publish To A Local Maven Repository With SBT</title><description>&lt;p&gt;The Simple Build Tool SBT to build Scala projects is simple most of the time, but if you need something special it can become hard to configure. Documentation is quite well, but not very detailed. More often than not I found me googling some receipts and follow some iterations of trial and error before I finally succeeded. Since I use Scala in real life commercial projects I&amp;#8217;m oft confronted with scepticism about the ability to integrate with Java, Maven, Hudson, you name it. Then, I have no choice but to make it work for the environment. Changing the environment is not an option, not in the current phase when Scala is still not widely in use in the industry.&lt;/p&gt;
&lt;p&gt;Here is a working receipt for XSBT (tested with 0.11.0)  to &amp;#8220;publish-local&amp;#8221; to a local Maven repository at &amp;#8220;~/.m2&amp;#8221; instead to the usual local Ivy repository at &amp;#8220;~/.ivy2&amp;#8221;. You should add the following expressions to your &amp;#8220;build.sbt&amp;#8221;.&lt;/p&gt;
&lt;pre&gt;// publish to local ~/.m2
publishMavenStyle := true

otherResolvers := Seq(Resolver.file("dotM2", 
                                    file(Path.userHome + "/.m2/repository")))
publishLocalConfiguration &amp;lt;&amp;lt;= 
   (packagedArtifacts, deliverLocal, ivyLoggingLevel) map 
   {
     (arts, _, level) =&amp;gt; new PublishConfiguration(None, 
                                                  "dotM2", 
                                                  arts, 
                                                  List[String](), 
                                                  level) 
   }
&lt;/pre&gt;</description><link>http://ingoschramm.tumblr.com/post/12638833165</link><guid>http://ingoschramm.tumblr.com/post/12638833165</guid><pubDate>Fri, 11 Nov 2011 13:47:00 +0100</pubDate><category>programming</category><category>sbt</category><category>xsbt</category><category>scala</category></item><item><title>PHP 5.4 Traits and the Diamond Problem</title><description>&lt;p&gt;PHP will introduce traits in 5.4. While testing this feature with 5.4.0alpha2 I was wondering how it deals with the well known diamond problem.&lt;/p&gt;
&lt;p&gt;trait T1 {&lt;br/&gt;    public function f1() { echo __METHOD__ . PHP_EOL; }&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;trait T2 {&lt;br/&gt;    use T1;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;trait T3 {&lt;br/&gt;    use T1;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;class Test {&lt;br/&gt;    use T2, T3;&lt;br/&gt;}&lt;br/&gt;&lt;br/&gt;$t = new Test;&lt;br/&gt;$t-&amp;gt;f1();&lt;/p&gt;
&lt;p&gt;This will output:&lt;/p&gt;
&lt;p&gt;PHP Fatal error:  Trait method f1 has not been applied, because there are collisions with other trait methods on Test in diamond.php on line 24&lt;/p&gt;
&lt;p&gt;To make it work you shall use &amp;#8220;insteadof&amp;#8221;:&lt;/p&gt;
&lt;p&gt;class Test {&lt;br/&gt;    use T2, T3 {&lt;br/&gt;        T2::f1 insteadof T3;&lt;br/&gt;    }&lt;br/&gt;}&lt;/p&gt;
&lt;p&gt;Now you get this expected output:&lt;/p&gt;
&lt;p&gt;T1::f1&lt;/p&gt;
&lt;p&gt;That&amp;#8217;s fine so far. Anyway, it burdens the programmer with the decision which path through the inheritance hierarchy to use, a hierarchy that&amp;#8217;s no longer a tree but a graph with cycles. Hopefully, he&amp;#8217;s not doomed with a poor documented library. In a non-trivial project this is not always the case. Here you may soon find yourself lost in a complex inheritance hierarchy which is even more complex if multiple inheritance is possible.&lt;/p&gt;
&lt;p&gt;Though knowing it well from Scala I&amp;#8217;m not a big fan of traits. They &lt;em&gt;may&lt;/em&gt; make your code more expressive but they &lt;em&gt;will&lt;/em&gt; make it harder to maintain. Interfaces seem to be less error-prone. In OO design, a deep inheritance hierarchy is usually considered bad design. A wide fan of traits should be as well. And the diamond is a gift from hell.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/8168421261</link><guid>http://ingoschramm.tumblr.com/post/8168421261</guid><pubDate>Thu, 28 Jul 2011 13:35:00 +0200</pubDate></item><item><title>PHP Design Bug Still Active in 5.4 Alpha - And Worse</title><description>&lt;p&gt;Today I tested my favorite PHP bug by design in current 5.4.0alpha2. It still works, and that&amp;#8217;s the good news.&lt;/p&gt;
&lt;p&gt;php &amp;gt; echo phpversion() . &amp;#8220;\n&amp;#8221;;&lt;br/&gt;5.4.0alpha2&lt;br/&gt;php &amp;gt; $foo = &amp;#8220;bar&amp;#8221;;&lt;br/&gt;php &amp;gt; echo $foo[0] . &amp;#8220;\n&amp;#8221;;&lt;br/&gt;b&lt;br/&gt;php &amp;gt; echo $foo[&amp;#8220;ouch&amp;#8221;] . &amp;#8220;\n&amp;#8221;;&lt;br/&gt;b&lt;br/&gt;php &amp;gt; $bar = array(1,2,3);&lt;br/&gt;php &amp;gt; echo $bar[0] . &amp;#8220;\n&amp;#8221;;&lt;br/&gt;1&lt;br/&gt;php &amp;gt; echo $bar[&amp;#8220;ouch&amp;#8221;];&lt;br/&gt;PHP Notice:  Undefined index: ouch in php shell code on line 1&lt;br/&gt;&lt;br/&gt;Notice: Undefined index: ouch in php shell code on line 1&lt;br/&gt;php &amp;gt;&lt;/p&gt;
&lt;p&gt;What you see here is the attempt to access a single character of a string using array syntax with an array key that does not exists. Doing this bad thing with a real array at least gives you a notice. Doing it with a string is assumed fine by the interpreter. The magic behind all this is that the string is somehow treated like an array with integer keys and &amp;#8220;ouch&amp;#8221; is then dynamically casted to an integer and this is 0 in PHP&amp;#8217;s strange logic.&lt;/p&gt;
&lt;p&gt;But 5.4.0alpha2 knows how to deepen this mess. While in 5.3.3 you may see this:&lt;/p&gt;
&lt;p&gt;php &amp;gt;  echo $foo[1][0];&lt;br/&gt;&lt;br/&gt;Fatal error: Cannot use string offset as an array in php shell code on line 1&lt;br/&gt;&lt;br/&gt;Call Stack:&lt;br/&gt; 3768.9080     630080   1. {main}() php shell code:0&lt;/p&gt;
&lt;p&gt;now you get this:&lt;/p&gt;
&lt;p&gt;php &amp;gt; echo $foo[1][0] . &amp;#8220;\n&amp;#8221;;&lt;br/&gt;a&lt;br/&gt;php &amp;gt; echo $foo[&amp;#8220;ouch&amp;#8221;][0] . &amp;#8220;\n&amp;#8221;;&lt;br/&gt;b&lt;br/&gt;php &amp;gt; echo $foo[&amp;#8220;ouch&amp;#8221;][&amp;#8220;ouch&amp;#8221;] . &amp;#8220;\n&amp;#8221;;&lt;br/&gt;b&lt;br/&gt;php &amp;gt;&lt;/p&gt;
&lt;p&gt;To name it: you get nonsense, and that&amp;#8217;s the bad news.&lt;/p&gt;
&lt;p&gt;Years ago my team has reported this to be a bug in PHP but the PHP guys say that&amp;#8217;s a feature. Now they improved that feature. Great!&lt;/p&gt;
&lt;p&gt;So, if you do not want your PHP software to show undesired behavior you have absolutely no idea where it originates from, always ensure to have an array and not a string when you expect an array: use type hinting excessively and &lt;em&gt;always&lt;/em&gt; hint for arrays in function declarations. Never try to catch the &amp;#8220;E_RECOVERABLE_ERROR&amp;#8221;. Set &amp;#8220;error_reporting = E_ALL | E_STRICT&amp;#8221;. Always ensure you have a string and not an array if you expect a string (use is_string() since you cannot type hint for strings).&lt;/p&gt;
&lt;p&gt;Do yourself a favor and write much more unit tests.&lt;/p&gt;
&lt;p&gt;Alternatively: use strongly typed languages.&lt;/p&gt;</description><link>http://ingoschramm.tumblr.com/post/8167094659</link><guid>http://ingoschramm.tumblr.com/post/8167094659</guid><pubDate>Thu, 28 Jul 2011 12:09:00 +0200</pubDate></item></channel></rss>
