<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-3967966362003449228</id><updated>2011-07-30T16:51:07.102-07:00</updated><category term='SMB Protocol'/><category term='Pentaho BI Server'/><category term='GWT'/><category term='Microsoft'/><category term='OpenLaszlo'/><category term='Kimball Type 1'/><category term='Samba'/><category term='Marion'/><category term='SQL Server'/><category term='CORBA'/><category term='Web 2.0 Collage'/><category term='Iowa'/><category term='AtomPub'/><category term='data warehouse'/><category term='Google Sites'/><category term='Oracle'/><category term='ZD Net'/><category term='Joe Gregario'/><category term='slowly changing dimension'/><category term='Scala'/><category term='Black Swan'/><category term='Henrik Gemal'/><category term='Brendon Boshell'/><category term='Google AppEngine'/><category term='Kimball Type 2'/><category term='Chrome'/><category term='Ralph Kimball'/><category term='Safari'/><category term='Grails'/><category term='Data warehouse slowly changing dimension'/><category term='V8 Benchmarks'/><category term='Kimbal Type 3'/><category term='Eliezer S. Yudkowsky'/><category term='Google Gears'/><category term='SQL Anywhere'/><category term='iMac'/><category term='Bayes&apos; Theorem'/><category term='FLOSS'/><category term='Bret Victor'/><category term='dimension table'/><category term='Google Wave'/><category term='Google Web Toolkit'/><category term='REST'/><category term='IBM Developer Works'/><category term='programming'/><category term='Type 6 SCD'/><category term='Geolocation'/><category term='Opera'/><category term='GAE'/><category term='Swamp Fox'/><category term='David McKay'/><category term='Parallels'/><category term='Ben Fry'/><category term='Google'/><category term='Open Source'/><category term='Acid 3'/><category term='Taleb'/><category term='Browser Spy'/><category term='EnterpriseDB'/><category term='Firefox'/><category term='Liftweb'/><category term='PostgreSQL'/><category term='DB2'/><category term='Eclipse'/><category term='OpenOffice.org'/><category term='Jeff Grynaviski'/><category term='Monetdb'/><category term='Internet Explorer'/><category term='Webkit'/><category term='Pentaho'/><category term='whoami'/><category term='Erlang'/><title type='text'>Swamp Fox Analyst</title><subtitle type='html'>Musing on business intelligence, particularly using Pentaho.  Also interests in software design, particularly in the open source community.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>37</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-3189492941317769371</id><published>2010-06-13T15:05:00.000-07:00</published><updated>2010-06-13T18:14:29.701-07:00</updated><title type='text'>Children of Prolog</title><content type='html'>Recently, I have become interested in functional programming, largely because of the remarkable success of Erlang in producing robust web applications.  Erlang seems to have 'solved' concurrent programming, which is one of the growing challenges in programming - especially as we move into a post Web 2.0 world.  Erlang was initially implemented in Prolog.&lt;div&gt;Today, I listened to&lt;a href="http://db.cs.berkeley.edu/jmh/"&gt; Joseph M Hellerstein&lt;/a&gt;'s Keynote address at ACM PODS 2010, &lt;a href="http://hosted.mediasite.com/mediasite/Viewer/?peid=123584ea3d4141ea8169b97d5e454d331d"&gt;The Declarative Imperative: Experiences and Conjectures in Distributed Logic&lt;/a&gt;.  The &lt;a href="http://db.cs.berkeley.edu/jmh/talks/podskeynote10.pdf"&gt;slides&lt;/a&gt; are also available.  He uses Daedalus, a derivative of Datalog.  &lt;a href="http://en.wikipedia.org/wiki/Datalog"&gt;Datalog&lt;/a&gt; is, syntactically, a subset of Prolog.  Hellerstein also addresses the concurrency conundrum, a.k.a., the Programming Crisis by retelling children's classics&lt;/div&gt;&lt;div&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px 'Times New Roman'; color: #413331"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px 'Times New Roman'; color: #413331"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;“The sky is falling! The sky is falling!&lt;/span&gt;&lt;span class="Apple-tab-span" style="white-space:pre"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Computers won’t get any faster unless programmers learn to write parallel code!” squawked Chicken Licken.&lt;/span&gt;&lt;/p&gt; &lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px 'Times New Roman'; color: #413331"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;Henny Penny clucked in agreement: “Worse, there is Cloud Computing on the horizon, and it requires programmers to write parallel AND distributed code!”&lt;/span&gt;&lt;/p&gt;&lt;/blockquote&gt;&lt;p style="margin: 0.0px 0.0px 0.0px 0.0px; font: 24.0px 'Times New Roman'; color: #413331"&gt;&lt;span class="Apple-style-span" style="font-size: medium;"&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;div&gt;This is more fun than your average academic talk.  Of course, he then goes on to provide his solution to the programming crisis.  He shows how Datalog has been used to solve a series of practical problems in computer science.&lt;/div&gt;&lt;div&gt;The solutions Hellerstein expounds rely upon declarative programming in Datalog variants.  He describes a series of practical code for distributed crawlers, networking protocols, query optimizers, distributed file systems and a map-reduce scheduler.  What is as impressive as the breadth of topics is his claim that his declarative solutions have code bases that are orders of magnitude smaller that existing, imperative solutions.&lt;/div&gt;&lt;div&gt;His code samples describe solving problems with a time dependence that evolves in steps, like a turn-based game.  This was a little disconcerting to a physicist, since we like to think about time as continuous, still it was interesting to find a computer scientist shift from 'practical' solutions to a rather abstract discussion on the meaning of time and causality.  At this point, I am starting to think about the InfoQ talk by Rich Hicky on &lt;a href="http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey"&gt;Persistent Data Structures and Managed References&lt;/a&gt;.  &lt;/div&gt;&lt;div&gt;From a Prolog beginning, Ericsson developed Erlang.  Erlang is having a renaissance that is leading to high concurrency solutions for web programming.  Next, we have Hellerstein using Datalog to address the programming crisis.  Where are the imperative, OO solutions?  Declarative logic &amp;amp; functional programming - are these the tools that will lead out out the the programming crisis?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-3189492941317769371?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/3189492941317769371/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/06/children-of-prolog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3189492941317769371'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3189492941317769371'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/06/children-of-prolog.html' title='Children of Prolog'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-2890976456283484195</id><published>2010-06-05T12:00:00.000-07:00</published><updated>2010-06-13T13:14:34.747-07:00</updated><title type='text'>Trends in programming and Amdal's Law</title><content type='html'>in my previous blog, I explained trends I saw that will affect programmers.  The main takeaway  is that we are moving into a world of concurrent programming.  If we do concurrent programming with memory shared by several threads of execution, life is going to be miserable for programmers.  Fortunately, message passing via actors is a viable path to concurrency  that is much easier to program.&lt;div&gt;In any discussion of concurrency, the iron law is &lt;a href="http://en.wikipedia.org/wiki/Amdahl's_law"&gt;Amdahl's Law&lt;/a&gt;.  If you have a process in which some fraction, s,  of the steps are sequential and the rest, 1-s, can be done in parallel, then the most you can gain from concurrency over N processors is to reduce the time to execute from 1 to s + (1-s)/N.  So basically, the time to execute a program is limited by s as much as by N.  The hardware determines N and the software determines s.  So what determines s?  Basically, s is the fraction of the algorithm that you spend queueing stuff.  If I go to the grocery store, I can shop in parallel with everyone else.  It takes a little longer to shop in a busy store, but only a little longer.  But when it is time to check out, I have to queue up to pay.  &lt;/div&gt;&lt;div&gt;What is exciting is that by using techniques like 'no shared state' and Actors for communication can greatly reduce s, so we can write software that efficiently tanks advantage of concurrent hardware (i.e., big N).   If we look at a standard sort of web applications, the bottlenecks are things like writing to the database.  The first thing to do is to replace a single server with a cluster of identical servers, so that a given client can access any one of the servers and get the job done.&lt;/div&gt;&lt;div&gt;But there turns out to be a better plan - sharding.  In sharding, you still have a cluster of N servers, but you don't have each server having identical data.  If I have a large database, I would shard it by creating N servers, but I would shard the data so that any given server has only a fraction of the data.  This is much like partitioning data on a RAID array, and the more sophisticated designs take into account '&lt;a href="https://community.voltdb.com/docs/UsingVoltDB/KSafeEnable"&gt;k safety&lt;/a&gt;".  &lt;a href="http://en.wikipedia.org/wiki/Reed-Solomon"&gt;Reed-Solomon erasure codes&lt;/a&gt; exhibit this behavior, as do &lt;a href="http://en.wikipedia.org/wiki/Tornado_code"&gt;Tornado codes&lt;/a&gt;. This means that the data is divided in to n+k partitions so that any set of n partitions can reconstruct the entire data set.  This means you can loose k partitions before you loose any data.  This idea is central to VoltDB, but they implement it by having k+1 copies of each block.  It seems that a more efficient design could be built using erasure codes (See exercise 11.9 in David MacKay's &lt;i&gt;Information Theory, Inference and Learning Algorithms&lt;/i&gt;.)&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-2890976456283484195?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/2890976456283484195/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/06/trends-in-programming-and-amdals-law.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/2890976456283484195'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/2890976456283484195'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/06/trends-in-programming-and-amdals-law.html' title='Trends in programming and Amdal&apos;s Law'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-4630526414273916494</id><published>2010-06-02T19:53:00.001-07:00</published><updated>2010-06-03T21:19:22.306-07:00</updated><title type='text'>Trends in programming</title><content type='html'>There is a dizzying wealth of new options for web programmers.  I am trying to understand why there are so many changes and which of those changes I should be choosing to learn.  I have found that the answer to this sort of question often comes from looking backward and trying to judge current trends in an historical context.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://t2.gstatic.com/images?q=tbn:hegWLNuTRXQMIM:http://www.ezwire.com/cust/Tilera/JETRO/tile-package.jpg"&gt;&lt;img style="float: left; margin: 0pt 10px 10px 0pt; cursor: pointer; width: 145px; height: 146px;" src="http://t2.gstatic.com/images?q=tbn:hegWLNuTRXQMIM:http://www.ezwire.com/cust/Tilera/JETRO/tile-package.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Hardware: Multicore is the future&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;This is an inevitable trend, as carefully explained in &lt;a href="http://mitworld.mit.edu/video/671"&gt;The Future of Computing&lt;/a&gt; by Anant Agarwal to MIT freshman.  The power consumption of a CPU scales as the cube of the voltage.  So trying to improve performance by brute force is a loosing game. Instead, it is much better to build smaller, lower power cores.  Prof. Agarwal is among those who are laying the foundation for a future of RISC cores arranged in a tiled multi core architecture. As a programmer, you can get much better performance if you can leverage concurrency.   We can leave the hardware issues to the likes of MIT, but the programming challenges will affect everyone in who programs.   &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;To better understand hardware and how it affects software, listen to &lt;a href="http://www.infoq.com/presentations/click-crash-course-modern-hardware"&gt;A Crash Course in Modern Hardware&lt;/a&gt; by Cliff Click of Azul.  Azul has systems with 864 processor cores, so they are on the front lines of this revolution.  He explains how modern computers, with caches and pipelining, are not particularly well described by the &lt;a href="http://en.wikipedia.org/wiki/Von_Neumann_architecture"&gt;von Neumann architecture&lt;/a&gt;.  The entire talk seems like an explanation of how hardware engineers have been addressing the von Neumann bottleneck between CPU and memory.  Even here, we find that each physical core is running concurrent processes. &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;So, we are seeing horizontal scaling of computers in clusters, with each computer having more cores and with each core handing more concurrent tasks.  I can spot a trend - concurrent processing is the future.  But I HATE threading and locks.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;b&gt;&lt;span class="Apple-style-span"  style="font-size:large;"&gt;Functional Programming and Concurrency&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_H9cmDV9xmSo/TAc4n0_AeUI/AAAAAAAACZ4/nnxn3ruKjgE/s1600/com.google.chrome.Qbpowl"&gt;&lt;img style="float: right; margin: 0pt 0pt 10px 10px; cursor: pointer; width: 61px; height: 117px;" src="http://1.bp.blogspot.com/_H9cmDV9xmSo/TAc4n0_AeUI/AAAAAAAACZ4/nnxn3ruKjgE/s320/com.google.chrome.Qbpowl" alt="" id="BLOGGER_PHOTO_ID_5478409728608467266" border="0" /&gt;&lt;/a&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Erlang was developed for high reliability in Ericsson telephone switches.    Joe Armstrong describes how they tried to develop &lt;a href="http://www.infoq.com/presentations/Systems-that-Never-Stop-Joe-Armstrong"&gt;Systems that Never Stop&lt;/a&gt; and why that lead to &lt;a href="http://www.infoq.com/presentations/Message-Passing-Concurrency"&gt;Message Passing Concurrency in Erlang&lt;/a&gt;.  Armstrong came up with a list of six laws for reliable systems.  The laws/requirements are:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;isolation (the probability of isolated systems failing is independent.  So processes need to be isolated.)&lt;/li&gt;&lt;li&gt;concurrency (do you need to worry about how many concurrent processes can you support?  You need at least two systems to make a non-stop system.  Even a two computer system is concurrent. You can't avoid concurrency)&lt;/li&gt;&lt;li&gt;failure detection (if you can't detect a failure, you can't fix it.  the thing that crashed can  be the thing that detects failures.)&lt;/li&gt;&lt;li&gt;fault identification (You need to figure out why there was a failure if you want to fix it.)&lt;/li&gt;&lt;li&gt;live code upgrade (Systems that should never stop,  need live code upgrade)&lt;/li&gt;&lt;li&gt;stable storage (no backups, implies multiple copies. must keep crash logs)&lt;/li&gt;&lt;/ol&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;Erlang is a functional language, so there are no side effects to calculations, Joe Armstrong discusses the importance of &lt;a href="http://www.infoq.com/presentations/joe-armstrong-erlang-qcon08"&gt;Functional Programming in Functions + Messages + Concurrency = Erlang&lt;/a&gt;.   There really is no point in arguing about if he is right.  Erlang is the proof.  It is reliable, Ericsson has the AXD 301 switch with two million lines of code: BT operates these switches at a 'nine-nines' reliability - it can fail for 32 ms each year.  BT has run switches for six years without stopping.  Erlang also allows for high concurrency, this is clearly illustrated in &lt;a href="http://www.sics.se/%7Ejoe/apachevsyaws.html"&gt;Apache vs. Yaws&lt;/a&gt;: while Apache and Yaws have similar throughputs for score of concurrent clients, Apache bogs down at around 4 thousand parallel sessions.  By contrast, the Erlang powered Yaws can serve over 80 thousand parallel sessions on Linux with similar hardware.  Apache is a well written server, Netcraft shows that &lt;a href="http://news.netcraft.com/archives/2010/05/14/may_2010_web_server_survey.html"&gt;Apache is easily the #1 server on the World Wide Web in May 2010&lt;/a&gt;.   But Yaws beat it handily in this measure.  In &lt;a href="http://www.infoq.com/articles/vinoski-erlang-rest"&gt;RESTful Services with Erlang and Yaws&lt;/a&gt;, Steve Vinoski examines Yaws in more detail.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;But perhaps Erlang is hard to use and expensive to code?  According to Ulf Wigner, Ericsson recorded a &lt;a href="http://www.erlang.se/publications/Ulf_Wiger.pdf"&gt;Four-fold increase in Productivity and Quality&lt;/a&gt; on the ADX 301 project.  Joe Armstrong is &lt;a href="http://www.pragprog.com/articles/erlang"&gt;very optimistic about the future of Erlang&lt;/a&gt;, and I think he is right.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;When I looked into this some more, I realized that Erlang was not the 'bolt of the the blue' that is first seemed to me.  Some of the greatest minds in programming have been noticing that imperative programming has been at something of a standstill.  Read John Backur's &lt;i&gt;1977&lt;/i&gt; ACM Turing Award Lecture, &lt;a href="http://www.thocp.net/biographies/papers/backus_turingaward_lecture.pdf"&gt;Can Programming Be Liberated from the von Neumann Style?  A Functional Style and Its Algebra of Programs&lt;/a&gt;.  This is a broadside attack on imperative programming is all the more remarkable because it is coming from the author of FORTRAN.  He then goes on to explain what he sees are the advantages of functional programming.  This must have been a controversial paper, Edsger Dijkstra &lt;a href="http://userweb.cs.utexas.edu/users/EWD/transcriptions/EWD06xx/EWD692.html"&gt;critique&lt;/a&gt; of Backur's lecture ended with:&lt;blockquote&gt;In short, the article is a progress report on a valid effort but suffers badly from agressive overselling of its significance, long before convincing results have been reached.&lt;/blockquote&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;I  tend to believe both Backur and Dijkstra.  I resolve any apparent conflict by admitting that Backur was ahead of his time.&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:medium;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-4630526414273916494?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/4630526414273916494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/06/trends-in-programming.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4630526414273916494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4630526414273916494'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/06/trends-in-programming.html' title='Trends in programming'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_H9cmDV9xmSo/TAc4n0_AeUI/AAAAAAAACZ4/nnxn3ruKjgE/s72-c/com.google.chrome.Qbpowl' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-6884885214798945691</id><published>2010-05-10T17:06:00.000-07:00</published><updated>2010-05-10T19:12:35.881-07:00</updated><title type='text'>Gaelyk again</title><content type='html'>&lt;a href="http://gaelyk.appspot.com/"&gt;Gaelyk&lt;/a&gt; is gaining ground as a Google AppEngine framework.  Developer Works has&lt;a href="http://www.ibm.com/developerworks/java/library/j-javadev2-6/"&gt; Java Development 2.0: Gaelyk for Google App Engine&lt;/a&gt; by Andrew Glover.  This title emphasizes that Java is more of a platform than a language.  I tried this a few months ago, but was disappointed by the initial load times.  The application runs fine once it loaded, but my application doesn't get many hits, so most users ended up hitting a cold site.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One solution is to &lt;a href="http://distractable.net/coding/google-appengine-language-performance-comparison-followup/"&gt;regularly ping the site&lt;/a&gt; with a service like &lt;a href="http://pingdom.com/"&gt;Pingdom&lt;/a&gt; with something like a 1 minute interval.  This seems like overkill to me, but 43,200 pings a month is still well below the roughly 500,000 hits per month that triggers payments.  A Basic Pingdom account is $9.95 per moth and there is also a free account that would be fine for a single site.  In addition, Groovy 1.7 as &lt;a href="http://docs.codehaus.org/display/GROOVY/2009/07/31/Groovy+1.6.4+and+1.7-beta-1+in+the+wild"&gt;improvements&lt;/a&gt; for faster compilation.  So the performance issues are getting resolved.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The joy of Gaelyk is getting to use the AppEngine features with a minimum of Fuss.  Pratik Patel's &lt;a href="http://www.vimeo.com/6844104"&gt;screencast&lt;/a&gt; shows how to build a basic CRUD application.  This is also shown nicely in the &lt;a href="http://gaelyk.appspot.com/tutorial"&gt;Gaelyk tutorial&lt;/a&gt;.  Recently, Gaelyk introduced &lt;a href="http://jaxenter.com/extend-gaelyk-with-new-plugin-system-11486.html"&gt;plugins&lt;/a&gt; in version 0.4.  There is also a great &lt;a href="http://ice09.wordpress.com/2010/02/01/resting-with-json-in-gaelyk/"&gt;tutorial&lt;/a&gt; about adding &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;REST&lt;/a&gt; via &lt;a href="http://www.json.org/"&gt;JSON&lt;/a&gt; and &lt;a href="http://wiki.fasterxml.com/JacksonHome"&gt;Jackson&lt;/a&gt;.  It also seems like it should be reasonably easy to &lt;a href="http://www.ibm.com/developerworks/java/library/j-javadev2-5/"&gt;integrate with RESTClient&lt;/a&gt;.&lt;/div&gt;&lt;p style="margin-top: 0"&gt;       &lt;span style="color:#0000ff;"&gt;&lt;result style="background-color: #ffff00"&gt; &lt;/result&gt;&lt;/span&gt;    &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-6884885214798945691?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/6884885214798945691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/05/gaelyk-again.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/6884885214798945691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/6884885214798945691'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/05/gaelyk-again.html' title='Gaelyk again'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-7506408836272035351</id><published>2010-03-20T19:46:00.000-07:00</published><updated>2010-03-20T22:39:58.104-07:00</updated><title type='text'>Jeffrey Zeldman vs. Ed Bott</title><content type='html'>In his &lt;a href="http://blogs.zdnet.com/Bott/?p=1896&amp;amp;tag=trunk;content"&gt;ZD Net&lt;/a&gt; Blog, Ed Bott stated:&lt;br /&gt;&lt;blockquote&gt;In one breath he said, “I’m not challenging the quality of the hardware and software improvements,” and then, in the very next breath, he criticized Microsoft’s “brilliant browser engineers” for “torturing the IE rendering engine every couple of years instead of putting it out of its misery.”&lt;/blockquote&gt;This certainly seems damning.  But it isn't quite true.  Each of the quotes can be pulled from Zeldman's blog, &lt;a href="http://www.zeldman.com/2010/03/16/ie9-preview/"&gt;IE9 Preview&lt;/a&gt;, but Bott's juxtaposition of Zeldman's words are downright deceptive.  The two statements were separated by four paragraphs, so perhaps Bott quite understands what 'very next breath' means.  Or more likely, Bott is being intentionally being misleading. &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is clear that Jeffrey Zeldman does respect Microsoft Engineering, and that he considers at least some of the Microsoft engineers to be brilliant.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Jeffrey Zeldman clearly states that he is writing in response to  Dean Hachamovitch's report, &lt;a href="http://blogs.msdn.com/ie/archive/2009/11/18/an-early-look-at-ie9-for-developers.aspx"&gt;An Early Look at IE9 for Developers&lt;/a&gt;.  Zeldman's blog is dated 9 AM Eastern on 16 Mar 2010.  Bott then launched into a description of Hachamovitch's presentation at MIX at Las Vagas.  The talk was live blogged by Sharon Chan at 9:51 AM Pacific on 16 March 2010.  Or about 4 hours after Zeldman posted his blog.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For some reason, Bott is surprised that Zelman didn't report on the still 4 hour in the future MIX talk.  This is even more surprising since Bott was at the talk, so I would have expected him to note who was present in the room.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What there the significant changes that occurred between Hachamovitch's blog and his presentation at MIX?  From what I can tell, the major changes introduced at the talk were all known at PDC 2009 (18 November 2009):&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;html5&lt;/li&gt;&lt;li&gt;SVG 1.1&lt;/li&gt;&lt;li&gt;GPU rendering using Direct2D&lt;/li&gt;&lt;li&gt;CSS3&lt;/li&gt;&lt;li&gt;new JavaScript engine&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;These are good news.  What has changed between November:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;improving Acid3 (which did improve from 32 to 55)&lt;/li&gt;&lt;li&gt;support for CSS3 selectors (which improved from passing 574/578 tests to a perfect 578/578)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;So, we are seeing IE9 making significant improvements in standards compliance.  But this is just a start.  To see how IE9 is faring  on SVG 1.1, we can look at this &lt;a href="http://www.codedread.com/svg-support.php"&gt;recent blog at codedread&lt;/a&gt;. On the official &lt;a href="http://www.w3.org/Graphics/SVG/WG/wiki/Test_Suite_Overview"&gt;SVG Test Suite&lt;/a&gt;,  IE9 preview is scoring 28%, Firefox 3.7 scores 73%, Opera 10.5 scores 94%, Chrome 5 scores 87% and Safari 4 scores 82%.  These numbers are quite different than the &lt;a href="http://samples.msdn.microsoft.com/ietestcenter/"&gt;test results presented by Microsoft&lt;/a&gt;.  &lt;a href="http://my.opera.com/haavard/blog/2010/03/17/microsoft-svg-table"&gt;Haavard&lt;/a&gt; noticed that before I did.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The Acid3 score of 55 is well below the scores of the production versions of Firefox 3.5 (94%), Opera (100%), Chrome (99%) and Safari (100%).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That still leaves JavaScript.  In addition to speed, a a browser's JavaScript should conform to the ECMA standard.  Google released the &lt;a href="http://code.google.com/p/sputniktests/"&gt;Sputnik JavaScript  conformance test suite&lt;/a&gt;.  The Chromium blog recently posted &lt;a href="http://blog.chromium.org/2010/03/does-your-browser-behave.html"&gt;test results&lt;/a&gt;.  The winner is Opera (78 failures) and the looser is IE8, with 463 failures.  In terms of JavaScript performance, IE9 is now respectably fast.  It is on par with the the other modern JavaScript engines.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-7506408836272035351?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/7506408836272035351/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/03/jeffrey-zeldman-vs-ed-bott.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/7506408836272035351'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/7506408836272035351'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/03/jeffrey-zeldman-vs-ed-bott.html' title='Jeffrey Zeldman vs. Ed Bott'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-3557308441518235459</id><published>2010-03-04T08:41:00.000-08:00</published><updated>2010-03-31T19:54:54.999-07:00</updated><title type='text'>Making the case for Scala</title><content type='html'>At first glance, Scala seems like an odd choice for developing web applications.  Scala is a JVM language created by &lt;a href="http://lampwww.epfl.ch/~odersky/"&gt;Martin Odersky&lt;/a&gt; of EPFL seems like an academic's testbed for a 'grand unified language' combining functional programming and strict object-oriented design.  Scala is clearly gaining in popularity, but the current &lt;a href="http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html"&gt;TIOBE Software Index&lt;/a&gt; places Scala at #24 with a rank of only 0.459%, far behind the #1 language, Java, which has a a rank of 17.348%.  So, if you want to be on a JVM, why not stay with the undisputed champion of the TIOBE ranking since June 2001?&lt;div&gt;&lt;br /&gt;&lt;div&gt;The key reason is money.  Developer time is money.  Developer time is, to a remarkably good approximation, proportional to the number of lines of codes that need to be written.  This holds over a wide range of languages.  Rather than regurgitate an existing piece, I urge you to read &lt;a href="http://www.scala-lang.org/node/3069"&gt;Research: Programming Style and Productivity&lt;/a&gt; and &lt;a href="http://faler.wordpress.com/2009/07/13/scala-vs-java-conciseness-equals-less-bugs/"&gt;Scala vs Java: Conciseness equals less bugs&lt;/a&gt;.  Scala was found to reduce lines of code by 30-35%.  This should lead to a commensurate increase in productivity.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The second reason is that functional programming looks like it is the future.  Erlang proves that functional programming can lead to high reliability systems with massive concurrency.  Computers are becoming highly concurrent, not faster.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The third reason is more prosaic.  Liftweb gives many of the advantages of Ruby on Rails and it also provides type checking.  Call me old fashioned, but I get warm fuzzy feelings knowing that a compiler is preventing wide classes of errors.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The last reason is still in the future.  In 2002, Phil Bagwell wrote &lt;a href="http://lampwww.epfl.ch/publications/papers/techlists.pdf"&gt;Fast Functional Lists, Hash-Lists, Deques and Variable Length Arrays&lt;/a&gt;.  He introduced new data structures for functional programming.  Bagwell is Swiss and is at EPFL, where Martin Odersky works.  So EPFL is the center of Scala.  I learned about these by watching Rich Hickey's QCon London 2010 talk, &lt;a href="http://www.infoq.com/presentations/Value-Identity-State-Rich-Hickey"&gt;Persistent Data Structures and Managed References&lt;/a&gt;.  The slides are available on Michael Galpin's blog entry &lt;a href="http://fupeg.blogspot.com/2009/11/persistent-data-structures.html"&gt;Persistent Data Strictures&lt;/a&gt;.  This excites me, because many of the ideas of state took me back to physics, especially statistical mechanics.  The talk, and Clojure's approach to state just seems right.  So why is this a reason to use Scala!?  Why not cut to the chase and go right to Clojure?  At this point, I don't know, that may be the right answer.  But Scala is a bit of a chameleon, and it seems to me that the concepts of State and Identity, as well as the persistent data structures that make this efficient, will be implemented soon in Scala.  Scala 2.8 is getting Bagwell's VLists.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Suddenly, this is becoming an interesting time to be a programmer, and the JVM seems to be the epicenter of these changes.  The JVM is very robust - there has been a decade of work with theorem provers that demonstrate the robustness of the design.  There has also been a decade to flush out the bugs.  Now, Scala, Groovy and Clojure are leveraging the JVM, and the plethora of libraries on the JVM.  Full speed ahead!&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-3557308441518235459?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/3557308441518235459/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/03/making-case-for-scala.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3557308441518235459'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3557308441518235459'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/03/making-case-for-scala.html' title='Making the case for Scala'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-5885798397199035548</id><published>2010-03-01T06:19:00.000-08:00</published><updated>2010-03-20T19:46:31.686-07:00</updated><title type='text'>David Pollak's Web Framework Manifesto</title><content type='html'>&lt;p&gt;The best part of blogs is that is makes it possible for people with clear ideas, not just fame or access to money, to be published.  David Pollak certainly falls within the category of clear thinking people, and his &lt;a href="http://blog.lostlake.org/index.php?/archives/16-Web-Framework-Manifesto.html"&gt;Web Framework Manifesto&lt;/a&gt;, from November 2006, is a great technical summary of what we all should expect of a web framework.  It is fascinating to see the breadth of frameworks that he has examined.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Security figures predominantly in this manifesto.  He states:&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;There should exist an orthogonal security layer such that objects that are not accessible to a user should never be returned in a query for the user and fields on an object that are not accessible should not be visible. The security and access control rules should be algebraic and demonstrable during a security audit. This means that neither the view nor the controller should have to test for access control. Objects and requests should be sanitized before they get to the “controller.”&lt;/blockquote&gt;At first, this seems like Spring Security, but the algebraic caught my eye.  I don't know what this means.  A Google search found &lt;a href="http://www.cs.purdue.edu/homes/ninghui/papers/algebra_ccs06.pdf"&gt;Beyond Separation of Duty: An Algebra for Specifying High-level Security Policies&lt;/a&gt;, but this seems quite theoretical at this point.  In the IEEE Security &amp;amp; Privacy Journal, the article, &lt;a href="http://www.arctecgroup.net/pdf/0703-OWASPMetrics.pdf"&gt;A Metrics Framework to Drive Application Security Improvemen&lt;/a&gt;t, describes a more pragmatic, but still quantitative approach to security.&lt;br /&gt;&lt;p&gt;David then went on to create and act as &lt;em&gt;benevolent dictator for life&lt;/em&gt; of the Liftweb framework, or just Lift.  As a benevolent dictator, it is no surprise that the key ideas of the Web Framework Manifesto are all present in Lift.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-5885798397199035548?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/5885798397199035548/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/03/david-pollaks-web-framework-manifesto.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/5885798397199035548'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/5885798397199035548'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/03/david-pollaks-web-framework-manifesto.html' title='David Pollak&apos;s Web Framework Manifesto'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-653358554546542181</id><published>2010-02-12T20:00:00.000-08:00</published><updated>2010-02-24T16:12:35.339-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='Liftweb'/><category scheme='http://www.blogger.com/atom/ns#' term='GAE'/><category scheme='http://www.blogger.com/atom/ns#' term='Google AppEngine'/><title type='text'>Liftweb 1.1 and Google AppEngine</title><content type='html'>&lt;p&gt;With only minor modifications, I have repeated &lt;a href="http://jpkutner.blogspot.com/2009/08/scala-and-lift-on-google-app-engine.html"&gt;Joe Kutner's installation of Liftweb on AppEngine&lt;/a&gt;.  I'm running OS/X, so I started by using macports to install maven2.  I saw that Java App-Engine was just updated to 1.3.1, so that was installed and I adjusted my APPENGINE_HOME and M2_HOME in .profile.  The latest liftweb version is 1.1-M8, so I'll try that one.&lt;/p&gt;&lt;p&gt;Now that I know I have updated libraries, I  generated a liftweb project with:&lt;/p&gt;&lt;div&gt;&lt;code&gt;mvn archetype:generate -U   -DarchetypeGroupId=net.liftweb &lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;  -DarchetypeArtifactId=lift-archetype-blank   -DarchetypeVersion=1.1-M8 &lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;  -DremoteRepositories=http://scala-tools.org/repo-releases &lt;/code&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;  -DgroupId=com.folkertsfotografie. rlftest -DartifactId= rlftest&lt;/code&gt;&lt;div&gt;&lt;p&gt;Rather than using -Dversion=1.0-SNAPSHOT, I entered a version of 1.1-M8 when prompted in maven.  As usual, then next commands were &lt;code&gt;cd rlftestl&lt;/code&gt; and a quick &lt;code&gt; mvn jetty:run&lt;/code&gt; to see that &lt;i&gt;http://localhost:8080/&lt;/i&gt; was working.  As an eclipse user, I added &lt;code&gt; mvn eclipse:eclipse&lt;/code&gt;.  So far, so good.  The simple helloword application came up normally under the jetty installed with liftweb.&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;p&gt;To integrate with AppEngine, I just added the boilerplate appengine-web.xml in my WEB-INF directory.  The contents are:&lt;/p&gt;&lt;/div&gt;&lt;div&gt;&lt;code&gt;&lt;/code&gt;&lt;/div&gt;&lt;code&gt;&lt;div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;?xml version="1.0" encoding="utf-8"?&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt; &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;appengine-web-app xmlns="http://appengine.google.com/ns/1.0"&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;  &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;application&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;rlftest&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;  &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;version&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;3&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;/version&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;  &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;system-properties&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;    &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;property name="in.gae.j" value="true" /&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;  &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;/system-properties&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;  &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;sessions-enabled&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;true&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;/sessions-enabled&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;  &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;static-files&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;  &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;exclude path="/**" /&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;  &lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;/static-files&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;div&gt;&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;lt;&lt;/font&gt;/appengine-web-app&lt;font class="Apple-style-span" face="monospace" size="medium" style="  white-space: pre-wrap; "&gt;&amp;gt;&lt;/font&gt;&lt;/div&gt;&lt;/div&gt;&lt;/code&gt;&lt;div&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;With that done, I built the war file with &lt;code&gt;mvn package&lt;/code&gt;.  To run that war file under AppEngine, just type&lt;br /&gt;&lt;/p&gt;&lt;code&gt; $APPENGINE_HOME/bin/dev_appserver.sh target/rlftest-1.1-M8&lt;/code&gt;.&lt;p&gt;  That also worked, I could see &lt;i&gt;http://localhost:8080/&lt;/i&gt;.  Finally, I published this to appsite with &lt;code&gt;$APPENGINE_HOME/bin/appcfg.sh update target/rlftest-1.1-M8&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;With that done, I browsed my AppEngine control panel and tested that the hello world application.  It worked without a hitch.  Now, I can get back to learning liftweb and Scala.  It isn't at all clear to me how liftweb and datastore will work together, but I'll just have to burn that bridge when I get to it.  So thanks Joe, you have been a great help getting me started with Lift.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-653358554546542181?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/653358554546542181/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/02/liftweb-11-and-google-appengine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/653358554546542181'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/653358554546542181'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/02/liftweb-11-and-google-appengine.html' title='Liftweb 1.1 and Google AppEngine'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-1248105810265497140</id><published>2010-02-07T19:56:00.000-08:00</published><updated>2010-02-07T21:11:46.238-08:00</updated><title type='text'>Google Analytics: integration with web apps.</title><content type='html'>&lt;p&gt;Google Analytics is a powerful, free tool to gather information on events in the click streams of your website's visitors.  I'm trying to develop a web application for photographers, starting with my wife's site, &lt;a href="http://folkertsfotografie.com"&gt;folkertsfotografie.com&lt;/a&gt;.  I'm tracking progress on &lt;a href="http://sites.google.com/site/fotositeproject/"&gt;fotositeproject&lt;/a&gt; and the new &lt;a href="http://folkertsfotografie.appspot.com/"&gt;webapp&lt;/a&gt; is running on GAE, Google App Engine.     This is a rather Google-centric project.  I'm using Picasa to hold image galleries.  The RSS from Blogger, Picasa and flickr are being integrated using Google's Feed API via the jQuery library jGFeed.  So when we wanted to add analytics, Google Analytics was on the top our our list.&lt;/p&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/daTSQ7-f6eU&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/daTSQ7-f6eU&amp;color1=0xb1b1b1&amp;color2=0xcfcfcf&amp;hl=en_US&amp;feature=player_embedded&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowScriptAccess="always" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;p&gt;I had hoped to develop with Grails, but it has proven to be too slow.  This is a known issue, and both Google and SpringSource are working on speed ups. I switch to Gaelyk, a lighter Groovy framework for GAE, which is resulting in reasonable performance.    I looked at GAE sites using other Java frameworks, and was surprised how much faster they are.  However, GAE also has &lt;a href="http://olabini.com/blog/2009/04/jruby-on-rails-on-google-app-engine/"&gt;similar issues with Rails on jRuby&lt;/a&gt;, presumably for the same architectural reasons.  GAE performance with Groovy is still an issue, but one that I trust will have a happy ending in the next few months.  GAE does a lot of validating of included libraries on startup, which is probably a really good thing for security.  I wonder if they can have some standard pre-verified jar files for groovy, jruby, grails, sitemesh and so on.  When I want to use one of these jars, I agree to use the 'Google compatible version'.  When I load my app, they check the MD5 hash to make sure that I am still using an unadulterated copy &amp; they can just copy their jar image into my application's memory without the expensive validation.   Can't we pay this price once when we load the app, not every time we start it up?  There is still activity in the Grails community to develop GAE integration, so I can't believe that this issue will remain  for long.&lt;/p&gt;&lt;hr/&gt;&lt;p&gt;Returning to my original topic: Google Analytics requires adding some code snippets to the bottom of each tracked 'page' or in the event handlers for tracked  events.  In a MVC design, the code snippets must resign in the views.  However, the URLs are tied to controllers, so the keys for each URL need to be managed by the controller.  I had assumed that a quick search would find others who had discussed this topic.  Surprisingly, this is not the case.  I have written a page that will read a Picasa RSS feed and then show the album in Galleriffic, a terrific jQuery image gallery.  I want to have URLs like /gallery/show/sarah2009, so I don't want to place 'the key' in a file like /album/show.gsp, since the controller don't even expose that URL to the user.  I certainly want to track patrick2009 with a different code that campingTripSpring2007, even if they both use the same view.  So for each controller, I need a map of the view, the model, Google Analytics keys  to use.  This isn't quite model data, since the model should only have 'domain' data, which in this cased is information about the albums, media feeds, images, models and clients.  It seems that only the controller is in a position to address this.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-1248105810265497140?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/1248105810265497140/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/02/google-analytics-integration-with-web.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/1248105810265497140'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/1248105810265497140'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/02/google-analytics-integration-with-web.html' title='Google Analytics: integration with web apps.'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-1499069259233475372</id><published>2010-02-03T06:39:00.000-08:00</published><updated>2010-02-04T07:28:43.996-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Scala'/><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='CORBA'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Erlang'/><title type='text'>REST and application evolution</title><content type='html'>&lt;p&gt;REST turns out to be the key to allowing software to be upgraded without breaking applications.  The idea is pretty simple,you agree on the small number of REST verbs.  You then have interfaces that are specified by URL and a version number (perhaps part of URL).  You then allow clients to specify their version number in a request.&lt;/p&gt;&lt;p&gt;This is discussed in a couple of InfoQ talks. Alex Antonov gave &lt;a href="http://www.infoq.com/presentations/RESTful-Web-Services-Orbitz"&gt;Case Study: RESTful Web Services at Orbitz.&lt;/a&gt;  He shows how Protocol Buffers allow for efficient (he claims 7 times faster than SOAP) and flexible message passing using HTTP.  &lt;a href="http://en.wikipedia.org/wiki/Protocol_Buffers"&gt;Protocol Buffers&lt;/a&gt; is an open source HTTP messaging protocol &lt;a href="http://google-opensource.blogspot.com/2008/07/protocol-buffers-googles-data.html"&gt;developed by Google&lt;/a&gt;. The exchanged data uses &lt;a href="http://code.google.com/p/protobuf/"&gt;protobuf&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Steve Vinoski gives a great talk on &lt;a href="http://www.infoq.com/presentations/vinoski-rpc-convenient-but-flawed"&gt;RPC and its fundamental flaws&lt;/a&gt;.  He was an expert in CORBA in the 90's and he has recently moved to REST and Erlang.  He is quite convinced that functional programming is the future and that imperative languages, such as Java and C# are based upon a the wrong model of distributed programming.&lt;/p&gt;&lt;p&gt;These talks dovetail nicely with Kirk Wylie's earlier InfoQ talk, &lt;a href="http://www.infoq.com/presentations/restful-financial-systems-integration"&gt;Restful approaches to financial systems&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-1499069259233475372?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/1499069259233475372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/02/rest-and-application-evolution.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/1499069259233475372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/1499069259233475372'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/02/rest-and-application-evolution.html' title='REST and application evolution'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-6919629152330393554</id><published>2010-01-23T12:53:00.000-08:00</published><updated>2010-01-23T13:08:19.411-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Sites'/><title type='text'>Google Sites -  easy project web sites</title><content type='html'>I'm working with my wife to develop a web site for her business, &lt;a href="http://www.folkertsfotografie.com/"&gt;FolkertsFotografie&lt;/a&gt;.  Currently, it is a Smug Mug site.  She isn't a fan of selling images via shopping carts, so SmugMug is not a special advantage.  I'm wanting to learn about Google AppEngine, so we set up a 'project' to make this happen.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is where Google Sites fits in.  I wanted to organize all of the brainstorming, designing and so forth.  Google Sites makes it easy.  See for yourself at &lt;a href="http://sites.google.com/site/fotositeproject"&gt;Fotositeproject&lt;/a&gt;.  There is easy integration with a host of Google tools, such as Google Docs, Calendar, Groups, Analytics and Webmaster Tools.  Plus, I can rest knowing that I have offsite backup of everything and I do not have to worry about keeping the servers running 24/7.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Google Analytics &amp;amp; Webmaster Tools gives me as much monitoring data as my employer gets from IT.  But unlike me, Google provides IT services for free.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-6919629152330393554?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/6919629152330393554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/01/google-sites-easy-project-web-sites.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/6919629152330393554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/6919629152330393554'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/01/google-sites-easy-project-web-sites.html' title='Google Sites -  easy project web sites'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-1987320869651205264</id><published>2010-01-08T17:36:00.000-08:00</published><updated>2010-01-08T18:05:42.904-08:00</updated><title type='text'>Grails: By the numbers</title><content type='html'>Everybody likes to talk about highly productive environments, but numbers are notoriously hard to come by.  This makes alterlab's ALTERthoughts Blog, entitled &lt;a href="http://alterlabs.com/technologies/java/grails-vs-rails-the-thrilla-in-manilla-a-study-on-grails-productivity/"&gt;Grails vs. Rails&lt;/a&gt; especially interesting.  Using Java J2EE as a base, both &lt;a href="http://rubyonrails.org/"&gt;Ruby on Rails&lt;/a&gt; and &lt;a href="http://www.grails.org/"&gt;Grails&lt;/a&gt; were found to be twice as productive.  Grails beat Rails, but by a margin so slim it seems a dead heat.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-1987320869651205264?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/1987320869651205264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/01/grails-by-numbers.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/1987320869651205264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/1987320869651205264'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2010/01/grails-by-numbers.html' title='Grails: By the numbers'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-4707644474971171968</id><published>2009-10-01T13:52:00.000-07:00</published><updated>2009-10-14T18:50:03.953-07:00</updated><title type='text'>Erlang, Mochiweb and Webmachine</title><content type='html'>&lt;a href="http://bitbucket.org/justin/webmachine/wiki/Home"&gt;Webmachine &lt;/a&gt;is amazing.  Why doesn't .Net or Java have something this elegant? &lt;br /&gt;&lt;div&gt;&lt;object width="512" height="322"&gt;&lt;param name="movie" value="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.46"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="AllowScriptAccess" value="always"&gt;&lt;param name="bgcolor" value="#000000"&gt;&lt;param name="flashVars" value="id=13693397&amp;amp;vid=5178506&amp;amp;lang=en-us&amp;amp;intl=us&amp;amp;thumbUrl=http%3A//l.yimg.com/a/p/i/bcst/videosearch/9129/86376656.jpeg&amp;amp;embed=1"&gt;&lt;embed src="http://d.yimg.com/static.video.yahoo.com/yep/YV_YEP.swf?ver=2.2.46" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" bgcolor="#000000" flashvars="id=13693397&amp;amp;vid=5178506&amp;amp;lang=en-us&amp;amp;intl=us&amp;amp;thumbUrl=http%3A//l.yimg.com/a/p/i/bcst/videosearch/9129/86376656.jpeg&amp;amp;embed=1" width="512" height="322"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;a href="http://video.yahoo.com/watch/5178506/13693397"&gt;Erlang Factory 2009 Palo Alto - Justin Sheehy - Webmachine&lt;/a&gt; @ &lt;a href="http://video.yahoo.com/"&gt;Yahoo! Video&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;Have a look.  I was impressed by the clean design, but I was blown away by the debugger described in the last ten minutes.  This is an open source project in Erlang, the high concurrency functional language created by Joe Armstrong at Ericsson.  As noted in the talk, Webmachine is a high quality component to include in a web framework, like &lt;a href="http://code.google.com/p/mochiweb/"&gt;Mochiweb&lt;/a&gt;.  Mochiweb itself is interesting: it is an Erlang framework for high concurrency web applications.  When serving static content, it has been compared with yaws and nginx in a &lt;a href="http://www.joeandmotorboat.com/2009/01/03/nginx-vs-yaws-vs-mochiweb-web-server-performance-deathmatch-part-2/"&gt;deathmatch &lt;/a&gt;on &lt;a href="http://www.joeandmotorboat.com/"&gt;Joes Blog!&lt;/a&gt; Richard Jones is contemplating a &lt;a href="http://www.metabrew.com/article/a-million-user-comet-application-with-mochiweb-part-1/"&gt;Million User Comet App&lt;/a&gt;.  Erlang is turning into a pretty cool language for web apps with high concurrency.&lt;br /&gt;&lt;br /&gt;I wonder if there is any attempt to write an equivalent in Scala, a high concurrency functional language for the JVM?  I have got to get up to speed with Scala and Lift.  There is a lot going on here...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-4707644474971171968?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/4707644474971171968/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/10/erlang-mochiweb-and-webmachine.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4707644474971171968'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4707644474971171968'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/10/erlang-mochiweb-and-webmachine.html' title='Erlang, Mochiweb and Webmachine'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-8776485694708121493</id><published>2009-09-26T09:29:00.000-07:00</published><updated>2009-09-26T10:59:27.741-07:00</updated><title type='text'>Involve them in the same conspiracy</title><content type='html'>As previously noted, I am listening to the lectures from Berkeley's CS 61A.  In the fifth lecture, the class is listening to a video of &lt;a href="http://en.wikipedia.org/wiki/Alan_Kay"&gt;Alan Kay&lt;/a&gt;.  He ends the talk, "&lt;i&gt;If you want others to go along with you, you have to involve them in the same conspiracy.&lt;/i&gt;"   Oddly, this made me think about spreadmarts.  &lt;a href="http://www.linkedin.com/ppl/webprofile?action=vmi&amp;amp;id=277819&amp;amp;pvs=pp&amp;amp;authToken=zZK1&amp;amp;authType=name&amp;amp;trk=ppro_viewmore&amp;amp;lnk=vw_pprofile"&gt;Wayne Eckerson&lt;/a&gt; at TDWI create this term.  He &lt;a href="http://www.tdwi.org/publications/display.aspx?ID=7166"&gt;described&lt;/a&gt; a spreadmart as:&lt;blockquote&gt;&lt;p&gt;renegade spreadsheets and desktop databases that are wreaking havoc on organizations.   Since then, many people have adopted the term because it highlights a painful, yet largely ignored, problem that plagues organizations today.&lt;/p&gt;&lt;p&gt;Spreadmarts contain vital pieces of corporate data that are needed to run the business. But since spreadmarts are created by individuals at different times using different data sources and rules for defining metrics, they create a fractured view of the enterprise. Without a single version of corporate data and centrally defined metrics, employees can’t share a common understanding the business. With spreadmarts, each worker marches to the “beat of their own drummer” instead of marching together toward a common goal. In short, spreadmarts undermine corporate productivity and sabotage business alignment.&lt;/p&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;div&gt;I think Mr. Eckerson needs to consider Alan Kay's words.  Mr. Eckerson has just cast the creators of spreadmarts as corporate saboteurs that are destroying the One True Way™ that he and and upper management wish to bestow upon their ungrateful underlings.   This is a very top down approach, that probably isn't going to work well.  He does present a 'co-opt' solution where you agree to using CVS output so the spreadsheet jockeys can still use their beloved Excel.  Bu with title like &lt;a href="http://www.tdwi.org/publications/display.aspx?ID=7166"&gt;Reeling in Spreadmarts&lt;/a&gt;, In &lt;a href="http://www.tdwi.org/research/display.aspx?ID=7173"&gt;Search of a Single Version of Truth: Strategies for Consolidating Analytic Silos&lt;/a&gt; and &lt;a href="http://www.tdwi.org/display.aspx?ID=7167"&gt;Taming Spreadsheet Jockeys&lt;/a&gt;, I hear contempt for the existing business processes and the folks on the front line that do the business' work.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Consider how differently Kirk Wylie treats the traders in financial firms in &lt;a href="http://www.infoq.com/presentations/restful-financial-systems-integration"&gt;RESTful Approaches to Financial Services&lt;/a&gt;.  They are exactly the 'spreadsheet jockeys' derided by Eckerson.  Wylie describes centralized systems as über-systems, clearly a derogatory term.  Mr. Wylie also recognizes the proper desire for traders to keep control of their data processing.  He notes that developers are only acquiring the needed business understanding to become productive &lt;i&gt;after three to four months &lt;/i&gt;- he is looking for bottom up solutions that support the 'front line', not centralized solutions to give upper management a dashboard of global &lt;a href="http://management.about.com/cs/generalmanagement/a/keyperfindic.htm"&gt;KPI&lt;/a&gt;s, key performance indicators.  He accepts that "Any system that doesn't consider the traders pathological dependency on Excel is doomed to failure."  In the rest of the talk, he describes how RESTful solutions allow him to roll out shared data across a variety of format, including Excel, to end users on demand.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Like Alan Kay, Kirk Wylie is involved in the same conspiracy as his users.  I'm betting he has more success than Mr. Eckerson is rolling out working systems.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-8776485694708121493?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/8776485694708121493/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/09/involve-them-in-same-conspiracy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8776485694708121493'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8776485694708121493'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/09/involve-them-in-same-conspiracy.html' title='Involve them in the same conspiracy'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-114398345333598325</id><published>2009-09-19T06:40:00.000-07:00</published><updated>2009-09-19T08:15:17.367-07:00</updated><title type='text'>Comp Sci 61A - Online lectures</title><content type='html'>This week, I am starting to follow one series of the &lt;a href="http://www.youtube.com/user/ucberkeley"&gt;online UC Berkeley lectures&lt;/a&gt;.  The lectures are by &lt;a href="http://www.cs.berkeley.edu/~bh/"&gt;Brian Harvey&lt;/a&gt;'s CS 61A from the spring of 2008.  As is always the case, following a lecture without trying to do it yourself is not going to get you far.  &lt;div&gt;In the first two months of the class, Prof. Harvey is examining functional programming with LISP.  To follow along, I am using Clojure.  Installing on OSX amounts to '&lt;span style="font-style:italic;"&gt;sudo port install clojure&lt;/span&gt;'.  The clojure command line is accessed by the &lt;span style="font-style:italic;"&gt;clj&lt;/span&gt; command.   As noted in the lecture, it is easy to write interpreters.  The class uses scheme, so I need a &lt;a href="http://clojure.wikidot.com/scheme-interpreter-in-clojure"&gt;scheme interpreter for clojure&lt;/a&gt;.&lt;div&gt;In order to describe the foundations of computer programming, Prof.  Harvey wrote the following during his &lt;a href="http://www.youtube.com/watch?v=HFxGVf3KAto"&gt;second lecture&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;table&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;caption&gt;Physical foundation of computer science&lt;/caption&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;thead&gt;&lt;tr&gt;&lt;td&gt;Topic&lt;/td&gt;&lt;td&gt;studied in...&lt;/td&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Application Program&lt;/td&gt;&lt;td&gt;CS 61A&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;High level language (Scheme)&lt;/td&gt;&lt;td&gt;CS 61B&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Low Level Langauge (C)&lt;/td&gt;&lt;td&gt;CS 61C&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Machine Langauge/architecture&lt;/td&gt;&lt;td&gt;...&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;circuit elements&lt;/td&gt;&lt;td&gt;EE&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;transistors&lt;/td&gt;&lt;td&gt;applied physics&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;solid state physics&lt;/td&gt;&lt;td&gt;Physics&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Quantum Mechanics&lt;/td&gt;&lt;td&gt;Physics&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;tbody&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This ties in rather naturally with the &lt;a href="http://en.wikipedia.org/wiki/OSI_model"&gt;OSI Seven Layer Model&lt;/a&gt;.  &lt;/div&gt;&lt;br /&gt;&lt;div&gt;This class is presenting a 'real world' view of computer science, not computer science as applied mathematics.  As with the physical sciences and engineering, mathematics is the language, not the subject in CS.  This is not meant to be a put down of math.  &lt;/div&gt;&lt;br /&gt;&lt;div&gt;In the &lt;a href="http://www.youtube.com/watch?v=zmYqShvVDh4"&gt;first lecture&lt;/a&gt;, he gave a concise explanation of 'function' vs. 'procedure'.  I am going to enjoy these lectures...&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-114398345333598325?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/114398345333598325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/09/comp-sci-61a-online-lectures.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/114398345333598325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/114398345333598325'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/09/comp-sci-61a-online-lectures.html' title='Comp Sci 61A - Online lectures'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-8656872282632598026</id><published>2009-09-06T10:23:00.000-07:00</published><updated>2009-09-06T14:22:01.221-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dimension table'/><category scheme='http://www.blogger.com/atom/ns#' term='Type 6 SCD'/><category scheme='http://www.blogger.com/atom/ns#' term='slowly changing dimension'/><category scheme='http://www.blogger.com/atom/ns#' term='data warehouse'/><title type='text'>Slowly Changing DImensions, Type 6 = Type 1 + Type 2 + Type 3</title><content type='html'>Recently, I have designed a multi-tenant data warehouse for AdTrack clients.  One key decision in building a data warehouse is choosing how to deal with slowly changing dimensions (SCD).  In a standard data warehouse, there a two basic types of data tables: fact tables hold information about a particular event (e.g. a record of one sale) and the dimension tables describe how the facts can be organized (e.g. records about stores, customers, products, date of sale).  Basically, you access the data by specifying a 'slice' of each dimension and you then have the database find all the facts that fall within these slices.  The database then lists or summarizes (aggregates) these facts which are displayed in tables and charts which are reported to the users.&lt;div&gt;A major fly in the ointment is that the information in the dimension tables are slowly evolving.  Customers move, change phone numbers, addresses, marital status, last names, jobs and income levels.  Sometimes, you just want the current values.  It is not obvious a priori if clients will care about current values or historical values.  If I were selling hot tubs, does 'current' marital status or 'historic' (e.g. at the time of the sales) marital status matter?  I can imagine an analyst wanting to track sales by marital status, sex and income, so I can see them caring about tracking the history of a client's marital status.  However, if I were to make a report of top 10 married customers for a promotion, I would probably want to add in any sales to that customer when they were still single.  So, unless you know the context, there is no general answer to 'historic' vs. 'current' value when building a data warehouse.  This is doubly true for a mult-tenant warehouse where one client could be selling construction equipment b3b,  another could be selling medical equipment to university hospitals and a third could be selling windows b2c.  Any universal assumption as to what each of these clients need now and forever is going to be badly wrong for some users.&lt;/div&gt;&lt;div&gt;Data warehouse designers will recognize this as the Type 1 SCD (current value ) vs. Type 2 SCD (historic value) decision that needs to be addressed in design.  There is also a Type 3 SCD that has current and 'some history'.  The technorati, or anyone that reads the &lt;a href="http://en.wikipedia.org/wiki/Slowly_changing_dimension"&gt;slowly changing dimensions article&lt;/a&gt; in Wikipeida, will know that there is type which can act like Type 1 SCD, Type 2 SCD or Type 3 SCD.  Since 1+2+3=6, Ralph Kimball called this a Type 6 SCD.  &lt;i&gt;I have come up with a new implementation of a Type 6 SCD&lt;/i&gt;.  My solution is basically a Type 2 SCD, but with the addition of a single column.  I can then build views of this dimension table that function as Type 1, Type 2 or Type 3 SCD.  This solution has now been tested, and the query times are roughly equal for all types of behavior, this is not true of older solutions which could really slow down if you asked for historic values.  At least in the case of using Pentaho PDI, the changes to ETL are simple to implement and can be retrofitted to an existing Type 2 SCD.  If you are interested in how I do this, I have a &lt;a href="http://docs.google.com/fileview?id=0B3-v74N-ocsSZjU0NjA2NGQtNjA0MS00MmNiLTg3MTktYTE5ZTcwMDE1NGI4&amp;hl=en"&gt;paper&lt;/a&gt; on Google Docs that you may read.  If anyone is interested in implementing this, I would be eager to help or to hear if it works for you.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-8656872282632598026?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/8656872282632598026/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/09/slowly-changing-dimensions-type-6-type.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8656872282632598026'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8656872282632598026'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/09/slowly-changing-dimensions-type-6-type.html' title='Slowly Changing DImensions, Type 6 = Type 1 + Type 2 + Type 3'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-4205311087930966942</id><published>2009-08-30T20:00:00.000-07:00</published><updated>2009-09-10T18:39:56.733-07:00</updated><title type='text'>PosgreSQL: how to run on EC2 with EBS</title><content type='html'>Ron Evans has recently blogged in great detail about getting &lt;a href="http://deadprogrammersociety.blogspot.com/2009/08/postgresql-on-ubuntu-on-ec2.html"&gt;PostgreSQL up and running on Ubuntu images on Amazon EC2 &lt;/a&gt;with EBS storage for the database files.  Basically, you use EC2 to provide the server running PostgreSQL and you use EBS, elastic block storage to create a volume that you mount to hold the database files.  Presumably, you can create a second file system to hold WAL segment files, but perhaps you just use S3 to store these.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The next step would be to learn how to create PostgreSQL clusters on EC2.  This isn't much of post, but it is useful to me.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-4205311087930966942?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/4205311087930966942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/08/posgresql-how-to-run-on-ec2-with-ebs.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4205311087930966942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4205311087930966942'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/08/posgresql-how-to-run-on-ec2-with-ebs.html' title='PosgreSQL: how to run on EC2 with EBS'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-8565038100995417868</id><published>2009-08-29T17:22:00.000-07:00</published><updated>2009-08-29T19:57:49.295-07:00</updated><title type='text'>A virtual IT department: the database</title><content type='html'>Software as a Service, SaaS, seems like it is about to revolutionize how small and medium companies run their IT.  Today, many small and medium businesses have really kludgy IT.  There are a bunch of Windows desktops, and a few Windows servers for Exchange, SQL Server, a File Server, a domain server and perhaps a company web site, but that is likely to be a hosted site for  small business.  I think we will see Microsoft's dominance fracture as a result of SaaS.  Today, consider how SaaS may effect SQL Server.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Small companies now have the option of running database services in the cloud.  Using Amazon EC2, they can have a hosted data center with a 99.95% uptime in the SLA.  Of course, this only works when the company has a working internet connection.  Since Amazon is using Xen, you can find tools that will convert between Xen images and Amazon AMI files.  For Debian Linux, that maverick &lt;a href="http://jimmyg.org/blog/2007/custom-debian-ec2-amis-from-xen-images.html"&gt;James Gardner has blogged about this&lt;/a&gt;.  So, you could set up a local server to host Xen and you could then have a piece of the cloud in your data center.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Running SQL Server is a costly proposition.  Enterprise Edition is $25K per CPU.  Microsoft is planning to upgrade on a 2-3 year cycle and they don't intend to support servers more than two generations old.  So your $25K/CPU is recurring fee that will average around $5K/year per CPU.  If you want, you can run &lt;a href="http://aws.amazon.com/windows/"&gt;SQL Server on Amazon EC2&lt;/a&gt;.  There is a premium for this.  Lets assume that you will need a large server.  For Windows alone, this is $0.50 per hour fee.  But adding SQL Server Standard will increase this to $2.20 per hour.  &lt;b&gt;For one year, a hosted SQL Server 2008 Standard Server instance works out to about $19K&lt;/b&gt;.  This isn't crazy for a managed server, but it isn't a cost savings for most companies over running a Windows Server in-house.  So why is there so much buzz about the cloud?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With a few changes, we can save a great deal of money.  For the database engine, consider PostgreSQL.  It is fast and stable.  It has a carefully reviewed code base.  There are drivers for ODBC, JDBC and ADO.Net, so your applications can still access data.  Because PostgreSQL is open source, you can license it for $0.  On Amazon EC2, you can run a medium service instance with Linux for $0.40 per hour.  You can also take advantage of Reserved Instances.  For $1,400 you can reserve a server instance for three years.  This drops the per hour fee to $0.12 per hour.  Three years now costs 4, 555.76.  &lt;b&gt;So for one year, a hosted PostgreSQL instance works out to to just under $1,52&lt;/b&gt;&lt;b&gt;0&lt;/b&gt;. The cloud loves open source.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To be fair, SQL Server also include SSIS, which allows for a variety of ETL services to be built and run via a GUI.  I have been using Pentaho's &lt;a href="http://kettle.pentaho.org/"&gt;Kettle&lt;/a&gt; for this.  Pentaho has renamed this as Pentaho Data Integration.  PDI can be downloaded for free.  S&lt;b&gt;o, with PDI and PostgreSQL, you have the same basic functionality as SQL Server, it just saves $17,766.61 per year for a database server.&lt;/b&gt;   You still get 99.95% data center uptime.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Note: I have not added S3 storage for archiving databases or transaction logs.  This will increase costs, but for both servers.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-8565038100995417868?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/8565038100995417868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/08/virtual-it-department-database.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8565038100995417868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8565038100995417868'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/08/virtual-it-department-database.html' title='A virtual IT department: the database'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-8544280258402948317</id><published>2009-08-16T17:51:00.000-07:00</published><updated>2009-08-30T20:00:14.580-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='EnterpriseDB'/><title type='text'>PostgreSQL: the EnterpriseDB webcasts</title><content type='html'>PostgreSQL is becoming one of my favorite databases.  Postgres is the direct descendent of Ingres, both are the creation of the Berkeley and were authored by Michael Stonebreaker and Eugine Wong.  Other descendants of Ingres include Oracle, Sybase Enterprise Server and Microsoft SQL Server.  PostgreSQL has the advantage of a very clean code base, as demonstrated by Coverity's &lt;a href="http://www.scan.coverity.com/rung1.html"&gt;open source scans&lt;/a&gt;.  A limit for many open source project is getting access to paid support.  In the case of PostgreSQL there is commercial support from EnterpriseDB.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;One of the gems of the EnterpriseDB support is the &lt;a href="http://www.enterprisedb.com/learning/webcasts.do"&gt;wide range of webcasts&lt;/a&gt; about PostgreSQL.  Because PostgreSQL is open source, the developers present detailed information about the internals of PostgreSQL and best practices for database administrators and developers.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-8544280258402948317?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/8544280258402948317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/08/postgresql-enterprisedb-webcasts.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8544280258402948317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8544280258402948317'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/08/postgresql-enterprisedb-webcasts.html' title='PostgreSQL: the EnterpriseDB webcasts'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-1255457578605165935</id><published>2009-08-16T06:03:00.000-07:00</published><updated>2009-08-16T11:04:07.915-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='DB2'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='Oracle'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Server'/><category scheme='http://www.blogger.com/atom/ns#' term='SQL Anywhere'/><category scheme='http://www.blogger.com/atom/ns#' term='Monetdb'/><title type='text'>SQL Server and clustered indexes</title><content type='html'>&lt;p&gt;When a database reads a range of values,  a very common case, you may to read many values and IO usually becomes performance limiting.  These values reside on your data storage, which is almost always a hard drive or a RAID array of hard drives.  To make the IO faster, there are some basic strategies.&lt;/p&gt;&lt;p&gt;First you can make the data more compact.  As an extreme example, consider the case of Decisionmark's Census Counts.  This product provided a database with US Census Bureau Data distributed on a CD.  Watcom SQL Anywhere, now &lt;a href="http://www.sybase.com/products/databasemanagement/sqlanywhere"&gt;Sybase SQL Anywhere&lt;/a&gt;, was used in part because we could &lt;a href="http://www.sybase.com/detail?id=1053701"&gt;compress each row&lt;/a&gt;.  Compared with a hard drive, a CD has very slow data reads.  So it was faster to read data from compressed rows and to unzip the data than it would have been to just read the same data uncompressed.   Since SQL Anywhere's census data was read-only, we didn't need to worry about the write performance.&lt;/p&gt;&lt;p&gt;If you read about some modern database research, you will see that compressing data is one significant strategy in improving performance.  For example, in &lt;a href="http://old-www.cwi.nl/themes/ins1/publications/docs/ZuBoNeHe:DEBULL:05.pdf"&gt;MonetDB/X100 - A DBMS In The CPU Cache Zukowski&lt;/a&gt; and co-workers report &lt;/p&gt;&lt;blockquote&gt;Figure 5 show the speedup of the decompressed queries to be close to the compression ratio, which in case of TPC-H allows for a bandwidth (and performance) increase of a factor 3.&lt;/blockquote&gt;&lt;p&gt;So this is still an area of ongoing work at the frontier of research.  The goal is maximizing the amount of data in each block of storage, so that IO is minimized and performance is maximized.&lt;/p&gt;&lt;p&gt;A second strategy is to use indexes.  An index is a small bit of data that helps you quickly find the larger data recorded in your row.  An index is build by looking at the values of some subset of your row, e.g., one or a few columns.  For each value of the indexed value, you have a pointer to the row that holds the data.  If you have a hash index, the pointer is directly to the row, and if you have a b-tree index, you may have to traverse a few nodes in the tree before you actually get a reference to the data row.  If there is an index that is relevant for a query, it can speed that query significantly.  It can do this by either reducing the IO to find the data (the database engine might otherwise have to read the entire table) or, in many cases, allow the database to avoid reading the table and simply use the index.  Careful choices of indexes can vastly improve performance&lt;/p&gt;&lt;p&gt;A third strategy to improve read performance is physically order the data so that the data for your queries is adjacent on the hard drive.  Unless you are using a solid state drive, you need to be moving the head and rotating the platter to read data.  If the database can read adjacent blocks, it will read faster.  In a typical query, the database engine will use the index to build a list of blocks that need to be read.  If blocks are sequential, they can be read more quickly.&lt;/p&gt;&lt;p&gt;After laying this groundwork, I will now discuss what seems to be a fundamental problem with SQL Servers implementation of table ordering.  In many databases, there is a command that allows the records in a table to  be ordered by an index.  To have a concrete example, consider the case of a department store chain.  The chain has a computer system that records each sale in a purchase table.  The chain has several stores, several departments, many sales representatives and many clients.  To maximize the performance of our purchase table, you may want to order the records by (store, department, sales rep). For example, in PostgreSQL, you can create an index with &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;create index index_purchase_store_dept on purchase (store_id, department_id, order_id)&lt;/span&gt;.  You can then order the table records with the command &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;cluster index_purchase_store_dept on purchase&lt;/span&gt;.   The database engine will then order the data in the purchase table using the index.  This could significantly speed up reports of store or department.  DB2 has a similar concept, where you can define an index to be cluster index for a table, you can then reorganize the table using the REORG utility.  Oracle has a slightly different tactic: a &lt;a href="http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_5001.htm#i2105033"&gt;cluster&lt;/a&gt; is defined in a schema.  You can include up to 32 tables in the cluster and you can define an index to order the tables in the cluster.  This means that not only are the rows in a given table close together, but rows from these tables will be close together.  This takes the idea of clustering to a new level.  Donald Burleson, author of &lt;a href="http://www.rampant-books.com/book_0501_awr_proactive_tuning.htm"&gt;Oracle Tuning&lt;/a&gt;, &lt;a href="http://www.dba-oracle.com/oracle_tip_hash_index_cluster_table.htm"&gt;describes&lt;/a&gt; how these clusters are used.  When records are added to any table in the cluster, they are placed into overflow blocks if there is no more room in the block specified by the index.  When the overflow blocks reach as percent specified in PCTFREE, the records added to the tables get reorganized by the index.&lt;/p&gt;&lt;p&gt;SQL Server, as well as &lt;a href="http://dev.mysql.com/doc/refman/5.0/en/innodb-index-types.html"&gt;MySQL&lt;/a&gt;, makes clustering more convenient by defining an index to be &lt;i&gt;clustered&lt;/i&gt;.   You may declare one index per table to be the clustered index.  To maximize the performance of our purchase table, you may want to order the records by either (store, department, sales rep) or perhaps by (customer). When records are inserted, they are insert in the order specified by the index.  As &lt;a href="http://blogs.msdn.com/sqlserverstorageengine/archive/2008/03/01/example-data-fragmentation-with-insert-updates-measuring-it-and-fixing-it.aspx"&gt;carefully described&lt;/a&gt; in a blog by Sunil Agarwal,  a Program Manager in the SQL Server Storage Engine Group at Microsoft, this will result in a severely fragmented table.&lt;/p&gt;&lt;p&gt;Instead, Microsoft urges the user to define the primary key to be an auto-generated integer and to cluster the table on the primary key's index.  In other words, order the table chronologically.  This seems to fundamentally contradict the concept of clustering.  The records are 'clustered' in groups of one and they groups must be in chronological order.  I checked some tables that followed this rule, and they all had 0% (or at least under 1%) fragmentation on the clustered index, even after a year of operation without maintenance.&lt;/p&gt;&lt;p&gt;Recently, I was asked to improve the performance of set of queries that were run against a SQL Server 2000.  A review of the index statistics showed severe fragmentation, for the reasons outlined by Sunil Agarwal.  To see if defragmenting would matter, I followed the advice in &lt;a href="http://msdn.microsoft.com/en-us/library/cc966523.aspx"&gt;Microsoft SQL Server 2000 Index Defragmentation Best Practices&lt;/a&gt;.  I defragmented the tables used in one particularly slow query.  I was able to reduce the query time from over 4 minutes to just under 10 seconds.  With a rewrite of the query, the query time dropped to under a second. However, after only two days of transaction processing, the clustered index had a fragmentation of over 40%.  The query times were not back to the 4 minute level, but the formerly sub-second query was taking more than 10 seconds.  In this case, the indexes are fragmenting faster than we could reasonably defragment them, since we cannot take this server offline daily to reindex the tables and using DBCC INDEXDEFRAG is simply too slow.&lt;/p&gt;&lt;p&gt;My conclusion is that in order to make clustered indexes useful, you need to be able to append a significant number of rows to a table and then order those records using the clustered index.  Microsoft's solution of inserting each record at the location specified by the clustered index can rapidly cause severe fragmentation.  The solutions of PostgreSQL, Oracle and DB2 avoid this issue, but at the cost of additional maintenance.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-1255457578605165935?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/1255457578605165935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/08/sql-server-and-clustered-indexes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/1255457578605165935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/1255457578605165935'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/08/sql-server-and-clustered-indexes.html' title='SQL Server and clustered indexes'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-173120616997370431</id><published>2009-07-10T13:44:00.000-07:00</published><updated>2009-09-10T19:00:47.555-07:00</updated><title type='text'>Microformats:  Reuse, don't reinvent</title><content type='html'>&lt;div&gt;Orbitz engineer Mark Meeker has an introduction to microformats with examples&lt;br /&gt;&lt;embed id="VideoPlayback" src="http://video.google.com/googleplayer.swf?docid=4912491017216716477&amp;amp;hl=en&amp;amp;fs=true" style="width:400px;height:326px" allowfullscreen="true" allowscriptaccess="always" type="application/x-shockwave-flash"&gt;&lt;/embed&gt;&lt;br /&gt;&lt;br/&gt;This is one of the best introductions I have found.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;I found this Even Bill Gates wants you to use Microformats.&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/Z9X-vHJ_Z-I&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/Z9X-vHJ_Z-I&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;After some reflection, it seems that building an open source object model based upon hCard for people and organizations, hCalendar for events and rel-tags could be useful for many projects.  How often do you end up reinventing classes for people, addresses and so on?  With rel tags, you could define all sorts of relationships between people and institutions: you can add 'subsidiary', 'employee', 'retailer' and build all sorts of models for a wide range of business needs.  If there was a simple object model, with some basic implementations in a few key frameworks, you could start coding from that rather than from scratch.  This would also be useful for learning and comparing frameworks.  Presumably, you could get a REST implementation, an XHTML view, and a WS-* web services almost free.  You would also get the services in a format that would help others build mash-ups with your data.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-173120616997370431?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/173120616997370431/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/07/microformats-reuse-dont-reinvent.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/173120616997370431'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/173120616997370431'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/07/microformats-reuse-dont-reinvent.html' title='Microformats:  Reuse, don&apos;t reinvent'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-7796043425085108399</id><published>2009-07-06T19:50:00.000-07:00</published><updated>2009-08-16T11:08:06.123-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='REST'/><category scheme='http://www.blogger.com/atom/ns#' term='IBM Developer Works'/><category scheme='http://www.blogger.com/atom/ns#' term='AtomPub'/><category scheme='http://www.blogger.com/atom/ns#' term='Joe Gregario'/><category scheme='http://www.blogger.com/atom/ns#' term='Grails'/><title type='text'>The Story of REST: Representational State Transfer</title><content type='html'>Joe Gregario has provided a lucid description of REST at YouTube.  &lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/YCcAE2SCQ6k&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/YCcAE2SCQ6k&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;div&gt;He has also provided a companion video on the Atom Publishing Protocol, which is described in the &lt;a href="http://en.wikipedia.org/wiki/Representational_State_Transfer"&gt;Wikipedia article on Rest&lt;/a&gt; is described as a canonical RESTful protocol.  So Atom provides a great example of a real-world system that uses REST and Joe describes it clearly.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/T04fKsD56LU&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/T04fKsD56LU&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you want a clear understanding of how to use Rest, this may be your best use of half an hour.  If all you want to do is to grok Rest, &lt;a href="http://tomayko.com/"&gt;Ryan Tomayako&lt;/a&gt;'s &lt;a href="http://tomayko.com/writings/rest-to-my-wife"&gt;How I Explained RESR To My Wife&lt;/a&gt; is a classic, and it only takes five to ten minutes.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you have more time and really want to understand in greater detail, there is &lt;a href="http://roy.gbiv.com/"&gt;Roy Thomas Fielding&lt;/a&gt;'s dissertation, &lt;a href="http://www.ics.uci.edu/%7Efielding/pubs/dissertation/top.htm"&gt;Architectural Styles and&lt;br /&gt;the Design of Network-based Software Architectures&lt;/a&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For an actual implementation of a REST service, I am keen to use Grails.  Grails has &lt;a href="http://grails.org/doc/1.0.x/guide/13.%20Web%20Services.html"&gt;build-in support&lt;/a&gt; for REST.   Grails also &lt;a href="http://grails.org/doc/1.0.x/guide/single.html#6.8%20Content%20Negotiation"&gt;offers content negotiation&lt;/a&gt;.  In HTTP, part of the request is a specification of the media type.  Using &lt;a href="http://en.wikipedia.org/wiki/Content_negotiation"&gt;content negotiation&lt;/a&gt;, the user agent can specify which format it prefers.  This means that a URL for a person could return a portrait as image/jpeg, a hcard page via text/html, the vcard data as text/json, text/plain,  text/xml, or text-plain.  You could also use content negotiation to specify the language for the response.  Suddenly URL seems to be the locator for a universal resource,  as well as being the universal locator of a resource.&lt;br /&gt;&lt;br /&gt;While it may be feasible to support multiple mime types at a single URL, it is not trivial to provide multiple representations of the same item.  Even converting between two apparently similar data format has surprising complexity, as discussed in&lt;br /&gt;&lt;a href="http://www.ibm.com/developerworks/library/x-atom2json.html"&gt;Convert Atom documents to JSON&lt;/a&gt; at &lt;a href="http://www.ibm.com/developerworks/"&gt;&lt;/a&gt;&lt;a href="http://www.ibm.com/us/en/"&gt;IBM &lt;/a&gt;Developer Works.   The Developer Works also has a &lt;a href="http://www.ibm.com/developerworks/views/java/libraryview.jsp?search_by=mastering+grails"&gt;series of papers on Grails&lt;/a&gt;, which has specific examples of using &lt;a href="http://www.ibm.com/developerworks/java/library/j-grails06099/index.html?S_TACT=105AGX02&amp;amp;S_CMP=EDU"&gt;Grails with Atom syndication&lt;/a&gt;.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-7796043425085108399?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/7796043425085108399/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/07/story-of-rest-representational-state.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/7796043425085108399'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/7796043425085108399'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/07/story-of-rest-representational-state.html' title='The Story of REST: Representational State Transfer'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-8552975792086634264</id><published>2009-07-02T18:13:00.000-07:00</published><updated>2009-08-16T11:20:19.630-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Henrik Gemal'/><category scheme='http://www.blogger.com/atom/ns#' term='Brendon Boshell'/><category scheme='http://www.blogger.com/atom/ns#' term='Browser Spy'/><category scheme='http://www.blogger.com/atom/ns#' term='Web 2.0 Collage'/><category scheme='http://www.blogger.com/atom/ns#' term='Geolocation'/><title type='text'>What HTTP reveals about your browser.</title><content type='html'>When surfing the web, is easy to feel that you are a relatively anonymous consumer of content.   However, the HTTP traffic between your browser and the web server is a two way street.  Henrik Gemal has provided &lt;a href="http://browserspy.dk/"&gt;browserspy.dk&lt;/a&gt; which has a series of queries that find our more about your browser than you probably know.  Much of this information is potentially quite useful to the web site.  The classic example is the HTTP_ACCEPT_ENCODING &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html"&gt;header&lt;/a&gt; that tells the server if  your browser can accept compressed data.  This can significantly reduce the size of a page.  The other classic use is to identify Internet Explorer, the bane of JavaScript and CSS authors.  But this is just the start.  By &lt;a href="http://browserspy.dk/flash.php"&gt;knowing which version of Flash is installed&lt;/a&gt;, YouTube can warn you if you need to upgrade to view their video content.  By sensing &lt;a href="http://browserspy.dk/screen.php"&gt;color depth&lt;/a&gt; and &lt;a href="http://browserspy.dk/window.php"&gt;window size&lt;/a&gt;,  a web site could determine an optimum image for me.  This would be especially useful on a mobile device, where throughput and CPU limit battery life.&lt;br /&gt;&lt;br /&gt;I would really like it if the &lt;a href="http://browserspy.dk/geolocation.php"&gt;geolocation&lt;/a&gt; information could be used to set the default country, state and city in web forms.  In my case, the geolocation would have gotten me to Iowa, but would have placed me in Hiawatha rather than Marion.  There is another &lt;a href="http://www.gauravv.com/demo/demo_geolocation.html"&gt;geolocation demo&lt;/a&gt; that gets closer, but is still off by about 3 miles.  I would like to be able to set a location, address and hcard info and have the option of using that on web forms.  I would encourage more browser providers to support the navigator.geolocation object in the &lt;a href="http://www.w3.org/"&gt;W3C&lt;/a&gt; &lt;a href="http://dev.w3.org/geo/api/spec-source.html"&gt;Geolocation API&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;But in my opinion, the scary information is from a &lt;a href="http://browserspy.dk/css-exploit.php"&gt;CSS Exploit&lt;/a&gt; page.  This exploit has been &lt;a href="http://yro.slashdot.org/story/09/07/02/1317205/Your-Browser-History-Is-Showing?art_pos=20"&gt;covered today in Slashdot&lt;/a&gt;.   &lt;a href="http://web2.0collage.com/"&gt;Web 2.o Collage&lt;/a&gt; will &lt;a href="http://web2.0collage.com/app/"&gt;produce&lt;/a&gt; a collection of favicons of sites you have visited.  What is most surprising to me is that &lt;a href="http://www.making-the-web.com/misc/sites-you-visit/nojs/"&gt;this exploit&lt;/a&gt; by &lt;a href="http://making-the-web.com/contact/" target="_blank" style="color: rgb(0, 0, 255); "&gt;Brendon Boshell&lt;/a&gt; doesn't even require JavaScript.  He has a &lt;a href="http://www.making-the-web.com/misc/sites-you-visit/"&gt;Javascript version&lt;/a&gt; as well, which he &lt;a href="http://www.making-the-web.com/2009/04/12/mass-browser-history-sniffing-with-javascript/"&gt;describes in detail&lt;/a&gt;.  So, unless you use one of the 'stealth modes' that don't record history, anyone can be checking to see if you have visited a particular site.  Think about how that could facilitate a phishing attack.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-8552975792086634264?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/8552975792086634264/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/07/what-http-reveals-about-your-browser.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8552975792086634264'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8552975792086634264'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/07/what-http-reveals-about-your-browser.html' title='What HTTP reveals about your browser.'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-7640389044745639621</id><published>2009-06-30T17:24:00.001-07:00</published><updated>2009-08-16T11:09:38.067-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='V8 Benchmarks'/><category scheme='http://www.blogger.com/atom/ns#' term='Parallels'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='iMac'/><category scheme='http://www.blogger.com/atom/ns#' term='Chrome'/><title type='text'>V8 - the extremes</title><content type='html'>When it comes to the V8 Benchmarks, Chrome is still king, even on a Mac.  Despite the fact that this is running under Parallels, Chrome 2 is almost twice as fast on the iMac as it is on the Dell at work.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_H9cmDV9xmSo/Skqs44HbhPI/AAAAAAAACDs/YsCRJ_fHn7U/s1600-h/v8chrome2xp.png"&gt;&lt;img style="cursor: pointer; width: 264px; height: 320px;" src="http://3.bp.blogspot.com/_H9cmDV9xmSo/Skqs44HbhPI/AAAAAAAACDs/YsCRJ_fHn7U/s320/v8chrome2xp.png" alt="" id="BLOGGER_PHOTO_ID_5353281200219456754" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Here is the real surprise.  While every other browser ran faster on the iMac than the Dell, IE8 actually slowed down.  But the slow down is almost entirely due to the final test, Splay.  Google describes this test:&lt;br /&gt;&lt;blockquote&gt;Data manipulation benchmark that deals with splay trees and exercises the automatic memory management subsystem (378 lines).&lt;br /&gt;&lt;/blockquote&gt;So it seems that the VM on the Mac can have performance issues with memory management.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_H9cmDV9xmSo/Skqs4ulTeYI/AAAAAAAACDk/Obc_XDa_qdg/s1600-h/v8ie8.png"&gt;&lt;img style="cursor: pointer; width: 230px; height: 320px;" src="http://2.bp.blogspot.com/_H9cmDV9xmSo/Skqs4ulTeYI/AAAAAAAACDk/Obc_XDa_qdg/s320/v8ie8.png" alt="" id="BLOGGER_PHOTO_ID_5353281197660404098" border="0" /&gt;&lt;/a&gt;&lt;div&gt;If there is a problem with memory management, perhaps I should shut down all of the other applications and see if the numbers improve.  Yup.  Look at Splay: it went from 0.397 to 143.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_H9cmDV9xmSo/SkqwYemMjuI/AAAAAAAACD0/r-Y5mFVmasY/s1600-h/v8ie8only.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 210px; height: 320px;" src="http://2.bp.blogspot.com/_H9cmDV9xmSo/SkqwYemMjuI/AAAAAAAACD0/r-Y5mFVmasY/s320/v8ie8only.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5353285041659875042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So, running Parallels usually works fine, but in this case, it seems important to help the memory management along by closing down other applications.  Still, it is IE8 which is far behind the other browsers in terms of JavaScript performance.  Hey Microsoft, any chance you can keep up with the pack?&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-7640389044745639621?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/7640389044745639621/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/v8-extremes.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/7640389044745639621'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/7640389044745639621'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/v8-extremes.html' title='V8 - the extremes'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_H9cmDV9xmSo/Skqs44HbhPI/AAAAAAAACDs/YsCRJ_fHn7U/s72-c/v8chrome2xp.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-520776692334637985</id><published>2009-06-30T16:55:00.000-07:00</published><updated>2009-06-30T17:15:16.525-07:00</updated><title type='text'>More V8 - on an iMac</title><content type='html'>&lt;div&gt;After running the &lt;a href="http://v8.googlecode.com/svn/data/benchmarks/v4/run.html"&gt;V8 benchmark  suite&lt;/a&gt; at work, I am repeating at home.  Home means a iMac with a 2.93 GHz Intel Core 3 Duo with 4 GB.  I'm running Leopard (10.5.7).    This time, I was more interested in looking at the improvements in Firefox 3.5 relative to Firefox 3.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But first, here are the results for Safari 2, this time running on OS/X.&lt;/div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_H9cmDV9xmSo/Skqmimzy7lI/AAAAAAAACDc/ECX7CdgomGE/s1600-h/v8safari2osx.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 311px; height: 320px;" src="http://1.bp.blogspot.com/_H9cmDV9xmSo/Skqmimzy7lI/AAAAAAAACDc/ECX7CdgomGE/s320/v8safari2osx.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5353274220546813522" /&gt;&lt;/a&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_H9cmDV9xmSo/Skqmimzy7lI/AAAAAAAACDc/ECX7CdgomGE/s1600-h/v8safari2osx.png"&gt;&lt;/a&gt;For some reason, Blogger reverses the order of the images, so here we have the results for Firefox 3.5.  There are two runs, one under OS/X and the other on XP.  The XP version is running under Parallels.  It sure looks like the VM running XP is very efficient: the Firefox numbers are within a few percent.  They are also twice as fast the Dell Optiplex at work, even if the memory and clock speeds are quite similar.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_H9cmDV9xmSo/SkqmiTHZfxI/AAAAAAAACDU/h14RF_7F9Is/s1600-h/v8ff35xp.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 201px; height: 320px;" src="http://3.bp.blogspot.com/_H9cmDV9xmSo/SkqmiTHZfxI/AAAAAAAACDU/h14RF_7F9Is/s320/v8ff35xp.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5353274215260323602" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_H9cmDV9xmSo/SkqmiF1KCWI/AAAAAAAACDM/bui8m1r6xFI/s1600-h/v8ff35osx.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 275px; height: 320px;" src="http://3.bp.blogspot.com/_H9cmDV9xmSo/SkqmiF1KCWI/AAAAAAAACDM/bui8m1r6xFI/s320/v8ff35osx.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5353274211694152034" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_H9cmDV9xmSo/SkqmiF1KCWI/AAAAAAAACDM/bui8m1r6xFI/s1600-h/v8ff35osx.png"&gt;&lt;/a&gt;Finally, we see the results of the old Firefox 3.  The upgrade almost doubled the speed.  So kudos to the Firefox team for the improvement in JavaScript performance.  But we still have to recognize that the Webkit-based browsers are really dominating the JavaScript performance numbers.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_H9cmDV9xmSo/Skqmh-YZ9hI/AAAAAAAACDE/fRNfLfWLP7c/s1600-h/v8ff3xp.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 246px; height: 320px;" src="http://1.bp.blogspot.com/_H9cmDV9xmSo/Skqmh-YZ9hI/AAAAAAAACDE/fRNfLfWLP7c/s320/v8ff3xp.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5353274209694512658" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_H9cmDV9xmSo/Skqmhr2lBWI/AAAAAAAACC8/zRFQRjh0xSo/s1600-h/v8ff3osx.png"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 267px; height: 320px;" src="http://4.bp.blogspot.com/_H9cmDV9xmSo/Skqmhr2lBWI/AAAAAAAACC8/zRFQRjh0xSo/s320/v8ff3osx.png" border="0" alt="" id="BLOGGER_PHOTO_ID_5353274204720792930" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-520776692334637985?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/520776692334637985/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/more-v8-on-imac.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/520776692334637985'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/520776692334637985'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/more-v8-on-imac.html' title='More V8 - on an iMac'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_H9cmDV9xmSo/Skqmimzy7lI/AAAAAAAACDc/ECX7CdgomGE/s72-c/v8safari2osx.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-3344097671559520648</id><published>2009-06-30T15:09:00.001-07:00</published><updated>2009-08-16T11:17:04.463-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='V8 Benchmarks'/><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Webkit'/><category scheme='http://www.blogger.com/atom/ns#' term='Safari'/><category scheme='http://www.blogger.com/atom/ns#' term='Chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>V8 Benchmarks</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_H9cmDV9xmSo/SkqPBVi_jMI/AAAAAAAACC0/ENc4nzYlUuY/s1600-h/v8chrome2.PNG"&gt;&lt;img style="cursor: pointer; width: 275px; height: 320px;" src="http://1.bp.blogspot.com/_H9cmDV9xmSo/SkqPBVi_jMI/AAAAAAAACC0/ENc4nzYlUuY/s320/v8chrome2.PNG" alt="" id="BLOGGER_PHOTO_ID_5353248360209812674" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_H9cmDV9xmSo/SkqPBPWRKTI/AAAAAAAACCs/ExGAxmAcMJc/s1600-h/v8safari2.PNG"&gt;&lt;img style="cursor: pointer; width: 314px; height: 320px;" src="http://2.bp.blogspot.com/_H9cmDV9xmSo/SkqPBPWRKTI/AAAAAAAACCs/ExGAxmAcMJc/s320/v8safari2.PNG" alt="" id="BLOGGER_PHOTO_ID_5353248358545828146" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_H9cmDV9xmSo/SkqPA8vwsFI/AAAAAAAACCk/6OQaBU4jRXs/s1600-h/v8ff35.PNG"&gt;&lt;img style="cursor: pointer; width: 210px; height: 320px;" src="http://4.bp.blogspot.com/_H9cmDV9xmSo/SkqPA8vwsFI/AAAAAAAACCk/6OQaBU4jRXs/s320/v8ff35.PNG" alt="" id="BLOGGER_PHOTO_ID_5353248353552478290" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_H9cmDV9xmSo/SkqPA58jSCI/AAAAAAAACCc/v7WBrzPFMpM/s1600-h/v8ie8.PNG"&gt;&lt;img style="cursor: pointer; width: 233px; height: 320px;" src="http://3.bp.blogspot.com/_H9cmDV9xmSo/SkqPA58jSCI/AAAAAAAACCc/v7WBrzPFMpM/s320/v8ie8.PNG" alt="" id="BLOGGER_PHOTO_ID_5353248352800819234" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Google's V8 Benchmark Suite is&lt;a href="http://v8.googlecode.com/svn/data/benchmarks/v3/run.html"&gt; easy to run&lt;/a&gt;.  Here are the results for several new browsers on my workstation, which is a Dell Optiplex GX620 with 2.79 GHz Pentium D and 3.49 GB of RAM.  Wow.  I didn't expect to see Webkit being this much faster.  If my brand new Firefox 3.5 is given a relative score of 1, Safari 4 on Windows has a score of 7.5, Google Chrome has a relative score of 8.6.  Internet Explore 8 has a score of 0.21.  &lt;span style="font-style: italic;"&gt;Webkit browsers have an order of magnitude better performance than Microsoft's flagship browser: IE8.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, is Microsoft that bad a writing a JavaScript interpreter or are they trying to move us away from web standards like JavaScript and toward Silverlight?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-3344097671559520648?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/3344097671559520648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/v8-benchmarks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3344097671559520648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3344097671559520648'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/v8-benchmarks.html' title='V8 Benchmarks'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_H9cmDV9xmSo/SkqPBVi_jMI/AAAAAAAACC0/ENc4nzYlUuY/s72-c/v8chrome2.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-8779040528052855747</id><published>2009-06-19T18:04:00.000-07:00</published><updated>2010-01-23T09:56:32.162-08:00</updated><title type='text'>Jef Jarvis and what to do next</title><content type='html'>Jeff Jarvis has more gray hair than me, but he really seems to understand the Internet.  He may be best know as the author of &lt;a href="http://www.buzzmachine.com/what-would-google-do/"&gt;What Would Google Do?&lt;/a&gt;  You can &lt;a href="http://browseinside.harpercollins.com/index.aspx?isbn13=9780061709715"&gt;read it online&lt;/a&gt;.  &lt;a href="http://fora.tv/"&gt;Fora.tv&lt;/a&gt; has some lectures of his:&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://fora.tv/2009/03/04/Jeff_Jarvis_Future_of_Media_and_the_Prospects_for_Brands#fullprogram"&gt;Future of Media and the Prospects for Brands&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://fora.tv/2009/02/18/Jeff_Jarvis_What_Would_Google_Do"&gt;What Would Google Do?&lt;/a&gt; (the Video)&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;After listening to him, I am getting jazzed to try some Web 2.0 projects.   He advocates being small, but being part of something big.  So, what are some big things that we can expect to see?  Here is something that comes to mind:&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;We all like images, and its probably the case that we have pictures all over the place that we like to access.  I have pictures on Picasa, a friend has images on MobileMe, my wife has images on SmugMug and Flickr.  My kids have images on FaceBook.  This is probably pretty common.  I don't want more ways to store images, I want a way to reference and search these images.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For images, I would like to have a linker site that lets me reference feeds, on line albums or even individual images on the Internet.  Many of these sources provide titles, descriptions and other image metadata.  Many images also have EXIF or IPTC metadata.  What would be great would be a simple web interface to allow me to build a tool to subscript to several different sources and then subscribe to unified feed.  Give the feed a URL and share with friends and family.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Even better, allow images to be linked to urls that identify people -  hcard descriptions, home pages, FaceBook pages and so on.  Then, you tag images (or better yet, some section of each image) with links to a person.  The tags should have some 'types' like 'photographer/owner', 'model/subject' that show the relationship between the person and the image.  Some key words links to images would also be great.  They I could build feeds for all images linked to family in the last 6 months.  Each of these dynamic albums could be given a URL on PubSubHubBub and expose the results has Media RSS.  Then, anyone with a Media RSS viewer could see the feed in a browser.  Open Iris and Slideshow Pro have inovative Media RSS viewers.&lt;/div&gt;&lt;div&gt;  &lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-8779040528052855747?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/8779040528052855747/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/jef-jarvis-and-what-to-do-next.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8779040528052855747'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/8779040528052855747'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/jef-jarvis-and-what-to-do-next.html' title='Jef Jarvis and what to do next'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-9101459775436309173</id><published>2009-06-17T15:30:00.000-07:00</published><updated>2009-08-16T11:18:09.859-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Wave'/><category scheme='http://www.blogger.com/atom/ns#' term='Eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Software Tutorials on Google Wave: Eclipsy</title><content type='html'>Google Wave absolutely floors me, but it isn't available yet.  I think that Wave is going to revolutionize teaching software.  Consider software tutorials.  First, we need something like an &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;Eclipsy&lt;/span&gt;, a hypothetical  Wave agent/Eclipse plug-in that allows Eclipse to be integrated into a Wave.  As one developer goes through the steps in a tutorial, a second developer (or even the same developer with a microphone), could be giving a verbal description of the actions.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Once the expert has successfully performed the tutorial, a student else could play it back and see each step in the processes.  I see major advantages of using Wave.  Perhaps you could play back the development in your Eclipse while listening to the process, with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;Eclipsy&lt;/span&gt; in a playback-mode.  At the end of this, you would know that the process worked with your configuration.  Assuming that it did work, you could then go through the steps yourself while listening to the audio &amp;amp; perhaps watching the steps in Eclipse  running on some virtual machine that you would watch as your copy the steps at home.  (Two monitors would be nice for this.)  The ability to pause during the playback is a big advantage of a Wave solution.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;With many Web 2.0 tools like Grails, you are iteratively developing you application.  For example, you might start by defining all of your  domain objects and use scaffolding to build the controllers.  You would then define the relationships between all of the objects.  Next, you might add more attributes.  To complete the domain objects, you could go in and add the constraints.  This sort of iterative approach seems perfect for the as-yet-hypothetical &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;Eclipsy&lt;/span&gt;.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Typically, you would also follow an iterative approach to evolving the views and the controllers.  Much of the skill in this approach is having a feel to know what to do in each iteration.  &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Eclipsy&lt;/span&gt; would be a good way to developing this.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In a complementary role, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;Eclipsy&lt;/span&gt; seems like it could be used for version control.  At the very least, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;Eclipsy&lt;/span&gt; would be tracking the state of each source code file and your project configuration.  This means that it could also function as a version control system that you could replay to get to any state in your development.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-9101459775436309173?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/9101459775436309173/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/software-tutorials-on-google-wave.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/9101459775436309173'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/9101459775436309173'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/software-tutorials-on-google-wave.html' title='Software Tutorials on Google Wave: Eclipsy'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-5782056586813993056</id><published>2009-06-16T07:15:00.000-07:00</published><updated>2009-08-16T11:15:24.733-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Internet Explorer'/><category scheme='http://www.blogger.com/atom/ns#' term='Acid 3'/><category scheme='http://www.blogger.com/atom/ns#' term='Safari'/><category scheme='http://www.blogger.com/atom/ns#' term='Chrome'/><category scheme='http://www.blogger.com/atom/ns#' term='Opera'/><category scheme='http://www.blogger.com/atom/ns#' term='Firefox'/><title type='text'>IE8: on Acid3</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_H9cmDV9xmSo/SjeuhS972OI/AAAAAAAACCU/jIY0Pie5BN4/s1600-h/acid3_ie8_20.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 310px; height: 320px;" src="http://2.bp.blogspot.com/_H9cmDV9xmSo/SjeuhS972OI/AAAAAAAACCU/jIY0Pie5BN4/s320/acid3_ie8_20.PNG" alt="" id="BLOGGER_PHOTO_ID_5347934969576282338" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_H9cmDV9xmSo/Sjerp_1lUDI/AAAAAAAACCE/7laUFu5dxeg/s1600-h/acid3_ie8_12.PNG"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer; width: 310px; height: 320px;" src="http://2.bp.blogspot.com/_H9cmDV9xmSo/Sjerp_1lUDI/AAAAAAAACCE/7laUFu5dxeg/s320/acid3_ie8_12.PNG" alt="" id="BLOGGER_PHOTO_ID_5347931820524916786" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_H9cmDV9xmSo/Sjep34-HpjI/AAAAAAAACB8/iOcM9oSzgsA/s1600-h/about_ie8.PNG"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 374px; height: 352px;" src="http://4.bp.blogspot.com/_H9cmDV9xmSo/Sjep34-HpjI/AAAAAAAACB8/iOcM9oSzgsA/s400/about_ie8.PNG" alt="" id="BLOGGER_PHOTO_ID_5347929860176586290" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Just for fun, I tested Internet Explorer 8 on the Acid3 test.  For completeness, the test was run on the morning of June 16, 2009.  Today, Opera 10 was released.  Opera 10, along with the recently released Safari 4, have attained a score of 100% on the Acid3 test.  I also tested Chrome, release 2.0.172.31, and it also scored 100%.       Is browser conformance breaking out?  Helas, no.  Just to prove what I say, I'm including bitmaps of 'About Internet Explorer at the time of the test.  As you can read, I am using version 8.0.6001.18702.  This is running on XP, as you can probably guess from the title bar.&lt;br /&gt;During the test, I was asked if I wanted to let an ActiveX component run, I believe that it was for XML processing, but I foolishly clicked OK before recording the component name.  The test looked like it completed at 12%.  I was surprised to see what appears to be an HTML text area suddenly pop up.&lt;br /&gt;&lt;br /&gt;After several seconds, the score started to creep up, finally reaching 20%.  This is  consistent with the scores reported at &lt;a href="http://www.anomalousanomaly.com/2008/03/06/acid-3/"&gt;Anomalous Anomaly&lt;/a&gt;, which has much more complete Acid3 test results.  Finally, I tested Firefox 3.0.10, which produced a score of 71%.  As expected, this is also consistent with Steve Noonan's results at Anomalous Anomaly.&lt;br /&gt;&lt;br /&gt;I also checked Acid2, all the browsers scored 100%.  Perhaps there is still hope that bothIE and Firefox will be made more standard compliant so that there Acid3 scores can match their Acid2 scores.&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;[followup on July 20, 2009]&lt;/span&gt; Firefox 3.5 is making rapid progress.  With Firefox 3.5.1, I have an Acid3 score of 93.  My IE scores have remained the same.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-5782056586813993056?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/5782056586813993056/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/ie8-on-acid3.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/5782056586813993056'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/5782056586813993056'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/ie8-on-acid3.html' title='IE8: on Acid3'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_H9cmDV9xmSo/SjeuhS972OI/AAAAAAAACCU/jIY0Pie5BN4/s72-c/acid3_ie8_20.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-580385210161695405</id><published>2009-06-13T13:41:00.000-07:00</published><updated>2009-08-16T11:24:08.941-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Ben Fry'/><category scheme='http://www.blogger.com/atom/ns#' term='GWT'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenLaszlo'/><category scheme='http://www.blogger.com/atom/ns#' term='Bret Victor'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Web Toolkit'/><category scheme='http://www.blogger.com/atom/ns#' term='Pentaho BI Server'/><title type='text'>Richer web interfaces</title><content type='html'>Web interfaces are improving all around.  With tools like &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_0"&gt;GWT&lt;/span&gt; and &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_1"&gt;OpenLaszlo&lt;/span&gt;, it is possible to build rich web applications with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_2"&gt;GUIs&lt;/span&gt; that at least match stand-alone applications.  Some of the applications that I am finding innovative include:&lt;div&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.pentaho.com/products/try_bi_suite.php"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_3"&gt;Pentaho&lt;/span&gt; BI Server&lt;/a&gt;.  Their new Mantle &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_4"&gt;UI&lt;/span&gt; is build with &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_5"&gt;GWT&lt;/span&gt; and is a huge jump beyond the old interface.  It just behaves like a stand-alone application.  Some of the components, especially &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_6"&gt;jPivot&lt;/span&gt;,  could use an update, but the Server platform is in a great place to organize all of these new features.  With the modular design of BI Server 3.0, &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_7"&gt;Pentaho&lt;/span&gt; users will be seeing a great deal of new reporting and analytic tools they can plug in.&lt;/li&gt;&lt;li&gt;&lt;a href="http://g.ho.st/main.jsp"&gt;G.ho.st&lt;/a&gt;, the &lt;i&gt;g&lt;/i&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_8"&gt;lobally&lt;/span&gt; &lt;i&gt;ho&lt;/i&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_9"&gt;sted&lt;/span&gt; operating &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_10"&gt;sy&lt;/span&gt;&lt;i&gt;st&lt;/i&gt;em, is a virtual computer that you can access from anywhere.  You have a full GUI, built in &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_11"&gt;OpenLaszlo&lt;/span&gt;, apparently by their team of only 30-40 staff.  Ghost seeks to provide a free, web-based virtual computer for anyone in the world.  The &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_12"&gt;UI&lt;/span&gt; is fast and simply doesn't feel like a browser.  Have a look.&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.openlaszlo.org/lps4.2/demos/lzpix/app.lzx?lzr=swf9&amp;amp;lzt=html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_13"&gt;LZPIX&lt;/span&gt;&lt;/a&gt; is another &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_14"&gt;OpenLaszlo&lt;/span&gt; application for viewing photos on &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_15"&gt;Flickr&lt;/span&gt;.  The link is to the Flash version, there is also a &lt;a href="http://www.openlaszlo.org/lps4.2/demos/lzpix/app.lzx?lzr=dhtml&amp;amp;lzt=html"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_16"&gt;DHTML&lt;/span&gt; version&lt;/a&gt; and you can see the &lt;a href="http://www.openlaszlo.org/lps4.2/demos/calendar/calendar.lzx?lzt=source"&gt;source code&lt;/a&gt; as well.  On a side note, open the application and search for '&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_17"&gt;toureiffel&lt;/span&gt;' , the photo &lt;a href="http://www.flickr.com/photos/gadl/456185667/"&gt;Paris &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_18"&gt;s'éveille&lt;/span&gt;&lt;/a&gt; is magnificent!&lt;/li&gt;&lt;li&gt;&lt;a href="http://sites.google.com/site/jtvmaker/"&gt;Maple&lt;/a&gt; is another interesting tool to view photos, but it is designed for multimedia slide shows.  This can run as either a Java application or a  a Java Applet.  It uses Java 6, and my shiny new Mac only has Java 5, so the only way for me to view this is running a &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_19"&gt;VM&lt;/span&gt; with either Windows or Linux so I can install Java 6, which was released in December 2006.  Come on Apple, is it not possible to get the bugs out in 2 1/2 years!?  Oh well, one more reason to hope for Snow Leopard.  I just hope that they have a Java 6 upgrade for Leopard, since I can't run Snow Leopard on the older G4/G5 Macs.  I was going to ask why Java applets didn't catch on like Flash applets, but I guess when you have trouble accessing a consistent Java platform across OS/X and Windows,  the answer is clear.  This is unfortunate, as Maple is a great slide show viewer.  Java really does work, it is just a shame that it has  been held captive by an Apple or Microsoft.&lt;/li&gt;&lt;li&gt;Ben Fry's &lt;a href="http://benfry.com/zipdecode/"&gt;&lt;span class="blsp-spelling-error" id="SPELLING_ERROR_20"&gt;zipdecode&lt;/span&gt;&lt;/a&gt;.  Try this and tell me why this shouldn't be part of any application that needs a zip code.  It should be easy to gather the data needed to make this international.  If I am filling out a web form, why do I have to type in 52302 and then choose Marion, Iowa? There are some &lt;span class="blsp-spelling-error" id="SPELLING_ERROR_21"&gt;zipcodes&lt;/span&gt; that server multiple communities, but in that case, I would just need one extra click to pick the city.  The only thing I would add to this applet would be a semi-transparent zip code on top of the map.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;What we need to do is develop simple, rest-based tools that we can easily drop into web applications.  If your application is residing on the web, you should be able to simply reference well designed tools.  The current practice of installing web apps on your application's server seems to undercut the promise of the web.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;For a coherent theory of how software should be designed for people, I recommend Bret Victor's &lt;a href="http://worrydream.com/MagicInk/"&gt;Magic Ink&lt;/a&gt;.  He has thought deeply about this, while I am just providing examples.&lt;/div&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;  In some ways, it is possible to outdo stand-alone applications.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-580385210161695405?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/580385210161695405/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/richer-web-interfaces.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/580385210161695405'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/580385210161695405'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/richer-web-interfaces.html' title='Richer web interfaces'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-3954413254055048892</id><published>2009-06-05T13:23:00.000-07:00</published><updated>2009-08-16T11:18:58.430-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google Wave'/><category scheme='http://www.blogger.com/atom/ns#' term='Google Gears'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Google I/O viewed from IOwa.</title><content type='html'>With some software presentations, you are overwhelmed by the show but afterwards the gee-wiz wears off as you start to piece together what is going on.  But the more I think about &lt;a href="http://wave.google.com/"&gt;Google Wave&lt;/a&gt;, the more the ideas are growing on me.  At this time, hardly anyone has heard about Google Wave, but that is going to change.  Within a few years, Google Wave could be recognized one of the few paradigm changing applications, much like  hypertext going mainstream was to the growing of the web in the 1990's.    &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the developer preview, there were no lack of eye-popping features:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;Drag and drop photos from iPhoto into the browser.  Really cool use of Gears and GWT.  Watching the photo upload automatically and appear on the other browsers in seconds was a direct reminder to me that we are only beginning to understand how the web can connect us.&lt;/li&gt;&lt;li&gt;Watching real-time translation between French and English shows how we are going to be able to interact more freely in wider communities.&lt;/li&gt;&lt;li&gt;The &lt;a href="http://www.endesha.com/blog/on-google-wave-part-5-version-control/"&gt;multiple, concurrent editing&lt;/a&gt; of a single document shows how much power there is concurrent versioning systems. &lt;/li&gt;&lt;li&gt;The use of &lt;a href="http://www.endesha.com/blog/on-google-wave-part-1-architecture/"&gt;associative memory&lt;/a&gt;, which resides not only on the server, but is shared with each participant is part of the secret sauce that makes is seem that everyone on the wave is 'together'.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;This just seems like it is the next phase in the evolution of the world wide web.  Before this, the web was a bunch of places to go.  With Wave, it will become a bunch of events to join, review and create.&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-3954413254055048892?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/3954413254055048892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/google-io-viewed-from-iowa.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3954413254055048892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3954413254055048892'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/06/google-io-viewed-from-iowa.html' title='Google I/O viewed from IOwa.'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-4318262755456518857</id><published>2009-05-15T14:59:00.000-07:00</published><updated>2009-08-16T11:22:16.266-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Samba'/><category scheme='http://www.blogger.com/atom/ns#' term='OpenOffice.org'/><category scheme='http://www.blogger.com/atom/ns#' term='ZD Net'/><category scheme='http://www.blogger.com/atom/ns#' term='FLOSS'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><category scheme='http://www.blogger.com/atom/ns#' term='SMB Protocol'/><title type='text'>Innovation in the computer industry</title><content type='html'>Most innovations are combinations of existing ideas, this is how innovation works.  In a &lt;a href="http://blogs.zdnet.com/BTL/?p=17993"&gt;recent ZD Net blog&lt;/a&gt;, Larry Dignan examined how effective Microsoft, IBM and others are at profiting from their R&amp;amp;D spending.  The article seems quite reasonable and the claims seem well supported. &lt;div&gt;But in the comments, there was a recurring meme that claimed that there is no innovation in FLOSS software.  For example, &lt;a href="http://talkback.zdnet.com/5208-10532-0.html?forumID=1&amp;amp;threadID=64551&amp;amp;messageID=1201301"&gt;mikefarinha claims&lt;/a&gt; that "all of the big name OSS projects" exist to steal market share from Microsoft.  His list of FLOSS projects is Firefox, Open Office, Samba, WINE and Lindows.  For starters, Lindows is hardly a major FLOSS project, I would list it well behind Apache, any of the BSDs, Linux and OpenJDK, none of which made his list of 'big name projects'.&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Firefox comes from Mozilla. Mozilla comes from Netscape.  Apparently, Firefox exists to take market share away from Internet Explorer.  If you look at the User-Agent string from Internet Explorer, you will read &lt;blockquote&gt;Mozilla/4.0 (compatible; MSIE 7.0b; Windows NT 6.0)&lt;/blockquote&gt;Interesting, it looks like Internet Explorer is emulating Mozilla.  If you really want to look for who invented the web browser, you will discover &lt;a href="http://en.wikipedia.org/wiki/ViolaWWW"&gt;ViolaWWW&lt;/a&gt;.  Rather that running on Windows, ViolaWWW ran on Unix and X Window.   You may recognize X Window, since X.org is a 'big name' FOSS projects&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;OpenOffice.org is simply the open source version of Star Office.  StarOffice began with StarWriter, just like Microsoft Office began with Microsoft Word.  But StarWriter was originally a German word processor for Zilog Z80 and CP/M.  CP/M is an operating system that was originally developed by Gary Kindall at DEC.  CP/M is the ancestor of several DOS systems, including MS-DOS.   In Microprocessor Report (Vol 8, No. 13, October 3, 1994), John Warton concluded "The Origins of DOS" with:&lt;br /&gt;&lt;blockquote&gt;The strong impression I drew 13 years ago was that Microsoft programmers were untrained, undisciplined, and content merely to replicate other people’s ideas, and that they did not seem to appreciate the importance of deﬁning operating systems and user interfaces with an eye to the future. In the end it was this latter vision, I feel, that set Gary Kildall so far apart from his peers.&lt;/blockquote&gt;Not exactly a rousing defense of software innovation at Microsoft.  So, we find that StarWriter was developed for a OS that predates MS-DOS.  If I recall correctly,  the GUI version of MS Word was actually developed for the Macintosh.  So it is not clear to me how OpenOffice.org is an example of a Microsoft innovation that others copied, it can trace its code base back further than MS Word can.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Next, we have the case of Samba.  Samba implements the SMB protocol, which Barry Feigenbaum at IBM.  Microsoft implemented a heavily modified version of SMB.  Andrew Tidgell, and the Samba team, worked to create a version of SMB that worked with DEC Pathworks.  It is only later that they tried to understand Microsoft's undocumented modifications so their SMB Server could work with more of the computers in their employer's network.  It seems that trying to achieve file sharing between Windows and Unix is just an attempt to steal market share.  To my way of thinking, when Microsoft added undocumented changes to an otherwise open protocol, it was an attempt to achieve vendor lock-in and steal market share from the rest of the industry.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;That leaves only Wine, which is an emulator that allows *nix computers to run Windows applications.  Personally, I haven't had much luck with Wine, so I don't see how Microsoft has much to worry about from Wine.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In addition to mikefarinha, we have Rick S._z who states&lt;/div&gt;&lt;div&gt;&lt;blockquote&gt;But here's a TECHNICAL creation which changed the computing world, and was almost &lt;span class="Apple-style-span" style="font-weight: bold;"&gt;totally&lt;/span&gt; invented by Microsoft: truetype fonts. Before MS built Windows 3.1 around them, no one had thought to use the SAME fonts for your printers and your screens. Fantastic idea, and implemented beautifully.&lt;/blockquote&gt;The time is about right, but the source of the innovation is wrong.  TrueType Fonts were developed by Apple, as &lt;a href="http://www.microsoft.com/typography/truetypehistory.mspx"&gt;noted&lt;/a&gt; by Microsoft.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am not actually just an 'anything but Microsoft' Zealot, but it is just wrong to state that FOSS does nothing other than 'steal market share from Microsoft.'  For example, Microsoft did release NT, which does represent several significant innovations over DOS.  According to the &lt;a href="http://www.nytimes.com/1991/07/27/business/microsoft-widens-its-split-with-ibm-over-software.html"&gt;New York Times&lt;/a&gt;, the original name for NT was OS/2 3.0.  OS/2 was an operating system developed by IBM.  Microsoft did a great deal to improve the network stack.  Namely, they used the BSD Unix network stack, see the &lt;a href="https://forum.defcon.org/archive/index.php/t-6512.html"&gt;Defcon archives&lt;/a&gt; for evidence to support this claim.  There is nothing wrong with this, but you have to admit that the innovations for the network stack came from those open source Unix developers at Berkeley.  Just for giggles, open ftp.exe, its in your C:/Windows/System32 directory with Notepad.  You will see the BSD license.  Microsoft is not amazing because they invented everything, they are amazing because they integrated innovations from all of the world. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Remember Pablo Picasso's observation, "Bad artists copy.  Good artists steal."  If you want to be creative, you have to steal the good ideas.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-4318262755456518857?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/4318262755456518857/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/05/innovation-in-computer-industry.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4318262755456518857'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4318262755456518857'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/05/innovation-in-computer-industry.html' title='Innovation in the computer industry'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-3953398682497880424</id><published>2009-05-05T17:48:00.000-07:00</published><updated>2009-05-05T18:16:11.352-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data warehouse slowly changing dimension'/><title type='text'>Choosing SCT Type at Run Time</title><content type='html'>When a data warehouse is designed, the architect must choose a dimension type for each dimension in the warehouse.  The two must common types identified by Ralph Kimball are the Type 1 SCD, in which changes in dimensional attributes are overwritten.  In the Type 2 SCD, changes are not overwritten, but are recorded in multiple records for each object in the dimension table.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;After using Pentaho's PDI, it become clear that you can specify the dimension type at the attribute level as long as the underlying table is a Type 2 SCD.  Still these decisions need to be made when the dimension table's ETL is being designed.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What happens if you would rather delay the decision until run-time?  This flexibility can be provided with an auxiliary table for each dimension table.  The auxiliary table links each record in the dimension table with the most recent record for that object.  With that view defined, you can easily set up a view for a Type 2 dimension table that behaves like a Type 1 dimension.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am surprised that I don't find any references to this in standard data warehouse references or in online articles.  If anyone can point out a reference to this, I would be grateful,.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-3953398682497880424?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/3953398682497880424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/05/choosing-sct-type-at-run-time.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3953398682497880424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/3953398682497880424'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/05/choosing-sct-type-at-run-time.html' title='Choosing SCT Type at Run Time'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-6845634499227255494</id><published>2009-04-17T15:05:00.000-07:00</published><updated>2009-04-17T16:00:44.997-07:00</updated><title type='text'>Learning to program on OS/X</title><content type='html'>&lt;blockquote&gt;&lt;/blockquote&gt;Ages ago, I used HyperCard on a Mac SE.  Now, I'm trying to get back into programming on an iMac running Leopard.  My first observation, &lt;span class="Apple-style-span" style="font-style: italic;"&gt;Holy Cow! This is a fast workstation&lt;/span&gt;.  This absolutely blows away my workstation at work.  At work, I'm (still) running XP with Office 2003.  Outlook is a complete hog: between Outlook, Windows checking for updates, and virus scanning, just logging up takes a few minutes.  All day long, I am listening to my hard drive chatter as I work on as Pentaho BI Server site, so once I get Tomcat, Eclipse and a browser or two running.  I boot up, log in, and go get coffee.  &lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But on my Mac, Netbeans 6.5 comes up faster (under 15 seconds).  Learning Grails is a joy with a workstation that responds quickly.  I am quite happy to pay my 'Apple Tax',  I get OS/X, iLife and iWork.  I also get a faster JVM.   The biggest downer is that I can't run IE, so its hard to tell if my valid web pages will break on the world's dominant browser. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To get started, I followed &lt;a href="http://shifteleven.com/articles/2008/03/21/installing-postgresql-on-leopard-using-macports"&gt;these instructions&lt;/a&gt; at &lt;a href="http://shifteleven.com/"&gt;ShiftEleven&lt;/a&gt; to get up and running with Apple's developer tools, the MacPorts tools and PostgreSQL.  However, I didn't want to start PostgreSQL by default.  So rather than using &lt;a href="http://developer.apple.com/DOCUMENTATION/DARWIN/Reference/ManPages/man1/launchctl.1.html"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;lauchctl&lt;/span&gt;&lt;/a&gt;,  I'm just going to type &lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;&lt;blockquote&gt;sudo -u postgres/opt/local/lib/postgresql83/bin/postgres -D /opt/local/var/db/postgresql83/defaultdb&lt;/blockquote&gt;&lt;/span&gt; in&lt;span class="Apple-style-span" style="font-style: italic;"&gt; &lt;/span&gt;&lt;a href="http://iterm.sourceforge.net/"&gt;&lt;span class="Apple-style-span" style="font-style: italic;"&gt;iTerm&lt;/span&gt;&lt;/a&gt;.  &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-6845634499227255494?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/6845634499227255494/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/04/learning-to-program-on-osx.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/6845634499227255494'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/6845634499227255494'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/04/learning-to-program-on-osx.html' title='Learning to program on OS/X'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-6060438513045225935</id><published>2009-03-28T09:39:00.000-07:00</published><updated>2009-04-02T13:15:12.329-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Kimbal Type 3'/><category scheme='http://www.blogger.com/atom/ns#' term='dimension table'/><category scheme='http://www.blogger.com/atom/ns#' term='Pentaho'/><category scheme='http://www.blogger.com/atom/ns#' term='Kimball Type 1'/><category scheme='http://www.blogger.com/atom/ns#' term='Ralph Kimball'/><category scheme='http://www.blogger.com/atom/ns#' term='PostgreSQL'/><category scheme='http://www.blogger.com/atom/ns#' term='data warehouse'/><category scheme='http://www.blogger.com/atom/ns#' term='Kimball Type 2'/><title type='text'>Dimension tables in data warehouses: Type 2+1</title><content type='html'>&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;Introduction&lt;/span&gt;&lt;/div&gt;In condensed matter physics, a system is often characterized by the dimensionality of the crystal lattice.  A bulk crystal has a 3D lattice, while a surface has a 2D lattice.  Crystal growth occurs on the surface.  There are times where surface growth is described as being 2+1D.  I used to research this.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In data warehouses, data is stored using a data cube.  When a data cube is stored in a relational database, a star schema is build from fact tables and dimension tables.  In a fact table, the facts are stable and do not have any time dependence: facts are facts.  All of the time dependence is recorded in the dimension tables.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;The problem: with example&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To make this more concrete, consider a simple data cube for a swim conference.  The facts will be the race results.  The dimensions will be a swimmer dimension, an event dimension and a meet dimension.  Race results include the time recorded.  The results are linked to the dimension tables.  So, we can build reports on a given swimmer, even if they change teams.  Swimmers have a name, photo and birth date.  Swimmers also have a link to their current team. Teams have a name, coach, city and league.  (This example gives us a simple 'snowflake dimension').  Meets have a location, date, league and season.  Events include a stroke (backstroke, butterfly, breaststroke and freestyle) and distance.  For now, we will ignore team events, so the schema is quite simple.  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;This is for a Web 2.0 swim league, so we also have to create an iPhone web app to record all of the results during a meet.  We can even be cool and have a URL to a 'photo finish' image for each race, pictures for each swimmer, and a Google map showing the location of each meet.  After each meet, we can then run a Kettle job to move all of the data into our data warehouse running on Amazon EC2 at 10 cents an hour.&lt;/div&gt;&lt;div&gt;   &lt;/div&gt;&lt;div&gt;In the &lt;a href="http://www.amazon.com/Data-Warehouse-Toolkit-Techniques-Dimensional/dp/0471153370"&gt;Data Warehouse Toolkit&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Ralph_Kimball"&gt;Ralph Kimball&lt;/a&gt; has described three types of time dependence for dimension data&lt;/div&gt;&lt;div&gt;&lt;ol&gt;&lt;li&gt;Type 1 - the past doesn't matter.  When data in the dimension tables changes, we just throw away the old data and use the new data.  This is appropriate for correcting errors.  If we find that we should have spelled Vicky rather than Vickie, we just change the name in production database for our application.  The ETL process will then change the swimmer's name in the data warehouse.&lt;/li&gt;&lt;li&gt;Type 2 - slowly changing dimension.  In this case, a single entity in the production system gets mapped to multiple records in the dimension table.  At any moment in time, there is only one record that is valid for the entity.  When we change the description in the production system, the ETL job will create a new record in the dimension table.  If our iPhone toting parents take a new photo of Vicky every month, Vicky will will get a new record in the swimmer dimension table.  When we look at the results of a race where Vicky was swimming, we can see what she looked like at the time of the race.&lt;/li&gt;&lt;li&gt;Type 3 - keep a few versions.  In this design, we end up with multiple columns for a given attribute in the dimension table.  Usually, this is used so we can have a 'current' value and a 'last' value.   This is used for something like an company reorganization.  Vicky is a superstar and in the middle of the season she is forced to move to a really weak team to make the league more equal.  The parents are upset, so they track Vicky with the current team assignments, but they also track her beginning-of-season team.  This example may seem silly, but similar reorganizations happens all the time within companies.&lt;/li&gt;&lt;/ol&gt;&lt;div&gt;As the database architect, what are you to do?  The first thing to realize is that you have to decide on the time dependence for each field in the database.  In our case, we want a Swimmer dimension with name as a type 1 dimension attribute, a 'photo URL' as a type 2 dimension attribute and a type three dimension for the 'team' attribute.  To further complicate matters, we didn't even know that the team should be 'type 3' before the Reorganization Controversy.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In physics and chemistry, we talk about reversible and irreversible transformations.  In a computer system, erasing data is irreversible.  From this perspective, we see that only the type 2 time dependence does not erase data: type 2 is reversible in the sense that even after we change the data in production, we can still reproduce the old data exactly - if a report was run last year, we can get exactly the same results running the report this year.  A type 1 dimension throws data away immediately and a type 3 dimension will throw data away eventually (after two team changes in the example).  Since a data warehouse is supposed to warehouse data, I have an immediate preference for the type 2 time dependence.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;But as a practical matter, people often prefer the 'curent' results, not the results 'at that point in history'.  For example, lets say that we have a swim team dashboard that lets you click on a photo of each swimmer to see their stats.  Almost certainly, you want to have only one picture of Vicky that links to her entire history, not simply her history since that picture was take.  When designing the warehouses, I am constantly having to choose between 'current' and 'historical' dimension data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-size:x-large;"&gt;The New Solution: Type 2+1 dimension&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In order to explain this, I need to define the structure of the production database and the data warehouse for the swimmer.  In the production database, the swimmer table will have the following columns:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;GUID, an id for each swimmer that is unique for every swimmer in every league that is using my Swim 2.0 web application.  This is the primary key of the production table.&lt;/li&gt;&lt;li&gt;Name, a string with the swimmer's name.  There could be separate fields for first and last names, but this doesn't matter for this discussion&lt;/li&gt;&lt;li&gt;Birthdate, a date field.&lt;/li&gt;&lt;li&gt;Photo URL, preferably a URL class&lt;/li&gt;&lt;li&gt;Team GUID, a foreign key tying each swimmer to their current team&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;In our data warehouse, our swimmer dimension is also represented by a database table.  In a table designed for type 2 data, we would have the following columns:&lt;/div&gt;&lt;div&gt;&lt;ul&gt;&lt;li&gt;GUID (same as above, the G is for global, and the data warehouse is part of our world of data)&lt;/li&gt;&lt;li&gt;ID, a unique integer determined by the database engine.  This is the primary key of the swimmer dimension table.&lt;/li&gt;&lt;li&gt;version, an integer that starts at 1 and increments by 1 each time a new record is added for a given GUID.  There is a 1-1 mapping between (GUID, version) and ID &lt;/li&gt;&lt;li&gt;start date and end date. These two columns define when a given version is valid.&lt;/li&gt;&lt;li&gt;name, birthdate and photo URL fields, just like in production&lt;/li&gt;&lt;li&gt;Team ID.  Foreign keys reference primary keys, so rather than recording the Team GUID, we will record the Team ID.  This may be a bad idea, if you have arguments about when to use the GUID and when to use the ID when dimensions reference each other, I would be happy to hear from you.&lt;/li&gt;&lt;/ul&gt;&lt;div&gt;The rule for a data change is fairly simple.  In ETL, any changes in the production data are detected.  When a change is found, the current version of the entity (e.g., with the same GUID) is end dated and the current version is read and the end time is recorded.  A new record is inserted with the GUI, the attributes from production,  a new ID , the next version number, the start date is set to the end date of the previous record and the end date is usually sent to 'the end of time'.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In order to identify which version is current, &lt;a href="http://etl-tools.info/en/scd.html"&gt;the data warehouse architects at ETL-Tools&lt;/a&gt; recommend adding a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;current&lt;/span&gt; field,  a Boolean set to true for the current value and false for all others.  This field is could be determine by a simple rule, such as &lt;span class="Apple-style-span" style="font-style: italic;"&gt;now() between swimmer_dim.date_from and swimmer_dim.date_to&lt;/span&gt; or &lt;span class="Apple-style-span" style="font-style: italic;"&gt;swimmer_dim.version = ( select max(version) from swimmer_dim sd where sd.GUID = swimmer_dim.GUID)&lt;/span&gt;  (I use the default field names from Pentaho's Kettle, and the date functions from PostgreSQL, but this is easy to rewrite for other environments.)  As a practical matter, it is more efficient to add a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;current&lt;/span&gt; field so you can apply the rule once during ETL rather than each time the you run a query that needs the current values.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I argued that a 'proper' design should be reversible and that no data should be lost.  Doesn't adding a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;current&lt;/span&gt; field that I am willing to 'throw away' each time I run ETL violate my theoretical argument?  No.  The reason is that the information in the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;current&lt;/span&gt; field is redundant.  Since I can figure out which record would have been current at any time in the past, changing this field does not irreversibly lose data.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Rather than just recording a Boolean as to which record is current, I add a field called &lt;span class="Apple-style-span" style="font-style: italic;"&gt;current_id&lt;/span&gt; to my dimension tables.  If you want a Type 2 time dependence, you just ignore the &lt;span class="Apple-style-span" style="font-style: italic;"&gt;current_id&lt;/span&gt; since the rest of the table was set up to support Type 2.  So, if you want a dimension with Type 2 time dependence, you can write&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;create view swimmer_dim_type2 as &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;select GUID, ID, version, date_from, date_to&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;     , name, birth_date, photo_url, team_id&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;from swimmer_dim&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;If you want a Type 1 time dependence to return the current values for any historical id, you need to make a single self join&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;create view swimmer_dim_type1&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;select any.GUID, any.ID, curr.name&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;     , curr.birth_date, curr.photo_url, curr.team_id&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;from swimmer_dim any &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;join swimmer_dim curr on any.current_id = curr.id&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;This ability to act like a dimension of Type 1 or Type 2 is why I call this Type 2+1.  But, we know that 2+1=3, so is there a way to get the Type 3 time dependence as well?  Yes, but we will need to be able to choose a time when we want to choose the additional columns.  In the swimmer example, we want the current team and the team at the beginning of the season.  Let's assume that the season began on June 1, 2008.  We can create our Type 3 time dependence with:&lt;/div&gt;&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;create view swimmer_dim_type3 as&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;select any.GUID, any.ID&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;     , curr.name, curr.birth_date, curr.photo_url&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;     , any.team_id, june.team_id as starting_team_id&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;from swimmer_dim any&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;join swimmer_dim curr on any.current_id = curr.id&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;join swimmer_dim june on any.current_id = june.current_id&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;where cast('2009-06-01' as date) between june.date_from and june.date_to&lt;/span&gt;&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;So, Type 2+1 can emulate Type 1, Type 2 or Type 3 time dependence.  As I noted earlier, the time dependence should be determined at the field level, not the table level.  If we want to always use the current name, the photo that was current at the time of each race, and the team as of June 1, 2008, we can write a view to do exactly that without the need to alter the ETL or the table structures.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I have tested this idea on larger data sets, and each view is almost as fast a query of the underlying dimension table.  In most queries of a data warehouse, the query performance is dominated by the reads and aggregates of the data within the fact tables.  This technique should be valuable to nearly any data warehouse architect, so I would be pleased to hear from anyone who finds this useful.&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-6060438513045225935?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/6060438513045225935/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/03/dimension-tables-in-data-warehouses.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/6060438513045225935'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/6060438513045225935'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/03/dimension-tables-in-data-warehouses.html' title='Dimension tables in data warehouses: Type 2+1'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-4968855837169576445</id><published>2009-03-21T08:34:00.000-07:00</published><updated>2009-08-16T11:26:52.749-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Eliezer S. Yudkowsky'/><category scheme='http://www.blogger.com/atom/ns#' term='Bayes&apos; Theorem'/><category scheme='http://www.blogger.com/atom/ns#' term='David McKay'/><category scheme='http://www.blogger.com/atom/ns#' term='Taleb'/><category scheme='http://www.blogger.com/atom/ns#' term='Jeff Grynaviski'/><category scheme='http://www.blogger.com/atom/ns#' term='Black Swan'/><title type='text'>Bayes' Theorem and Taleb's Silent Evidence</title><content type='html'>In chapter Eight of the Black Swan, Taleb recounts Cicero's Story of the Drowned Worshippers:&lt;div&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div&gt;One Diagoras, a non believer in the gods, was shown painted tablets bearing the portraits of some worshippers who prayed, then survived, a subsequent shipwreck.  The implication was that praying protected you from drowning.  Diagoras asked, "Where were those who prayed, then drowned?"&lt;/div&gt;&lt;div&gt;The drowned workshippers, being dead, would have a lot of trouble advertising their experiences from the bottom of the sea.  This can fool the casual observer into believing in miracles.&lt;/div&gt;&lt;/blockquote&gt;&lt;div&gt;&lt;/div&gt;&lt;div&gt;Taleb calls this as the problem of silent evidence.  We a drawn to success, and we shun failure, so, as Taleb notes, nobody ever writes 'How I failed to Make a Million Dollars on Wall Street'.   &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Suppose that one of our Wall Street success stories claims that in order to succeed in Wall Street, you need to be a Harvard graduate; this author cites himself and and his college roommate who have both made a million dollars on Wall Street.  If you are in high school (or have a child in school), you need to choose a collage.   You are wanting to know if a Harvard education is worth its rather considerable cost.  If the author is right, then the decision is easy.  You will simply replay your student loans with the millions you make on Wall Street.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What information do you need to assess this claim?  We could begin by looking for particular cases.   Finding one black swan may prove that not all swans are white, likewise finding one millionaire from a state university will disprove a claim that a Harvard education is a &lt;span class="Apple-style-span" style="font-style: italic;"&gt;requirement&lt;/span&gt; for success on Wall Street.  Similarly,  finding an unsuccessful Wall Street trader from Harvard proves that a Harvard education is not sufficient for success on Wall Street.   Likewise, we can find examples of Harvard graduates that failed on Wall Street.  So being a Harvard Alumni is not a guarantee of success of Wall Street.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Life is not certain, so we need to make a gamble.  How can we to play the odds odds intelligently?  The sort of data that would be helpful would include the resumes of both successful and failed Wall Street investors.  As a practical matter, getting the list of unsuccessful investors would be something of a trick.  Taleb is right about silent evidence: we remember the winners and forget the losers.  The winners advertise and the losers go on to something else.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In the age of data mining and databases, it should be possible to build such as list. &lt;br /&gt;&lt;/div&gt;&lt;div&gt;If we can gather the data, what framework should we use to decide if going to Harvard would be a rational risk?    The correct framework to assess the validity of a claim is to use Bayes' Theorem from statistics.  If you haven't heard about Bayesian statistics, a good starting point is &lt;a href="http://yudkowsky.net/rational/bayes"&gt;An Intuitive Explanation of Bayes' Theorem&lt;/a&gt; by Eliezer S. Yudkowsky.  In fact, Yudkowsky's explanation is so good that there really isn't any point in me writing more on this subject.    There are also on-line course materials.  Currently, I'm trying to work through &lt;a href="http://home.uchicago.edu/~grynav/"&gt;Jeff Grynaviski&lt;/a&gt;'s (at the University of Chicago) has provided &lt;a href="http://home.uchicago.edu/~grynav/bayes/abs03.htm"&gt;his course materials&lt;/a&gt;.  In order to learn more, there is &lt;a href="http://www.inference.phy.cam.ac.uk/mackay/"&gt;David McKay&lt;/a&gt;'s &lt;a href="http://www.inference.phy.cam.ac.uk/mackay/itila/book.html"&gt;Information Theory, Inference and Learning Algorithms&lt;/a&gt;.   I especially like McKay's book because it is able to unite Bayesian methods with Claude Shanon's Information Theory and even to include elements of AI.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;If you still have some time left after reading about Bayesian methods, read Yudkowsky's article &lt;a href="http://www.singinst.org/upload/cognitive-biases.pdf"&gt;Cognitive biases potentially affecting judgement of global risk&lt;/a&gt;.  His assessment seems to be in general agreement with Taleb.  Since I live next to Cedar Rapids, which has just had a major flood, Yudkowsky's observation about flood damage was particularly revealing:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;a href="http://www.amazon.com/Environment-As-Hazard-Second/dp/0898621593/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1238256400&amp;amp;sr=1-1"&gt;Burton et. al. (1978) report&lt;/a&gt; that when dams and levees are built, they reduce the frequency of floods, and thus apparently create a false sense of security, leading to reduced precautions.  While building dams decreases the &lt;i&gt;frequency&lt;/i&gt; of floods, damage &lt;i&gt;per flood&lt;/i&gt; is so much greater afterward that the average yearly damage &lt;i&gt;increases&lt;/i&gt;.&lt;/blockquote&gt;&lt;br /&gt;Wow, this is an extraordinary claim.  If true, the much of the work done to protect people in the Mississippi/Missouri River basins is not just useless but is actually counterproductive.  I will remain skeptical on this claim, but it does seem worthy of investigation before Cedar Rapids, Linn County, the State of Iowa and Federal agencies sink more money into flood control on the Cedar River.  We need to find a more rational way to understand and manage risk.  If we can improve that, we will have learned an important lesson from the catastrophic failures of 9/11, the Indian Ocean Tsunami of 2004,  the flooding of New Orleans following Hurricane Katrina, and the current financial collapse.   We need Taleb's empiricism.  When we have enough data to analyze, we should be using Bayesian methods for that analysis.&lt;br /&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-4968855837169576445?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/4968855837169576445/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/03/bayes-theorem-and-talebs-silent.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4968855837169576445'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4968855837169576445'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/03/bayes-theorem-and-talebs-silent.html' title='Bayes&apos; Theorem and Taleb&apos;s Silent Evidence'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-3967966362003449228.post-4795755914148676651</id><published>2009-03-08T07:44:00.001-07:00</published><updated>2009-03-08T09:32:07.203-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='whoami'/><category scheme='http://www.blogger.com/atom/ns#' term='Marion'/><category scheme='http://www.blogger.com/atom/ns#' term='Iowa'/><category scheme='http://www.blogger.com/atom/ns#' term='Swamp Fox'/><title type='text'>Why Swamp Fox Analyst?</title><content type='html'>First, I live in Marion, Iowa, home of the &lt;a href="http://cvra.net/swampfox"&gt;Swamp Fox Festival&lt;/a&gt;.  I was was raised largely in Marion County, Iowa.  Both are named after Francis Marion. Of course, there are &lt;a href="http://en.wikipedia.org/wiki/List_of_places_named_for_Francis_Marion"&gt;hundreds of places in the US&lt;/a&gt; named after Francis Marion.  I am no historian, but even a quick read of his &lt;a href="http://en.wikipedia.org/"&gt;Wikipedia&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/Francis_Marion"&gt;article&lt;/a&gt; or the Smithsonian's &lt;a href="http://www.smithsonianmag.com/history-archaeology/biography/fox.html"&gt;recent article&lt;/a&gt; reveal a fascinating character.  He was a small child, being something of the family runt.  He was a good student and fluent in French.  At age 15, he survived a shipwreck when a whale rammed the schooner he was sailing.  At 25, he became a military officer in the French-Indian Wars.  The following quote&lt;br /&gt;&lt;blockquote&gt;The next morning we proceeded by order of Colonel James Grant, to burn down the Indians' cabins. Some of our men seemed to enjoy this cruel work, laughing very heartily at the curling flames, as they mounted loud crackling over the tops of the huts. But to me it appeared a shocking sight. Poor creatures! thought I, we surely need not grudge you such miserable habitations. But, when we came, according to orders, to cut down the fields of corn, I could scarcely refrain from tears. For who could see the stalks that stood so stately with broad green leaves and gaily tasseled shocks, filled with sweet milky fluid and flour, the staff of life; who, I say, without grief, could see these sacred plants sinking under our swords with all their precious load, to wither and rot untasted in their mourning fields.&lt;/blockquote&gt;suggests to me that he was a sensitive and compassionate man, but still a man that did his duty.  He is most famous for his leadership in the American Revolutionary War.  Following the &lt;a href="http://en.wikipedia.org/wiki/Waxhaw_massacre"&gt;Waxhaw Massacre&lt;/a&gt; , his band of about fifty irregulars was the only force opposing the British in South Carolina.  He earned his nickname, The Swamp Fox, by outfoxing Col. &lt;a linkindex="77" href="http://en.wikipedia.org/wiki/Banastre_Tarleton" title="Banastre Tarleton"&gt;Banastre Tarleton&lt;/a&gt; and his British forces.  His tactics are predecessors of modern guerrilla warfare.  In short, he was able to accomplish a great deal with very little.  In short, he used intelligence to succeed.  I cannot make claims that I am following in his footsteps (I failed my military physical for acne scars on my chest and back), I can certainly take inspiration from his success.&lt;br /&gt;&lt;br /&gt;There is also a cautionary note that I associate with Francis Marion.  While we Americans, and even Mel Gibson,  regard Marion as hero, he was clearly viewed as a terrorist by the British.  The historian Christopher Hibbert described him as a racist and rapist for his treatment of the Cherokee.  There is evidence that both views are correct.  One man's terrorist &lt;span style="font-style: italic;"&gt;is &lt;/span&gt;another man's freedom fighter.&lt;br /&gt;&lt;br /&gt;Francis Marion was also alive during the Age of Enlightenment.  His  lifetime (1732-1795) overlaps the lives of the skeptic David Hume (1711-1776), the Reverend Thomas Bayes (1702-1761), and the French aristocrat Pierre-Simon, marquis de Laplace (1749-1827).   As &lt;a href="http://www.fooledbyrandomness.com/"&gt;Nassim Nicholas Taleb&lt;/a&gt; notes in &lt;a href="http://en.wikipedia.org/wiki/The_Black_Swan_%28Taleb_book%29"&gt;The Black Swan&lt;/a&gt;, Hume was an influential empiricist for the English-speaking world.  For all of the reasons Taleb outlines, we need empiricism and some of the intellectual humility of a real skeptic, to counter the hubris of modern economists.&lt;br /&gt;&lt;br /&gt;Taleb speaks a great deal about The Problem of Silent Evidence.  In a nutshell, if we try to understand the unusual, we try to look for characteristics that we feel were a cause of the event.  For example, we have all been taught that World War I was caused by 'entangling alliances' between the major powers and the 'powderkeg' in the Balkans.  But, identifying characteristics that were true before WWI is not the same as identifying causes.  To have a useful knowledge, we need to be able to predict, not create an after-the-fact narrative.  There were many times in history where there were alliances and many places where angry young men plotted to be revolutionaries.  Does the presence of these conditions have any predictive value?  That is what we need to know if we want to plan.&lt;br /&gt;&lt;br /&gt;It seems to me that some of Taleb's criticism of classical statistical analysis can be addressed by using Bayesian methods.  This is the tie to the Reverend Bayes and Laplace, they founded what we now called Bayesian statistics.  Over the last twenty years, Bayesian methods have been rapidly evolving.   In particular, Bayes theorem provides a mathematical framework to discuss Taleb's Problem of Silent Evidence.  Of course, a framework is not a 'solution' and this only addresses one of Taleb's issues.  More to come ...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/3967966362003449228-4795755914148676651?l=swampfoxanalyst.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://swampfoxanalyst.blogspot.com/feeds/4795755914148676651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/03/why-swamp-fox-analyst.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4795755914148676651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/3967966362003449228/posts/default/4795755914148676651'/><link rel='alternate' type='text/html' href='http://swampfoxanalyst.blogspot.com/2009/03/why-swamp-fox-analyst.html' title='Why Swamp Fox Analyst?'/><author><name>Bob Folkerts</name><uri>http://www.blogger.com/profile/07723506329986997236</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='33' height='21' src='http://2.bp.blogspot.com/_H9cmDV9xmSo/ScUZukeYaWI/AAAAAAAACAo/DkuFK80_p4k/S220/Bob3.jpg'/></author><thr:total>0</thr:total></entry></feed>
