<?xml version="1.0" encoding="utf-8" ?>
<?xml-stylesheet href="/templates/default/atom.css" type="text/css" ?>

<feed 
   xmlns="http://www.w3.org/2005/Atom"
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/">
    <link href="http://blog.lostlake.org/index.php?/feeds/atom10.xml" rel="self" title="David Pollak's Blog" type="application/atom+xml" />
    <link href="http://blog.lostlake.org/"                        rel="alternate"    title="David Pollak's Blog" type="text/html" />
    <link href="http://blog.lostlake.org/rss.php?version=2.0"     rel="alternate"    title="David Pollak's Blog" type="application/rss+xml" />
    <title type="html">David Pollak's Blog</title>
    <subtitle type="html">Information, experiences, rants...</subtitle>
    <icon>http://blog.lostlake.org/templates/default/img/s9y_banner_small.png</icon>
    <id>http://blog.lostlake.org/</id>
    <updated>2010-03-06T06:06:56Z</updated>
    <generator uri="http://www.s9y.org/" version="1.4">Serendipity 1.4 - http://www.s9y.org/</generator>
    <dc:language>en</dc:language>

    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/99-Burn-your-TransLink-card.html" rel="alternate" title="Burn your TransLink card" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2010-03-06T06:06:56Z</published>
        <updated>2010-03-06T06:06:56Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=99</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=99</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/2-Personal" label="Personal" term="Personal" />
    
        <id>http://blog.lostlake.org/index.php?/archives/99-guid.html</id>
        <title type="html">Burn your TransLink card</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>I am outraged at the SF Muni and their adoption of the <a
href="https://www.translink.org/TranslinkWeb/index.do">TransLink</a>
card.&#160; Soon, there are certain bus lines that will only accept the
TransLink card during rush hour... you won't be able to ride the bus
except with one of these evil devices.<br />
</p>
<p>So, what's my outrage?<br />
</p> <p>I spent most of today trying to obtain a TrankLink card for my
kids.&#160; I read on the TransLink site that the <a
href="https://www.translink.org/TranslinkWeb/seniors.do">youth cards</a>
had to be obtained in person rather than at the normal retail
outlets.&#160;
So, I took my kids downtown figuring I could buy a card at a Muni
station, but no dice.&#160; Most of the folks in the Muni stations had
no clue.&#160; Finally, somebody pointed me to Golden Gate Transit in
the Ferry Building, so off we went to the Ferry Building.<br />
</p>
<p>We find the right booth to buy the pass.&#160; Now, my kids are in
kindergarten.&#160; There's no question that they are youths and are
elegible for youth discounts.&#160; In fact, most Muni drivers say,
"These kids look too young to pay."&#160; My response is, "Muni rules
say that 5 year olds pay and we follow rules in our family."<br />
</p>
<p>So, I ask for 2 youth passes.&#160; The woman behind the counter
says, "give me their birth certificates and we'll give you the youth
passes."&#160; I say, "that's a joke, right?&#160; Look at them, do
they look anywhere near 16 or 18 or whatever the cutoff age is?"&#160;
She responds, "Our policy is that we only issue youth cards with a
birth certificate."<br />
</p>
<p>We've had to show the kids' birth certificates for their social
security cards and for entrance to school.&#160; We did not have to
produce birth certificates for library cards, health insurance, so I'm
wondering what is going on here.&#160; I ask for a supervisor.<br />
</p>
<p>I talk to the supervisor and he tells me, "It is our policy that you
need a birth certificate to obtain a youth TransLink card."&#160; Me:
"Why?&#160; Do these kids look like they're too old for the
card?"&#160; Him: "We bond the birth certificate to the card to avoid
fraud."&#160; Me: "You what?"&#160; Him: "We make sure that the
discount card is associated with the person."&#160; Me: "So, you're
telling me that in order to get a discount, you guys are going to track
the movements of my kids throughout the TransLink system?&#160; How is
this supposed to reduce fraud?"&#160; Him: "That's our policy,
sir."&#160; Me: "Your policy is Orwellian and there's no way I'm
letting you associate my kids' public transportation usage with their
birth certificate.&#160; Instead of trying to buy cards for the kids,
I'm going to burn mine."<br />
</p>
<p>So, we walk away.&#160; The supervisor comes running after me.&#160;
"Sir, your kids look young enough that they don't need to pay a fair
anyway."&#160; Me: "First, they have to pay on the SF Muni and we
follow the rules so we pay.&#160; Second, giving me a 'free-be' today
don't mitigate your Big Brother policy of tracking my kids
where-abouts."&#160; Him: "I'm just trying to be helpful."&#160; Me:
"If you want to be helpful, go back to your boss and explain to him
that this is the United States and we move freely in this country."<br />
</p>
<p>My kids asked me why I was cranky.&#160; I said, "Because the bad
people want to know where you go."&#160; Kids: "We're not going
anywhere bad, so why don't we want people to know where we've
gone?"&#160; Me: "It is our right as Americans to come and go as we
please.&#160; It's our right to be private.&#160; But more importantly,
historically, once the government starts tracking their citizens,
especially their children, they will find a way to use the information
against you.&#160; It's not that we have anything to hide, it's that
any time people want to always know, they are up to no good... they are
bad people."<br />
</p>
<p>So, we walk through the Ferry Building and I see a guy with an <a
href="http://www.eff.org/">EFF</a> hat.&#160;
Now, this is San Francisco, so it's not unexpected to see some guy
sporting an EFF hat.&#160; I go up to him and say, "Are you a member of
the EFF?&#160; I was one of the first donors to the EFF so don't get
freaked."&#160; He says, "Yes."&#160; I say, "The TransLink folks want
my kids' birth certificates in order to get a youth TransLink card and
they bond the birth certificate to the card so they track the kid's
movement throughout their system."&#160; His jaw dropped to the
ground.&#160; We shared a brief moment of liberal outrage and my kids
and I went on our way.<br />
</p>
<p>When I got home, I checked the TransLink site.&#160; There is no
mention of requiring a birth certificate to obtain a youth pass.&#160;
I called the TransLink customer service line and they did verify that a
birth certificate is required.<br />
</p>
<p>First, TransLink is hiding the fact that a birth certificate is
required.&#160; It's not on their public web site although it is
mentioned in a press release.&#160; Why are they hiding this
information?&#160; Do they think that if they don't publish it on their
web site that somehow it'll make it okay?<br />
</p>
<p>Second, TransLink is managed by the <a
href="http://www.mtc.ca.gov/services/translink/">Metropolitan
Transportation Commission</a>, but this is not mentioned anywhere on
the TransLink web site and is only mentioned once in the TransLink
cardholder "license agreement".&#160; Why is the MTC hiding?<br />
</p>
<p>Third, if the MTC is a governmental body, where was the public
hearing and the public comment request relating to requiring a birth
certificate and bonding that information to youth passes?<br />
</p>
<p>Forth, what great problem are they looking to solve by associating a
card with a person?&#160; What kind of failures is the current youth
(and elderly) pass mechanism (a different colored pass) justify bonding
my child's birth certificate to their transit card and track my
children's comings and goings?<br />
</p>
<p>So, I am outraged.&#160; I will burn my TransLink card and until
this Orwellian, KGB-esq policy of requiring a birth certificate to get
a youth TransLink, I will not in any way participate in the TransLink
system.&#160; I urge you to do the same.<br />
<br />
</p> 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/98-Back-in-the-Goat-Saddle.html" rel="alternate" title="Back in the (Goat) Saddle" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2010-02-14T09:11:31Z</published>
        <updated>2010-02-14T09:11:31Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=98</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=98</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/98-guid.html</id>
        <title type="html">Back in the (Goat) Saddle</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Back in June, I started chatting about <a
href="http://blog.lostlake.org/index.php?/archives/94-Lift,-Goat-Rodeo-and-Such.html">Goat
Rodeo</a>: a highly scalable mechanism for building distributed
applications.&#160; My first set of concepts for Goat Rodeo were wrong,
most notably trying to do distributed Software Transactional
Memory.&#160; I've spent the last bunch of months revising the concept
and code for Goat Rodeo... and today, I'm excitied to announce the <a
href="http://liftweb.assembla.com/spaces/goat_rodeo/stream">0.1 alpha
code for Goat Rodeo</a>.<br />
</p> <p>First, some background on the problem:</p>
<p>Far and away the most common way of persisting and calculating state
is in a relational database (RDBMS).&#160; RDBMSs are awesome
creatures.&#160; They sit on top of some excellent and well understood
mathematics: set theory.&#160; They have well known and well understood
concurrency mechanisms: transactions.&#160; They have been designed,
built, tested, and optimized over the last generation. RDBMSs offer a
simple set of commands (SELECT, DELETE, INSERT, UPDATE) as well as a
generally human understandable set of semantics: people understand that
RDBMSs are a sets of things and there are simple ways to ask about
these sets.&#160; RDBMSs have evolved along with ERP systems and have
evolved to meet the needs of these systems.</p>
<p>However, there are well known things that RDBMSs don't do well that
include tree structures (yeah, Oracle and others have extensions for
tree walks, but nothing is part of the SQL spec and the performance of
these extensions is not always the same as other models: a tree-walk in
an RDBMS costs O(log n) for each node where a tree walk in an OO system
costs O(1)).&#160; Social networks/social graphs are another place
where RDBMSs do not excel.<br />
</p>
<p>Let's dive down into this.<br />
</p>
<p>A naive implementation of a social messaging site runs something
like these tables:<br style="font-family: monospace;" />
</p>
<ul>
<li><span style="font-family: monospace;">Users(id, name, password)</span></li>
<li><span style="font-family: monospace;">Friends(owner, friend)</span></li>
<li><span style="font-family: monospace;">Messages(id, poster,
content, date)</span></li>
</ul>
<p />
<p>So, if we wanted to calculate the timeline for a given user at a
given instant, the query would look like:<br />
<br style="font-family: monospace;" />
<span style="font-family: monospace;">SELECT messages.* FROM messages,
friends WHERE friends.owner = current_user</span> <span
style="font-family: monospace;">AND messages.poster = friends.friend
ORDER BY messages.date DESC LIMIT 20</span><br />
<br />
</p>
<p>Assuming we've got indexes on friends.owner, messages.poster and
messages.date, the query still results in O(n log n) where n is the
aggregate number of messages posted.&#160; This is non-trivial and if
you follow someone who has posted 20,000 messages, then log n cost
becomes non-trivial.<br />
</p>
<p>Basically, each time a client asks for the latest timeline, you've
got an O(n log n) operation to determine state.&#160; This doesn't
scale.<br />
</p>
<p>The first obvious response to the issue is caching (capturing the
state beyond the duration of a short-lived session).&#160; I'm going to
skip caching for a moment and do a more sophisticated implementation of
timelines so wecan get better performance.<br />
</p>
<p>Let's create a mailbox table.&#160; Each time someone publishes a
message, a reference to that message will be put in a Mailbox(owner,
message, date) table and we'll create an index on the table: (owner,
date DESC)<br />
</p>
<p>This changes the query to:<br />
<br style="font-family: monospace;" />
<span style="font-family: monospace;">SELECT messages.* FROM messages,
mailbox WHERE mailbox.owner = current_user</span> <span
style="font-family: monospace;">AND messages.id = mailbox.message
ORDER BY mailbox.date DESC LIMIT 20</span><br />
<br />
</p>
<p>Depending on your RDBMS, you will wind up with an O(log n)
operation.&#160; You find the newest mailbox entry by user (O(log n))
and do an index walk until you've found 20 entries (I'm putting aside
the fact that looking up the 20 messages is an O(n log n) operation
because 20 is a small number and the messages will likely be in the
database's cache... this operation is going to be fast.)<br />
</p>
<p>I'm going to sidetrack for a moment.&#160; I had the pleasure of
talking over a few beers at a baseball game with one of the senior
engineers at Facebook. We were talking about Facebook's scaling
success.&#160; His comment was that it was successful but very
expensive.&#160; If there were more than 3% cache misses from MySQL
queries, the system would back up.&#160; If they got more than 2% cache
misses from the memcached stuff in front of their MySQL servers the
system would back up.&#160; So, basically Facebook has 195% of their
data in RAM.<br />
</p>
<p>The net is that O(log n) is only going to work if you've got your
entire index in the cache of your RDBMS.&#160; Even a dozen disk reads
is going to turn a 10ms query into a 250ms query and if you've got
1,000 users asking for a status update, you'll wind up with disk
thrashing and ultimately you will not be able to satisfy all of those
requests.<br />
</p>
<p>Let's make our discussion more concrete.&#160; I'm assuming that an
social networking instance will support 25,000 users.&#160; On average,
a user will follow 100 people (100x fan-out of messages).&#160; Users
will post one message every 30 minutes (48 messages a day).&#160; The
day lasts 10 hours (this is a reasonable approximation for peakiness...
basically, you're compressing 48 message sends in to a 10 hour
period).&#160; There are 300 days in a year.&#160; These numbers are
averages and there will be some folks who are above average in terms of
fan out (the CEO will have a 25,000x fan out) and some folks are above
average in number of messages per day.<br />
</p>
<p>So, that means that each year, there will be 36,000M (36B) mailbox
entries. If each entry costs us 16 bytes of RAM for index purposes,
that means we're at 576B bytes of index.&#160; There's no way that
amount of index will fit in RAM.&#160; So, what happens if the average
messages/day drops to 1, you're still looking at 10GB of index. &#160;
Alternatively, you could purge messages after 3 weeks or limit
timelines to a certain number of messages.&#160; That's not
unreasonable, but it's also adding a constraint to the system to deal
with limitations of the RDBMS.&#160; There are other alternatives.<br />
</p>
<p>Let me talk memcached for a minute.&#160; In my opinion, memcached
means that you have a failed design.&#160; Memcached means abandoning
all the awesome things that you get with an RDBMS: a mathematical
model, a concurrency/transactional model, durability guarantees, etc.<br />
</p>
<p>But, we could move our state from the calculate-on-demand model of
the RDBMS to the a calculate once and cache model using
memcached.&#160; This means that you only take the nasty hits if the
cache is not valid.&#160; Putting aside the cost of cache invalidation
(I haven't covered the costs of updates in this discussion because
there's no need to go there... the implementation failures can be
demonstrated with just reads), if you have a simple cache invalidation
scheme, most of the cache entries will not survive for 15 minutes (I
can go through the math, but I'm going to leave this one to the
reader).&#160; You risk cache stampedes (more than 1 process rebuilding
the cache entry).&#160; Basically, the naive memcached implementation
buys you a little bit of head room over the naive (non-mailbox)
approach.&#160; In order to get more than 5x or so improvement
(something that will serve a few thousand rather than a few hundred
users), you need to manipulate the cache entries inserting/deleting
individual messages.<br />
</p>
<p>The above paragraph in fact leads us in the direction of a better
answer.<br />
</p>
<p>But first, let me state that I have proven that an RDBMS cannot be
the sole locus of state for a social messaging site that services more
than a few hundred users.&#160; Period.&#160; We must move state
somewhere else and manage the cached state manually rather than with
queries and indexes. Let's walk through a design that gives us a
concurrency model as well as the performance we want.<br />
</p>
<p>Imagine a model where you interact with a User with a limited set of
(asynchronous) messages:<br />
</p>
<ul>
<li><span style="font-family: monospace;">add/remove friend</span></li>
<li><span style="font-family: monospace;">add message to timeline</span></li>
<li><span style="font-family: monospace;">post message (the user has
created a message and it needs to be processed)</span></li>
<li><span style="font-family: monospace;">get current timeline (with
offsets and number of entries)</span></li>
</ul>
<p />
<p>These are the basic messages needed to implement a social messaging
site. If we guaranty that a User will only process 1 message at a time,
we have a concurrency model.&#160; It's simple and simple is
good.&#160; We have not defined how/where Users store there state (it
could be on a filesystem, in an RDBMS, in a NoSQL store, who
knows).&#160; But we can say that adding a message is an O(1) operation
(prepending to the head of a singly linked list).&#160; Each User can
have a caching policy (and that caching policy could be dynamic based
on the access characteristics for the User).&#160; The sender of the
message doesn't block on the processing of the message (although the
get current timeline message will have an asynchronous response that
the sender will likely block on).<br />
</p>
<p>We have changed our abstraction from one where all data (tables and
indexes) are created equal to one where certain data structures are
more prominent (User and Message) than others (mailbox, friends).<br />
</p>
<p>We have lost something: transactions.&#160; In this model, if I add
Dick as a friend, I am not guaranteed that I will receive Dick's next
update... it may take time for the messages to propagate to Dick's User
and his Message may be sent before the "add friend" message gets to
him.&#160; In the case of a financial transaction, this would be
fatal.&#160; In the case of social networking, this is a perfectly
reasonable trade-off.<br />
</p>
<p>One of the ways that RDBMSs get performance (and the way products
like Oracle distinguish themselves from the likes of MySQL) is the
ability to cache optimized query plans, cache the right data, and
invalidate the right caches at the right time.&#160; The same
requirements are going to come up in a social networked application.<br />
</p>
<p>So far, I've described an Actor based system... and there are a
plethora of Actor-based systems around.&#160; Erlang is the the best
system for distributed Actors.&#160; <a href="http://akkasource.org">Akka</a>
is the best Scala Actor implementation around.&#160; But Actors provide
a single service: ordered messaging.&#160; The additional services that
are needed to create scalable social systems are:<br />
</p>
<ul>
<li>A unified transaction model such that different components in the
system have a single mechanism to engage in transactions;</li>
<li>A simple interface to extract data from the system without being
and Actor in the system;</li>
<li>A scalable storage model that provides transactions (integrated
with the system's transaction mechanism) and a richer data model than
key-value pairs.</li>
</ul>
<p>Additionally, the system should behave the same way when everything
is running in a single JVM or distributed across the network.&#160; The
application-level code should not know or be different if the resources
are local or remote.&#160; Code should go from the developer's laptop
to the production system unchanged.&#160; Additionally, the business
logic in the code should be testable without having to set up a large
number of different software systems.</p>
<p>Goat Rodeo acheives all the above goals... plus one additional goal:
the single machine implementation is open source under an Apache 2.0
license.&#160; The scalable multi-machine version is closed
source.&#160; What this means if if you've got a site that's going to
run on a single system, you can build it with Goat Rodeo.&#160; If you
become the next Twitter of FourSquare, you can rest assured that your
system will scale just by adding money.&#160; The benefit to the open
source community is that development is based on money rather than the
goodness of someone's heart.&#160; Anyway, back to the bits and bytes.<br />
</p>
<p>Goat Rodeo insures, at the compiler level, that all messages can be
JSON serialized and distributed across the network.&#160; Anything in
Goat Rodeo that could be serialized must be a subclass of the QBase
trait.&#160; Goat Rodeo includes a compiler plugin that insures that
all classes that extend QBase can be serialized (they contain only
immutable List, Map, String, primative types or things that subclass
from QBase.)&#160; This means that all messages are immutable.<br />
</p>
<p>The container of business logic in Goat Rodeo is a Worker.&#160; A
Worker is like an Actor, but there are enough syntactic and semantic
differences, that I choice a new name.&#160; Actors are typed based on
the WorkerId:<br />
</p>
<p><span style="font-family: monospace;">trait WorkerId extends QBase {</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; type MyType &lt;: WorkerId</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; type MsgType &lt;: QBase</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; type IdType</span><br
style="font-family: monospace;" />
<br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; def myType:
Manifest[MyType]</span><br style="font-family: monospace;" />
<br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; def id: IdType</span><br
style="font-family: monospace;" />
<br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; def uniqueNameForFile:
String</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">}</span><br />
</p>
<p>Here's an example of a SimpleId:</p>
<p><span style="font-family: monospace;">final case class SimpleId(id:
Long) extends WorkerId {</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; type MyType = SimpleId</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; type MsgType = SimpleMsg</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; type IdType = Long</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; def myType =
manifest[SimpleId]</span><br style="font-family: monospace;" />
<br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; def uniqueNameForFile:
String = "simple_"+id</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">}</span><br />
</p>
<p></p>
<p>A Worker is defined:</p>
<p><span style="font-family: monospace;">/**</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;* The interface to a
Worker.&#160; A Worker receives messages, performs computations and
communicates with</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;* other workers</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;*/</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">trait Worker[IdType &lt;:
WorkerId] extends SimpleActor[IdType#MsgType] {</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; /**</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160; * The unique ID of
the Work</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160; */</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; def id: IdType</span><br
style="font-family: monospace;" />
<br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; /**</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160; * Send a message to
the worker</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160; */</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; def !(msg: MsgType): Unit</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">}</span><br />
</p>
<p>You can only send an asynchronous message to a Worker.&#160; Here's
an example of an asynchronous message:</p>
<p><span style="font-family: monospace;">case class Moo(num: Int)
extends SimpleMsg</span><br />
</p>
<p>You can obtain a Worker[WorkerId] from the WorkerMgr:<br />
</p>
<p><span style="font-family: monospace;">WorkerMgr.find(SimpleId(4)):
Box[Worker[SimpleId]]</span><br />
</p>
And here's the code for a Worker[SimpleId]:
<p><span style="font-family: monospace;">class SimpleWorker(id:
SimpleId, calcFunc: SimpleId =&gt; ConnectionManager) extends</span> <span
style="font-family: monospace;">WorkerImpl[SimpleId, SimpleMsg](id,
calcFunc) {</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; var mooRes = 0</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; private var balance: Long
= id.id</span><br style="font-family: monospace;" />
<br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; def doMoo(in: Moo): Unit =
{</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160; mooRes = in.num</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; }</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">}</span><br />
</p>
<p>The code does not look like the typical Actor's react/receive
loop.&#160; While it's possible to write that kind of dispatch for
Workers, I opted to use reflection to build the dispatch table.&#160;
Public methods that start with "do", "perform" or "handle" and take a
subclass of IdType#MsgType are placed in the Worker's dispatch table.&#160;
So, you can send a message to a Worker (either from within another
worker or from the outside world):<br />
</p>
<p><span style="font-family: monospace;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;
for {</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;
worker &lt;- WorkerMgr.find(SimpleId(17))</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160;&#160;&#160;&#160;&#160;
} </span><span style="font-family: monospace;">worker !
StartTrans(SimpleId(18))</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160; </span><br />
</p>
<p>So far, nothing revolutionary.&#160; But, you may be asking, how
does the outside world ask a question of a Worker?&#160; All messages
that lead to a response must mix in:<br />
</p>
<p><span style="font-family: monospace;">/**</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;* A message that generates
a response with a particular type</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;*/</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">trait MsgWithResponse[T &lt;:
QBase] extends QBase</span><br />
</p>
<p>So, all messages that lead to a response are strongly typed.&#160;
So, we might have the following message:<br />
</p>
<p><span style="font-family: monospace;">case class GetBalance()
extends SimpleMsg with MsgWithResponse[QLong]</span><br />
</p>
<p>And from the outside world, we can send it to a worker:<br />
</p>
<p><span style="font-family: monospace;">&#160;OutsideOfWorker on
myWorker complete {resp: Box[QLong] =&gt; resp.foreach(q =&gt;
println("The balance is "+q))} ask GetBalance()</span><br />
</p>
<p>The method on the Worker looks like:<br />
</p>
<p><span style="font-family: monospace;">&#160; def doGetBalance(in:
GetBalance): QLong = {</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160; balance</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; }</span><br />
</p>
<p>Alternatively:<br />
</p>
<p><span style="font-family: monospace;">&#160; def doGetBalance(in:
GetBalance, answer: Box[QLong] =&gt; Unit): Unit = {</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160;
answer(Full(QLong(balance)))</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160; }</span><br />
</p>
<p>So, we can send messages to Workers and get answers to questions
from Workers from outside the Worker infrastructure.&#160; We can also
ask questions from within the Worker context:</p>
<span style="font-family: monospace;">on myWorker complete {resp:
Box[QLong] =&gt; resp.foreach(q =&gt; println("The balance is "+q))}
ask GetBalance()</span><br />
<br />
<p>The only difference between the two is that from within the context
of a Worker, you ask questions via the Worker.&#160; The answer
function is executed within the context of the Worker's mailbox and
within the context of the Worker.<br />
</p>
<p>Workers can also engage in transactions:<br />
</p>
<p><span style="font-family: monospace;">for {</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160;&#160;&#160; t
&lt;- msg.xacts</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160;&#160;&#160;
fromWorker &lt;- WorkerMgr.find(t.from)</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160; } transaction
avec fromWorker send SetupTransfer(t)</span><br />
</p>
<p>To send a message transactionally to another Worker (of the same
type or of a different type), you designate that the message is
transactional, the transaction is with (avec) another worker and the
message to send.&#160; There are a number of transaction modifiers:<br />
</p>
<p><span style="font-family: monospace;">postCommit {</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160;&#160;&#160;
f(Full(QLong(balance)))</span><br style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160; }</span><br />
</p>
<p>This says that after the commit operation, apply the function f...
send the balance to the asker of the question.&#160; We can also define
the action to take in case of a rollback:<br />
</p>
<p><span style="font-family: monospace;">rollback {(a,b) =&gt;</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160;&#160;&#160;
TestRecord.findAll().foreach{r =&gt; balance = r.balance}</span><br
style="font-family: monospace;" />
<span style="font-family: monospace;">&#160;&#160;&#160;&#160;&#160;
f(ParamFailure("rollback", Empty, Empty, (a, b)))}</span><br />
</p>
<p>Read the balance from the database and reply to the balance inquiry
with a Failure.<br />
</p>
<p>Particular messages can be marked as non-re-entrant... they can only
be serviced once per transaction:<br />
<br />
</p>
<p><span style="font-family: monospace;">transaction notReentrant
"doSetup called a second time with "+msg</span><br />
</p>
<p>Transactions can be rolled back explicitly:<br />
</p>
<p><span style="font-family: monospace;">if (balance &lt;
msg.transfer.amount) transaction rollbackTransaction("Insufficient
balance: "+balance+" need "+msg.transfer.amount)</span><br />
</p>
<p>But if all messages that are part of a transaction are processed
successfully and do not themselves send transactional messages, then
transaction commits... basically, the leaf nodes of the transaction are
the message handlers that do not send messages.&#160; If all the leaf
message handlers succeed, they notify their callers that they are
available to commit.&#160; This process rolls up to the original
handler and once all the methods have completed, the worker that
initiated the transaction sends out a Commit message which ripples
through the Workers that participated in the transaction.<br />
</p>
<p>During a transaction, a worker can only process messages related to
that transaction.&#160; I am working on deadlock detection (right now,
it's via timeout, but it could be more sophisticated) as well as
supporting two-phase commits.<br />
</p>
<p>Goat Rodeo includes a powerful backing store: SQL.&#160; Each Worker
has its own private relational data store.&#160; Each Worker can store
complex data structures and perform powerful queries against a
relational database.&#160; Each Worker's RDBMS commits (or rolls back
if the handler exits via an exception or if transaction is explicit
rolled back) at the end of each message process for messages that are
outside of a Goat Rodeo transaction.&#160; For messages within a Goat
Rodeo transaction, the RDBMS connection is committed or rolled back
based on the success or failure of the transaction.<br />
</p>
<p>Goat Rodeo's semantics for message passing, ask/answer and
transactions are identical for local systems or remote systems.&#160;
The Worker implementation will behave the same way in either
case.&#160; How is this acheived?&#160; All messages are guaranteed to
be serializable and not contain any mutable references.&#160; There's
no way to know where a message came from.&#160; The Worker interface is
simple (there are two additional private methods used for out-of-band
communications but those methods take limitted and well-defined system
control messages).&#160; All communication between Workers is handled
via messages.<br />
</p>
<p>If you are interested in a distributed version of Goat Rodeo, please
contact me and we can discuss your project, your needs, etc.<br />
</p>
<p>So, the Goat Rodeo code is up at Assembla (<a
href="http://liftweb.assembla.com/spaces/goat_rodeo/stream">http://liftweb.assembla.com/spaces/goat_rodeo/stream</a>)
[I chose Assembla over GitHub because Assembla has a much better
ticketing system and it has more flexible administrative controls, but
I might move it back to GitHub if there's a good reason].&#160; There's
a Google Group for discussing Goat Rodeo at <a
href="http://groups.google.com/group/goat-rodeo">http://groups.google.com/group/goat-rodeo</a>.&#160;
I look forward to seeing what people think and seeing how Goat Rodeo
can evolve.&#160; <br />
</p>
<p>Oh... and a few side notes.&#160; Goat Rodeo runs on Scala 2.8 Beta
1, so it's not ready for production.&#160; Goat Rodeo was inspired by
Philipp Haller's awesome work with Scala Actors and concurrency.&#160;
I think that the work Jonas and his team have done with Akka is great
and I am interested in seeing how we can share ideas, code,
inspiration, and exploration to make Goat Rodeo and Akka part of one
larger, better thing.&#160; I'll get the Maven bits and pieces up on
scala-tools.org sometime the week of 2/15/2010.&#160; Right now, Goat
Rodeo uses Maven as its build system, that will change to SBT very soon.</p>
<p><br />
Thanks!<br />
<br />
</p> 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/97-Happy-3rd-Anniversay.html" rel="alternate" title="Happy 3rd Anniversay" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-11-20T18:43:09Z</published>
        <updated>2009-11-20T18:43:09Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=97</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=97</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/97-guid.html</id>
        <title type="html">Happy 3rd Anniversay</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <h2>Wow, it's been 3 years I've been in Scala-land</h2>
<p>Three years ago, today November 20th, I discovered Scala... and
how my life has changed for the better.</p>
<pre>Mime-Version: 1.0 (Apple Message framework v752.3)<br />Content-Transfer-Encoding: 7bit<br />Content-Type: text/plain;<br /> charset=US-ASCII;<br /> format=flowed<br />To: scala-subscribe@listes.epfl.ch<br />From: David Pollak &lt;dpp@xxxx.com&gt;<br />Subject: Subscribe<br />Date: Mon, 20 Nov 2006 09:02:26 -0800<br />Subscribe</pre>
<p><br /> <br />
</p>
<p>After RubyConf 2006, I realized that Ruby was not on the right
track for me. I went searching for a new language.</p>
<p>I've been a JVM guy since '96, so finding a language that was as
on the JVM was a plus for me. I was looking for a statically typed
language with high performance, but with the syntactic economy of
Ruby. I bounced around a couple of language listing sites and found
Scala. Three years ago, I fell in total love with Scala. That love
continues today.</p>
<p>What is Scala to me?</p>
<ul>
<li> A language that strikes the right
balance between immutability and mutability. </li>
<li> A language with economical syntax
and type safety. </li>
<li> A object oriented language with a
tremendously powerful type system and compositional model. </li>
<li> A high performance language. </li>
<li> A language with a wealth of
libraries: all the Java libraries. </li>
<li> A language with a highly stable,
broadly available runtime: the JVM. </li>
<li> A language that convinced me that
computer science is really a science. </li>
<li> A language that excels at almost every task I've thrown at it. </li>
</ul>
<p>I discovered Scala and the awesomely warm community. The likes of
Martin Odersky, Lex Spoon, Burak Emir, Adriaan Moors, Jon Pretty and
Jamie Webb hung out in a forum chatting about high level language
topics and helped a Java-slinging, Ruby-toting, null-loving, stateful
guy like me find a new way and a better way.</p>
<p>These guys and some others in the Scala community enlightened me
as to a better way to describe to the computer how to interact with
data and users.</p>
<p>Three years ago, Scala was the next Pizza... a little known
language that was the brainchild of one of the most amazing
practical/theoretical minds in programming language design: Martin
Odersky. Scala was on version 2.2.0... just stretching its legs as a
self-hosted language (rather than the 1.x branch that had a compiler
written in Java.) Scala had hints of being a practical mainstream
language, but it wasn't well know and the community felt fairly
academic.</p>
<p>I first met Martin 6 months later at JavaOne in May 2007. He came
over to San Francisco to do a Scala presentation at JavaOne. By that
time, Bill Venners had become an instrumental part of the Scala
community. Martin was truly awesome. He was quiet. He was focused. He
loved Scala and loved the potential of what Scala could be. He
spent a lot of time fostering the right community on the Scala
mailing list... that excellent community continues through today.  At
the time, I had no clue that this was the first JavaOne mention
of Scala. I had no clue as to the lack of mainstreamness of Scala. I
had been out of JVM-land for long enough that I just thought that I
had missed something.</p>
<p>But, by the time I met Martin, I had embarked on Lift as a
project. We got some early recognition from Tim O'Reilly on his
<a href="http://radar.oreilly.com/archives/2007/05/liftscala-for-w.html">blog</a>.</p>
<p>About a year after I found Scala, Lift had matured into
something beyond a one man show. David Bernard, Jorge Ortiz, Steve
Jenson and others had joined the Lift project. Scala-tools.org was
online. Scala-blogs.org was attracting posters and readers. By
December 2007, Scala was on more and more people's radar.</p>
<p>For me, 2008 was a bad dream. There was a ton of personal
tragedy, but I found that the Scala and Lift communities continued to
be a source of positive energy and a place where I could find outlets
for my coding needs. During 2008, Scala the language matured. <i>Programming
in Scala</i><span style="font-style: normal;"> was
released and it was an excellent work. Scala became a language that
IT organizations were looking at seriously. Companies including
LinkedIn, Twitter and Office Depot were public about their Scala
adoption. We had the first Scala Lift Off in San Francisco. The
buzz about Scala was growing and the energy in the community continued
to be great.<br />
</span></p>
<p><span style="font-style: normal;">2009 seems to be the year that
Scala reached official “alternative mainstream” status along with
Groovy and JRuby. I wrote </span><i>Beginning Scala</i><span
style="font-style: normal;">
and a number of other excellent Scala books appeared. At JavaOne
this year, it was a Scala-fest with standing-room-only at most of the
Scala presentations. We had two Scala Lift Offs: West coast and East
coast. Tool chain support got better and better between IDE support,
the increasingly excellent SBT, and other efforts. Scala and Lift
were featured in BEA's Devoxx keynote highlighting alternative
language support on WebLogic.</span></p>
<p><span style="font-style: normal;">Is Scala at the self-sustaining
level that Python and Ruby are? Not yet. But, for the first time,
I'll predict that Scala has a &gt; 50% chance of reaching Python-level
mainstream
status. Scala and Lift has been embraced this year by hot start-ups
(<a href="http://foursquare.com">FourSquare</a>) as well as big
companies (<a href="http://www.novell.com/products/pulse/">Novell</a>).
The “Scala Bet”
is looking less and less risky and the rewards of using Scala are
increasingly well documented and understood.</span></p>
<p><span style="font-style: normal;">But... more about me. Three
years ago today, I though I had found a place where I could learn...
a place where I could find the right tools for expressing what was in
my mind's eye...
a place that I could contribute back to. Three years later, I am so
happy, so excited (overjoyed really), that I found Scala. Scala
rocks. Scala is fun. Scala is great.</span></p>
<p><span style="font-style: normal;">So, a great big thanks to Martin
and the current and former EPFL folks for making Scala something
great. A big thanks to the early Scala community for planting the
right seeds and shaping things so the Scala community is what it is
today. A super big thanks to the Lift community and the Lift
committers for giving me a place to learn, grow, and have fun.</span></p>
<p><span style="font-style: normal;">Three years later, Scala is
better than anything I could have imagined on November 20</span><sup><span
style="font-style: normal;">th</span></sup><span
style="font-style: normal;">,
2006.</span></p>
<p><br />
<br /> 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/96-Migrating-from-Scala-Actors-to-Lift-Actors.html" rel="alternate" title="Migrating from Scala Actors to Lift Actors" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-10-22T18:54:48Z</published>
        <updated>2009-10-22T19:56:44Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=96</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=96</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/96-guid.html</id>
        <title type="html">Migrating from Scala Actors to Lift Actors</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Lift recently made the shift away from Scala Actors to a more generic
Actor solution that allows for the use of Lift's lightweight Actors as
well as Akka Actors.<br /> <br />
Here's a brief overview of the new Actor structure and how to change
from Scala Actors to Lift Actors.<br />
<br />
Jonas and I worked on the simplest and most generic client interface
for Actors that we could. &#160;This is the interface that a caller
sees and says nothing about implementation. &#160;This is how we
can swap LiftActor and Akka Actor implementations.<br />
<br />
The most basic Actor is defined as something that can accept a message
(these definitions are found in <span
 style="font-family: monospace;">net.liftweb.common.Actor.scala</span>):<br />
<br />
<div style="margin-left: 40px; font-family: monospace;">trait
SimpleActor[T] {<br />
&#160; def !(param: T): Unit<br />
}<br />
</div>
<br />
This allows you to create an Actor that accepts a limited type of
messages. &#160;If you want an Actor to accept any kind of message
(like Scala Actors):<br />
<br style="font-family: monospace;" />
<div style="margin-left: 40px;"><span
 style="font-family: monospace;">trait SimplestActor extends
SimpleActor[Any]</span><br />
</div>
<br />
Many Actors have a send/receive mechanism (you send a message and hang
out waiting for a response). &#160;This is defined by TypedActor:<br />
<br />
<div style="margin-left: 40px; font-family: monospace;">trait
TypedActor[T, R] extends SimpleActor[T] {<br />
&#160; def !?(param: T): R<br />
<br />
&#160; /**<br />
&#160;&#160; * Compatible with Scala Actors' !? method<br />
&#160;&#160; */<br />
&#160; def !?(timeout: Long, message: Any): Box[R]<br />
<br />
<br />
&#160; /**<br />
&#160;&#160; * Asynchronous message send. Send-and-receive
eventually. Waits on a Future for the reply message.<br />
&#160;&#160; * If recevied within the Actor default timeout
interval then it returns Some(result) and if a timeout<br />
&#160;&#160; * has occured None.<br />
&#160;&#160; */<br />
&#160; def !!(message: T): Box[R]<br />
<br />
&#160; /**<br />
&#160;&#160; * Asynchronous message send. Send-and-receive
eventually. Waits on a Future for the reply message.<br />
&#160;&#160; * If recevied within timout interval that is
specified then it returns Some(result) and if a timeout<br />
&#160;&#160; * has occured None.<br />
&#160;&#160; */<br />
&#160; def !!(message: T, timeout: Long): Box[R]<br />
<br />
}<br />
</div>
<br />
Note that the message type, T, and the response type, R, are type
parameters. &#160;If you want a generic send/receive kind of Actor,
use:<br />
<br />
<div style="margin-left: 40px; font-family: monospace;">/**<br />
&#160;* Generic Actor interface. Can send and receive any type of
message.<br />
&#160;*/<br />
trait GenericActor[R] extends TypedActor[Any, R]<br />
<br />
trait SimplestGenericActor extends GenericActor[Any]<br />
</div>
<br />
So, this is the interface. &#160;How do you use a concrete
implementation? <br />
<br />
LiftActor (found in the net.liftweb.actor) package is a trait that
implements the SimplestGenericActor interface. &#160;Lift Actors
differ from Scala Actors in:<br />
<ul>
  <li>Lift Actors share a single scheduler which, by default, is
event base and uses the java.util.concurrent library for thread pooling.</li>
  <li>Lift Actors do not support any form of monitor hierarchy.
&#160;This means there's no link/unlink method. If an exception is
thrown during the processing of a message, it will be processed by the
PartialFunction defined by the exceptionHandler method. &#160;This
means your actor doesn't stop working if an exception is thrown during
message processing.</li>
  <li>Lift Actors do not have a running state. &#160;They
will always process incoming messages. &#160;This means there's no
start or exit methods. &#160;Lift Actors will be garbage collected
by the JVM's GC mechanism if there are no more references to it.</li>
  <li>Lift Actor's message processing is defined by the protected
def messageHandler: PartialFunction[Any, Unit] method. &#160;Because
of Scala's uniform access, this method may be defined as a var that can
be changed from message to message. &#160;If you have fixed rules
for handling incoming messages (as most apps do), you can define a
method (or even a lazy val) for your messageHandler.</li>
  <li>Lift Actors return futures using the !&lt; method
rather than the !! method. &#160;Jonas and I chose to use !! for
returning an option of the result.</li>
</ul>
How do you convert from Scala Actors to Lift Actors?<br />
<ul>
  <li>Remove<span style="font-family: monospace;">
scala.actors.xxxx</span> imports</li>
  <li>Add <span style="font-family: monospace;">import
net.liftweb.actor._</span></li>
  <li>Change "<span style="font-family: monospace;">Actor</span>"
to "<span style="font-family: monospace;">LiftActor</span>"</li>
  <li>Remove all calls to <span
 style="font-family: monospace;">start()/exit()/link()/unlink()</span>
&#160;If you have a monitor hierarchy, you'll have to manage
running/not running manually.</li>
  <li>change <span style="font-family: monospace;">def
act = loop { react {msgHandler } } }</span> to <span
 style="font-family: monospace;">protected def messageHandler
= { msgHandler }</span> &#160;Note that the substance of your
msgHandler does not change.</li>
</ul>
If you want to mix Scala Actors and Lift Actors in your codebase and
you want to have a way of saying "something that accepts the ! method",
you can use Scala's Structural Types:<br />
<br />
<div style="margin-left: 40px; font-family: monospace;">def
doSomethingWithEitherLiftOrScalaActor(actor: {def !(msg: Any): Unit}) =
actor ! "Hello World"<br />
</div>
<br />
Note that as of Scala 2.7.5, <a
 href="https://lampsvn.epfl.ch/trac/scala/ticket/1006">structural
types are not thread safe</a>.<br />
<br />
Hope this helps.<br />
<br />
Thanks,<br />
<br />
David<br />
<br />
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/95-See-Jack-Die...-a-great-book.html" rel="alternate" title="See Jack Die... a great book" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-08-28T04:13:09Z</published>
        <updated>2009-08-31T16:25:18Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=95</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=95</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/2-Personal" label="Personal" term="Personal" />
    
        <id>http://blog.lostlake.org/index.php?/archives/95-guid.html</id>
        <title type="html">See Jack Die... a great book</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p><span style="font-style: italic;">See Jack Die</span>
was an awesomely fun read. &#160;A few months back, I got a bit of
Twitter spam from <a
 href="http://www.nickblackbooks.com/default.aspx">Nicholas
Black</a> (<a href="http://twitter.com/Nicholasblack60">@NicholasBlack60</a>)...
author of&#160;<span style="font-style: italic;">See
Jack Die</span>. &#160;I followed him (a rare thing for me to
do.) &#160;Black tweeted an offer for a PDF review copy of the
book. &#160;I took him up on it. &#160;It took me a month to
find the right eReader to read it on (a Kindle DX), then I was off to
the races.</p>
 <p>I has just finished David Balducci's <span
 style="font-style: italic;">Simple Genius</span>.
&#160;It was a less than satisfying book... which seems to be the
case for most of Balducci's books... but somehow I can't seem to stop
reading them. &#160;Balducci's characters are barely one
dimensional. &#160;The dialog is stilted and the plots are
plotless... yet (and this is probably my personality defect), but I
can't stop reading them once I've started.</p>
<p>So, I get Black's book, <span style="font-style: italic;">See
Jack Die</span>, and I start to read it. &#160;It's fun.
&#160;It's funny. &#160;It's a little confusing at first... the
main character, Jack, has amnesia and as a reader, I feel his amnesia.
&#160;During the first part of the book, I really feel like I'm
exploring Jack's new-found world with him and trying to make sense of
it. &#160;Black really drew me in.</p>
<p>Okay... I'm going to take a break and complain a little:</p>
<ul>
  <li>Black needs some Twitter lessons. &#160;Yeah, he sucked
me in by following me, but his tweets are generally pointless,
repetitive and come 3 an hour, 24x7. &#160;I stopped following him
after 2 days. &#160;I'd be interested in Black's tweets about
actual writing (e.g., "Put Jack in a bad place... how am I going to get
him out?" &#160;"Ricky, Ricky, Ricky... I don't think dad's dollars
are going to help you with that." "Can't write today... gotta get some
transfat into my body.")</li>
  <li>The book needs a couple of more editing passes. &#160;I
found a fair number of type-os. &#160;Now, I'm not one to throw too
many stones about type-os and grammar checking (just look at some of
the reviews of <a href="http://www.apress.com/book/view/1430219890"><span
 style="font-style: italic;">Beginning Scala</span></a>),
but I think Black needs to enlist the community to help him with
editing.</li>
  <li>Ricky (Jack's best friend) seems to morph over the course
of the book to deliver whatever was needed as plot devices... either
that or Black has a deeper plan for why Ricky seems to pull so many
rabbits out of his hat.</li>
</ul>
<p>So, those are my complaints about the book. &#160;On the
good side:</p>
<ul>
  <li>The dialog is really good. &#160;It's not quite Robert
Parker (the old stuff, not the newer stuff) good, but it's Sanford good.</li>
  <li>Bonding over transfat is just plain funny. &#160;I
can't stop thinking about tard-farmers.</li>
  <li>Black kills characters better than anyone else.
&#160;In fact, he's got a dark, twisted and darned funny way of
dealing with death... which is a big part of the book.</li>
  <li>The research is really good. &#160;It's <a
 href="http://www.jefferydeaver.com/">Jeffrey Deaver</a>
good. &#160;Lots of interesting facts that Black clearly
understands and is able to weave into the plot a lot better than
Balducci does with quantum computing (the subject of <span
 style="font-style: italic;">Simple Genius</span>.)</li>
</ul>
<p>So, I strongly recommend <span style="font-style: italic;">See
Jack Die</span>. &#160;Black is right up there with authors
like PJ Tracy. &#160;He's new. &#160;He's got interesting and
original ideas. &#160;He can write a book that hangs together very
well and is very entertaining. &#160;I highly recommend that you
buy a PDF copy of <a
 href="http://www.scribd.com/doc/14458710/See-Jack-Die-Nicholas-Black"><span
 style="font-style: italic;">See Jack Die</span></a>
at Scribd or buy the dead tree version from Amazon. &#160;I wish
Black a lot of luck and look forward to reading more of his books and
more of the <span style="font-style: italic;">See Jack ...</span>
series.</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/94-Lift,-Goat-Rodeo-and-Such.html" rel="alternate" title="Lift, Goat Rodeo and Such" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-06-18T07:07:02Z</published>
        <updated>2009-06-18T07:09:15Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=94</wfw:comment>
    
        <slash:comments>0</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=94</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/94-guid.html</id>
        <title type="html">Lift, Goat Rodeo and Such</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>It's been almost three years since my <a
 href="http://blog.lostlake.org/index.php?/archives/16-Web-Framework-Manifesto.html">Web
Framework Manifesto</a>. &#160;In those three years, I've
founded the <a href="http://liftweb.net">Lift Web
Framework</a>
project, we've shipped Lift 1.0, I've seen a fair number of projects
built with Lift and I've had the honor to interact with a fair number
of excellent engineers at the largest social networking sites.
&#160;While Lift has pushed the envelop and allowed developers to
write
high performance, highly interactive web sites, there's a lot more than
needs to be done. &#160;Specifically, the impedance mismatch
between
browser-resident data, server-resident data, and the persistance layer.
&#160;Additionally, the current crop of persisance mechanisms,
relational databases, are ill-suited to tasks including social
networking and interactive gaming.</p>
 <h3>A Lift retrospective</h3>
<p>Lift
1.0 is out the door. &#160;The Lift community has grown beyond
1,000
members. &#160;I've built or been part of more than a dozen
Lift-related projects. &#160;I'm very happy with how Lift has
evolved.
&#160;But, what is Lift?</p>
<h4>What is Lift?</h4>
<p>When I started the
Lift project, I envisioned Lift being all things, from soup to nuts,
that a web developer would need to build web apps. &#160;That
included
an OR mapper, interfaces to Facebook, PayPal, OpenID, etc. &#160;As
Lift evolved and I heard from the community and other folks started
contributing to the Lift code base, it became clear that Lift-style
abstractions on top of all the things that people would want to do with
web apps was not the right answer. &#160;While there are a bunch of
Lift modules, the core of Lift is Lift Utils and Lift WebKit.
&#160;These two modules provide developers a way to securely
abstract
away the HTTP request/response cycle and focus on the business logic of
their applications. &#160;In the form of SiteMap as well as pattern
matching and extractors, security and access control is primarily
handled by declarative code. &#160;Developers can trust that by the
time a request gets to the view, the access control rules have been
enforced.</p>
<p>Lift's support for Ajax and Comet (a.k.a, Ajax Push or long
polling) is <a href="http://liftweb.blip.tv">unparalleled</a>.
&#160;There is no other framework that allows you to build a real
time
chat app in less than 30 lines of code. &#160;Lift's abstractions
of
long polling combined with Scala's Actors provide an amazingly simple
way to build web sites that update automatically and scale very
effectively, and without deadlocks and other hallmarks of
multi-threaded code. &#160;Lift's pattern of binding HTML elements
to
functions
provides a secure, unified, and extremely concise mechanism for
developers to write standard HTML as well as Ajax apps.</p>
<h4>Lift offers unparalleled security</h4>
<p>Lift apps are secure by default. &#160;Here is a partial
list of Lift's security features:</p>
<ul>
  <li>The Java Virtual Machine is impervious to buffer overflow
attacks</li>
  <li>Scala
is a strongly typed language so you will always know the type of the
parameter passed to your method (e.g., you will not get a List[String]
when you were expecting a String)</li>
  <li>Request parameters are
treated as UTF-8 and all Strings are URL decoded before they reach
application level methods (unless the developer actively requests
earlier access to the data)</li>
  <li>Lift builds all web pages as well
formed XHTML rather than a String or a stream of characters or bytes.
&#160;This means that the developer doesn't have to think about
escaping strings to HTML, it's done correctly and automatically.
&#160;If the developer wants to include non-escaped characters in
the
output, the developer must affirmatively use the Unparsed directive.
&#160;This means that the developer must actively do something to
open
a cross site scripting hole in the application.</li>
  <li>Lift apps are
built with Lift's mapper or JPA. &#160;In both persistence
frameworks,
SQL query parameters are properly escaped. &#160;The developer must
actively choose to send a raw query String to the database before the
app is vulnerably to an SQL injection attack.</li>
  <li>Lift's forms
mechanism associates randomly generated GUIDs with form elements and
functions. &#160;When forms are submitted containing the GUID, the
function is invoked. &#160;This means that replay attacks are not
possible with Lift apps and it means that only the form fields
presented to the user can be submitted back and cause code to execute
on the server. &#160;An attacker cannot add fields to a POST and
have
those fields cause code to be executed on the server.
&#160;Further,
Lift's default select and multi-select generators will reject any
options that were not originally presented when the form was generated.
&#160;All this means is that parameter tampering attacks are very
difficult against Lift apps.</li>
  <li>Lift's SiteMap provides unified
menu generation and access control. &#160;All pages have access
control
rules and if the rules do not evaluate to true, links to the page will
not be presented. &#160;When a page is requested, the access
control
rules are evaluated and if they do not succeed, the request will not be
serviced. &#160;The access control rules are defined declaratively
and
can be easily audited in a code review.</li>
</ul>
<p>All of the above
means that Lift apps are secure. &#160;I've been through a number
of
penetration tests with Lift apps that I've put into production.
&#160;The pen testers have never found a material security
vulnerability in any of the apps they tested. &#160;There's not one
single vulnerability in the OWASP to 10 that's crept into a Lift app
I've worked on. &#160;I've heard similar reports from other folks
who
have gone through pen tests with their Lift apps.</p>
<h4>The other stuff</h4>
<p>The
other parts of Lift are valuable and helpful, but they are not core to
Lift. &#160;Having built in support for XMPP and AMQP as well as
PayPal
and OpenID makes building apps nice. &#160;There is the Lift
Widgets
module for stuff like calendars, etc. &#160;This all makes building
rich Lift apps easy because so many of the pieces are there.
&#160;Additionally, the Lift WebKit has no dependencies on the
other
Lift modules. &#160;This means that the other Lift modules could
have
been written by external parties. &#160;This modularity is nice if
you
want to use your own persistence layer, your own JavaScript libraries
(rather than jQuery or YUI, the Lift defaults), etc.</p>
<h4>Share nothing is fail</h4>
<p>One
thing that has become very clear after spending lots of time with Lift
and watching other folks adopt Lift: share nothing is fail.
&#160;The
share nothing architectures are thin layers on top of relational
databases. &#160;The amount of work that it takes to build secure,
complex apps
in share nothing is amazingly high. &#160;Share nothing apps must
either be primarily stateless or they must put the state someplace.
&#160;Both choices lead to seriously suboptimal results in the goal
is
to build secure or interactive applications.</p>
<p>The
primarily stateless model
of share nothing apps is that there's a cookie that represents the
current session. &#160;The information in the session itself is
usually
the primary key of the current user. &#160;All the other
information
regarding state is based on the URL and any parameters that are passed
as part of the request. &#160;The difficultly in building
multi-form
wizards or shopping carts or other things with state is huge.
&#160;Is
the state kept in cookies or in hidden fields? &#160;If so, the
state
is subject to parameter tampering. &#160;Putting aside the security
issues, the developer effort required to marshal and unmarshal state on
each request is significant. &#160;Even if the developer gets it
right,
making any changes to the code becomes a seriously difficult issue.</p>
<p>The
other option for share nothing is to push state into memcached or the
RDBMS. &#160;This is a more secure method because the state cannot
be
altered changing parameter or cookie values. &#160;However, the
issues
related to marshaling remain. &#160;Further, there is pressure put
on
the RDBMS unless memcached is used to store state, but memcached is a
cache and subject to cache misses which means that state can go away.
&#160;Sure it works to marshal via the RDBMS, but then you have a
single point of pressure in your application and when the RDBMS hits
the wall, your application will come to a grinding halt... think fail
whale here.</p>
<p>There are a number of other success web frameworks, including
Wicket, WebObjects, and Seaside, that are highly stateful.
&#160;Many high volume sites (including Apple's store) run on these
systems and have a very good uptime record. </p>
<h4>Frameworks still evolving</h4>
<p>At the end of the day, web frameworks are still evolving.
&#160;Rails'
awesome leap forward in developer productivity provided the catalyst
for other folks to critically evaluate the web development process.
&#160;While I believe Lift has a bunch of really good concepts
built
into it, I think there are other better ways to describe web
applications. &#160;I expect web frameworks as a whole to be a
growing,
evolving category over the next 10 years until we've been able to
capture the semantics of web development and refined and reduced the
semantics into composible structures.</p>
<h3>Models</h3>
<p>Sometimes, software abstractions grow out of the definitions
of the underlying computing systems. &#160;For example, C
abstracted assembly language. &#160;C++ abstracted C.
&#160;Java abstracted C++ (more or less and in the case of
templates, a whole lot less.) &#160;Sometimes, software abstracts
the needs of the application developer. &#160;SQL and COBOL are
good examples. &#160; But as the application needs change, the
tools and frameworks must change to support the application demands.</p>
<p>SQL is an example of
an excellent response to the real world needs of business applications.
&#160;SQL is great for ERP. &#160;SQL in the abstract is good
for more recently
popular applications such as social networking. &#160;In practice,
SQL
databases are not good at dealing with social graphs once the social
graphs exceed a certain size. &#160;However, it's become clear that
SQL does not solve all the problems on the web. &#160;The rise of
CouchDB, Google App Engine/BigTable, Amazon's SimpleDB, etc. indicates
that for the web, the relational model is not the right fit.</p>
<p>Just as Rails signaled a shift in web frameworks, the spate of
new persistence technologies is signaling that it's time for us to
reexamine the way we store data and the way that we reflect the flow of
data from the edge of the network, typically the browser, through the
business logic (increasingly browser resident), through the
server-application into persistence and/or other systems that will
trigger the flow of data to other edge devices. &#160;That's a long
way of saying, "moving this data is hard and we don't have a clue how
to do it right."</p>
<p>The problem is further amplified by the rise of new client
technologies: DHTML (the real stuff) and Flash/Flex/Air.
&#160;Interactive client apps are pretty darned hard to build and
even harder to keep up to date with servers that have different
business logic models and different persistence models (not to mention
different object models.) &#160;While Adobe is doing a good job of
providing data synchronization tools for Air apps, I don't think
proprietary systems will have the reach that open systems built on open
standards do.</p>
<h3><a href="http://goatrodeo.org">Goat Rodeo</a></h3>
<p>There needs to exist a unified model for building real-time
interactive web applications from the persistence layer, through the
messaging layer, through the business logic layer, out to the client.
&#160;Lift is part of this equation. &#160;Goat Rodeo will
become the other part of the equation.</p>
<p>Goat Rodeo will provide:</p>
<ul>
  <li>A compiler-checked, Scala based unified model for
describing data structures that can be consumed by Scala, JavaScript
and anything else that speaks JSON... these items are called Qs (quanta
of information)</li>
  <li>A distributed transaction model based on the <a
 href="http://hadoop.apache.org/zookeeper/">ZooKeeper</a>
project. &#160;This will support 20K transactions per second.</li>
  <li>A scalable persistence layer, most likely built on <a
 href="http://incubator.apache.org/cassandra/">Cassandra</a></li>
  <li>A transaction model based on <a
 href="http://www.haskell.org/haskellwiki/Software_transactional_memory">Software
Transactional Memory</a> that is exposed to the developer using
Scala's for comprehension</li>
  <li>References that support the storage of Qs, doubly linked
lists of Qs or maps of Qs with persistence definitions of local,
ZooKeeper, and long term</li>
  <li>Association of methods with Qs such that the methods can be
emitted in native Scala or JavaScript... the code is a subset of Scala
and can be pushed to environments (e.g., the browser</li>
</ul>
<p>With the above building blocks, you get:</p>
<ul>
  <li>Scalable persistence</li>
  <li>Distributed actors</li>
  <li>Synchronization of data and data model from browser through
long term storage (yes, I'll be working to make sure this works with
Lee's <a href="http://github.com/mighdoll/jsync/tree/master">jsync</a>.)</li>
  <li>Unified interprocess communications, even across
heterogeneous processes</li>
  <li>What I believe will be a very scalable system for social
networks and other social, interactive web apps to build on top of</li>
</ul>
<p>Right now, Goat Rodeo is in the noodling and building phase.
&#160;I'm working on the Scala compiler plugin that does the
enforcement of Q types as well as the generation of serialization and
deserialization. &#160;I'm also wiring up ZooKeeper and Cassandra
such that the play with transactional niceness with each other.</p>
<p>I am not developing Goat Rodeo in a vacuum. &#160;Goat
Rodeo will be a back end for Lift's new Record system (along with JDBC
and JPA). &#160;I am working on a real time information sharing
system so that people can annotate and link pictures and other
information from the Scala Lift Off as a test bed and driver for Goat
Rodeo.</p>
<p>I expect that by end of summer, Goat Rodeo and its associated
Lift integration will be ready for someone who isn't me to play with.
&#160;In the mean time, if you're interested in helping to shape
the direction of Goat Rodeo, please drop by the <a
 href="http://groups.google.com/group/liftweb/">Lift list</a>
and share your thoughts.</p>
<p>Oh... and if you're wondering about the name... just think
about the job of managing the piles of data that come into your
application... it's a...</p>
<br />
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/93-In-defense-of-DHH-the-Rails-comminity.html" rel="alternate" title="In defense of DHH &amp; the Rails comminity" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-04-29T13:16:06Z</published>
        <updated>2009-05-03T17:20:28Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=93</wfw:comment>
    
        <slash:comments>15</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=93</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/3-Ruby" label="Ruby" term="Ruby" />
    
        <id>http://blog.lostlake.org/index.php?/archives/93-guid.html</id>
        <title type="html">In defense of DHH &amp; the Rails comminity</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>No, my machine was not hacked.  Yes, I do believe that DHH and the Rails community has done far more to advance web development than the Apache
Software Foundation.  I radically disagree with <a href='http://cubiclemuses.com/cm/articles/2009/04/28/a-community-of-rockstars/'>J Aaron Farr's</a> 
post comparing the two.</p> <p>First, I am a fan of DHH.  I think he's a wicked smart person and that Rails as a piece of software and as a catalyst for
web development is a milestone.  DHH built Rails and created the Rails community.  He's done a masterful job.
He's also become more of a statesman over the years.  With that being said, I'm not a huge fan of the Rails community
or its culture.</p>

<p>I'm a user of a lot of Apache Software Foundation stuff.  It's solid.  It's maintained.  With the possible exception of Wicket,
none of it is groundbreaking.  In fact,
some of it is <a href="http://tomcat.apache.org/">poorly</a>
<a href='http://ant.apache.org/'>designed</a> <a href='http://struts.apache.org/'>crap</a>.
I'm an Apache <a href='http://people.apache.org/~jim/committers.html'>commiter</a> (perhaps not for long) 
on the <a href='http://incubator.apache.org/esme/community/community.html'>ESME</a> project.
I have seen very little of the meritocracy that Aaron blogs about.
</p>

<h2>It's not easy <strike>being green</strike> running a ground-breaking project</h2>

<p>I've run my share of <a href='http://www.plsys.co.uk/mesa'>groundbreaking</a>
<a href="http://athena.com">software</a> <a href="http://liftweb.net">projects</a> in my life.
It's really not an easy task.  Having vision, managing employees/committers, building community, and
satisfying users all takes a bit of attitude that pisses people off.  Let's look at what DHH did with Rails:
<ul>
<li>He blew away most of the other web frameworks by demonstrating that web development could be
concise and that web apps could be built to be visually pleasing and easy to use without a ton of
developer time.  That, IMHO, puts him in diety territory.</li>
<li>He built an ecosystem around Rails that had enough critical mass to spawn a whole industry around
Rails development.</li>
<li>And the 37 Signals apps don't suck.</li>
</ul>
But doing all that requires making choices.  DHH made a series of choices about style, community building, etc.
Some people think he's a jerk... but the same can be said about Steve Jobs, Bill Gates, Halsey Minor and other folks who
fundamentally changed the game (yeah, I'm lumping DHH in league with those guys.)  In my opinion,
DHH is not a <a href="http://en.wikipedia.org/wiki/Kim_Polese">one</a> <a href="http://en.wikipedia.org/wiki/Craig_Newmark">trick</a> 
<a href="http://en.wikipedia.org/wiki/Mark_Pesce">pony</a> (<a href="http://www.amazon.com/Architects-Web-Built-Future-Business/dp/product-description/0471171875">Folks who built the future</a>).
He's got direction, attitude, energy, charisma, and the other stuff that it takes to change the game, and he'd done just that.
</p>

<h2>And in the other corner, weighing 98 pounds...</h2>
<p>Now, let's look at the ASF.  It's a nice place to house a project.  There are lots of reports to write.  In fact, I believe more
time is spent on the ESME project writing monthly reports than writing code.  The ASF has done nothing to help
the ESME folks build community or inspire folks to join the project.  There's been little in the way
of technical guidance.  Sure there's brand and visibility in having an ASF project,
but there's no meritocracy.  There's nothing that I've seen in the ASF that rewards anything other than being nice and writing
reports and having statistics get better.  Sure, if I'm Yahoo! and I want to open source <a href="http://hadoop.apache.org/">Hadoop</a> and pay my developers to
work on it, Apache is a nice neutral place to house it.  <a href="http://couchdb.apache.org"/>CouchDB</a> is high on the doesn't
suck scale, but I gotta say, <a href="http://damienkatz.net/">Damien Katz</a> is the personality behind it (no, he's not
as acerbic as DHH) and without him, CouchDB would not be (violating the ASF guidelines, but I guess they needed a flashy project).</p>

<p>Further, let's look at the ASF crap pile.  Well, there's the HTTP server... so bogged down in commityism that Nginx 
blows it away.  Struts... the ultimate piece of crap web framework.  ActiveMQ... junk compared to RabbitMQ.  Tomcat,
consistently behind Jetty (a personality driven show.)  There's no real merit that I can see across the board in Apache's offerings.
Put another way, if the ASF were a meritocracy, they'd dump the crap that's in their top-level projects.</p>

<p>Yes, I think that the Rails community could be a nicer place to be.  I've tried to build the Lift community so that
it's a warmer and more welcoming place to be than the Rails community.  But I am sure glad Lift is not part of
the ASF.  I tip my hat to DHH and what he's built.</p>

<p>Party and (likely) flame on.</p> 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/92-Lift-1.0-is-available.html" rel="alternate" title="Lift 1.0 is available" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-02-26T18:13:08Z</published>
        <updated>2009-03-03T04:27:17Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=92</wfw:comment>
    
        <slash:comments>13</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=92</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/92-guid.html</id>
        <title type="html">Lift 1.0 is available</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Two years ago, today, I <a
 href="http://blog.lostlake.org/index.php?/archives/43-Announcing-the-lift-web-framework-version-0.1.0.html">launched</a>
the Lift Web Framework as an open source project. &#160;Wow... it's
been a long and fun experience... and today the dozen plus Lift
committers and the whole Lift community together are&#160;releasing
Lift 1.0.<br />
<br />
 Lift is an expressive elegant web framework based on the <a
 href="http://scala-lang.org">Scala</a>
programming language and released under an an Apache 2.0 license.
&#160;Lift provides developers the best way to build interactive,
high
performance web applications. &#160;Lift based applications are
deployed as WAR files into J2EE containers such as Jetty, Tomcat, and
WebLogic. &#160;Lift based applications are high performance and
can
make use of your existing Java libraries.<br />
<br />
I could wax on for hours about:<br />
<ul>
  <li>Lift's Comet and Ajax support which allows you to build
real-time interactive applications</li>
  <li>Lift's concise code allowing developer productivity
normally associated with Rails and TurboGears</li>
  <li>Lift's high performance and scalability</li>
  <li>Lift's built-in support for REST and other web services</li>
  <li>Lift's use of Scala's type-safety so your tests can focus
on business logic</li>
</ul>
But, that's not the most impressive thing about Lift. &#160;Lift is
powered by a community of committers and users that cares about
building tools for building great web apps. &#160;Lift is
impressive because of the people who use, drive, enhance and exchange
ideas about Lift. &#160;The Lift community is a warm, welcoming
place for people of all backgrounds. &#160;The Lift community and
Lift committers strive to learn from others and roll that learning into
Lift and their own projects. &#160;That's my take on what makes
Lift great, but let's hear what other have to say about Lift:<br />
<blockquote>The interest and excitement about Scala continues to
grow.&#160;
It's great to see Lift reaching the 1.0 milestone as this is a proof
point for the maturity of Scala as a software platform.
  <br />
  <div style="margin-left: 40px;"><a
 href="http://lamp.epfl.ch/%7Eodersky/">Martin Odersky</a>,
ACM Fellow, Father of Scala<br />
  </div>
</blockquote>
<blockquote><br />
Lift is the only new framework in the last four years to offer fresh
and innovative approaches to web development. It's not just some
incremental improvements over the status quo, it redefines the state of
the art. If you are a web developer, you should learn Lift. Even if you
don't wind up using it everyday, it will change the way you approach
web applications.
  <br />
  <div style="margin-left: 40px;"><a
 href="http://www.ibm.com/developerworks/opensource/library/os-ag-lift/#author">Michael
Galpin</a>, Developer,
eBay<br />
  </div>
</blockquote>
<br />
<blockquote>
The slight added complexity of static typing is more than offset by the
performance, scalability, and the benefits of type safety. Lift is
maturing rapidly and has already proven itself many times over, and it
will only get better.<br />
  <br />
As much as I liked Ruby and Rails, I like Scala and Lift better. After
more than two years of developing software in Ruby/Rails, we've shifted
all our development efforts to Scala/Lift. And we are not looking back.<br />
  <div style="margin-left: 80px;">Charles Munat, <a
 href="http://lightsourceinteractive.com/">Lightsource
Interactive</a><br />
  </div>
</blockquote>
<br />
<blockquote>
Lift's excellent 'Comet made easy' philosophy made it an absolute
no-brainer as the choice of framework for the Apache ESME project.
Additionally, the fact that Lift-based applications run unchanged on
the SAP's NetWeaver CE Java application server makes this an intriguing
approach for enterprise applications in the SAP world.<br />
  <div style="margin-left: 40px;">Darren Hague, SAP
Mentor, <a href="http://blog.esme.us">ESME</a>
team lead<br />
  </div>
</blockquote>
<br />
<blockquote>
When I decided to put <a href="http://buyafeature.com">Innovation
Games</a>® online, I knew that I couldn't
afford a massive development effort. I needed a small, sharp team who
could leverage best-in-class tools to help us solve the problems we
knew that we'd have to solve in creating a new kind of collaborative
gaming experience on the web. David suggested Lift and Scala and
initial testing proved that we could realize the developer efficiency
and backend scalability that we felt was required to efficiently
support thousands of simultaneous games. We're now very comfortable
with Lift and Scala and are pleased with how the solution framework
continues to evolve to meet our needs. While we've used lift to push
the boundaries of interactive web design, I strongly recommend anyone
who wants to build a compelling web experience using an elegant
framework to consider using Lift.
  <br />
  <div style="margin-left: 40px;">Luke Hohmann, CEO, <a
 href="http://enthiosys.com">Enthiosys</a><br />
  </div>
</blockquote>
<br />
<blockquote>
If you're looking for a web framework on a strongly typed functional
language and the JVM, Lift is the only game in town. Oh, and it just
works, too.<br />
  <div style="margin-left: 40px;">L.G. Meredith, Managing
Partner, Biosimilarity LLC<br />
  </div>
</blockquote>
<br />
<blockquote>
For me it's mainly because Lift represents collective web wisdom - all
lessons learned and new to be discovered.
  <br />
  <div style="margin-left: 40px;">Viktor Klang<br />
  </div>
</blockquote>
<br />
<blockquote>
I find Lift a very solid piece of software very well designed and
written. It is the result of many years of experience of many people. I
believe in Lift's utility when developing not only compelling web
applications but also other server side applications sitting on top of
HTTP stack. I would choose Lift over any other web framework out there
without blinking.
  <br />
  <div style="margin-left: 40px;">Marius Danciu</div>
</blockquote>
<br />
<blockquote>
Lift is like a breath of fresh air: concise, elegant and robust - all
on my existing Java infrastructure...<br />
  <br />
Lift stands on the shoulders of giants, learns from their mistakes and
adds a whole new dimension to web application development.<br />
  <br />
Irrespective of the technology, what makes Lift really special is the
community - well read, intelligent and welcoming.<br />
  <div style="margin-left: 40px;">Tim Perrett<br />
  </div>
</blockquote>
<br />
<blockquote>
Lift combines simplicity, flexibility and power better than any other
web framework in my experience.
  <br />
  <div style="margin-left: 40px;">Derek Chen-Becker<br />
  </div>
</blockquote>
<br />
<blockquote>
Lift allows a single person to accomplish what would have previously
taken an entire team.<br />
  <div style="margin-left: 40px;">Tyler Weir<br />
  </div>
</blockquote>
You can get started with <a href="http://liftweb.net">Lift</a>
or join the <a href="http://groups.google.com/group/liftweb?hl=en">Lift
community</a> right now. &#160;But, it's time for me to thank
a whole bunch of folks that led to Lift and keep Lift going:<br />
<ul>
  <li>The Lift committers who are a totally awesome group of
folks that I'm honored to work with.</li>
  <li>The Lift community as a whole.</li>
  <li>Dani, Jon and Brion for doing the SmartMode thing back in
2000-2001. &#160;SmartMode inspired Lift.</li>
  <li>Martin Odersky, Lex Spoon, Burak Emir, Philipp Haller and
the other awesome people that build Scala and the Scala community.</li>
  <li>Jamie and Jon who, along with Burak, taught me Scala.</li>
  <li>The Scala community as a whole which is a great place.</li>
  <li><a href="http://ecstatic.com/">Roger Rohrbach</a>
for the name Lift and the rest of the Gabblists for a lot of support
and feedback.</li>
  <li>Matthew and Walt for taking the first chance with Lift and
helping me understand how to teach Scala.</li>
  <li>Tim O'Reilly for <a
 href="http://radar.oreilly.com/archives/2007/05/liftscala-for-w.html">raising
awareness</a> about Lift.</li>
  <li><a href="http://enthiosys.com">Luke Hohmann</a>
for betting <a href="http://buyafeature.com">Buy a Feature</a>
on me and Lift.</li>
  <li>SteveJ, Jorge, and DavidB for being the early committers
and the guys that turned Lift from my project into the community's
project.</li>
  <li>Aaron Williams for the putting Buy a Feature into SAP's <a
 href="https://cw.sdn.sap.com/index.jspa">Collaboration
Workspace</a>.</li>
  <li>Lee Mighdoll for making repeated bets on me and Lift, not
to mention crafting the phrase "expressive elegant web framework".</li>
  <li>Kaliya who builds the best communities.</li>
  <li>Jack, an awesome CEO, for reminding me what focused leadership means.</li>
  <li>Darren and Dick for choosing Lift for ESME and for
including me in the ESME project.</li>
  <li>The whole ESME team for exposing 10,000+ SAP developers to
a Lift application at three DemoJams.</li>
  <li>Greg who keeps on asking me the hard questions that drive
Lift in a more functional direction.</li>
  <li>Debby who has been herding the Lift project towards 1.0.</li>
  <li>My wife and father and kids who provide(d) the tools for
taking the risks of thinking beyond the norm.</li>
</ul>
Lift is 1.0. &#160;Lift is ready and able to power your interactive
web applications. &#160;The Lift community is waiting to welcome
you, your questions and your feedback. &#160;Please join us.<br />
<br />
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/91-IntelliJ-update-its-still-a-piece-of-junk-but-Scala-support-isnt-bad.html" rel="alternate" title="IntelliJ update: it's still a piece of junk (but Scala support isn't bad)" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-02-09T18:17:49Z</published>
        <updated>2009-02-15T05:22:12Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=91</wfw:comment>
    
        <slash:comments>24</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=91</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/91-guid.html</id>
        <title type="html">IntelliJ update: it's still a piece of junk (but Scala support isn't bad)</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                I recently did a pretty negative review of the IntelliJ and its Scala
support. &#160;Based on a lot of feedback and some very polite
posts from Ilya, one of the Scala plugin developers, I took another
look at IntelliJ. &#160;Based on spending more than a week with
IntelliJ, configuring and tuning it, I fail to understand why someone
would pay a dime for IntelliJ. &#160;I find it to be a poorly
thought out product. &#160;The Scala support has strengths and
weaknesses compared to the NetBeans Scala plugin. &#160;If you use
and like IntelliJ, you will likely disagree with this review and you'll
likely find the Scala plugin to be a good tool. &#160;If you
haven't used IntelliJ yet, don't waste your time.<br />
<br />
 I've been using programming editors since 1983 when I first started
doing C programming for the Apple ][. &#160;Despite this, I do not
think I'm a power user of programming editors. &#160;I have a few
things that I do and don't try to dig deeper. &#160;My favorite
editor of all time is Brief, but alas (and partially due to my
lawyering work), Brief is not longer available. &#160;Emacs is my
default editor of choice.<br />
<br />
I write a lot of code, but I do it simply. &#160;I write code.
&#160;I compile code. &#160;I test code. &#160;I write
more. &#160;I open lots of files and usually have 2 or 3 projects
open at the same time. &#160;In rank order, the most important
things an editor can do for me are:<br />
<ol>
  <li>Allow me to quickly navigate to the <span
 style="font-style: italic;">file </span>I want to edit</li>
  <li>Find the lines in the file that I need to change/add to</li>
  <li>Give me real-time feedback about errors</li>
  <li>Format code nicely</li>
  <li>Support a very nice manual find/replace mechanism (Emacs is
king of this)</li>
  <li>Allow me to see more than one part of a file at once</li>
  <li>Support opening multiple projects and files outside of
projects quickly and easily</li>
  <li>Does not assume that I will be doing all my work inside the
editor... I use the command line a lot</li>
  <li>Open files based on a regular expression (e.g., emacs
$(grep -l Foo $(find . -name *.scala)))</li>
</ol>
While Emacs does most of this stuff very, very well, it doesn't support
real-time feedback on program errors, nor is its Scala formatting
particularly good. &#160;I was using jEdit for a while, but as the
NetBeans plugin matured, I switched to NetBeans. &#160;It does 1
and 2 well enough and is great at 3 and 4. &#160;NetBeans is still
beta. &#160;Its got its weaknesses, most notably class navigation
is particularly weak.<br />
<br />
A couple of random things. &#160;First, I have a vested interest in
more better tools for Scala, so posting negative things about IntelliJ
is not in my interest. &#160;Second, Scala's object model,
implicits, traits, etc. make things particularly difficult for IDE
plugin writers. &#160;Third, I do not do automatic refactoring.
&#160;I find that it takes away from my understanding about the
code. &#160;Even if a refactoring takes me 2 hours rather than 30
seconds, the 2 hours is <span style="font-weight: bold;">always</span>
well spent learning about how the code works.<br />
<br />
I'm going to put aside my installation issues for IntelliJ on 64 bit
Linux. &#160;I outlined those issues in my last post. &#160;All
my testing was done on a Windows Vista machine. &#160;Installation
was flawless and IntelliJ fired right up. &#160;So far, so good.<br />
<br />
I installed the 8.1 Diana EAP version of IntelliJ as I was told that
this was better for Scala work. &#160;I installed the Git, Maven,
and Scala plugins. &#160;I opened Lift and went for the most gnarly
file for an IDE: the Lift Textile parser. &#160;This 1,300 line
file results in about 2,000 classes. &#160;It's a big hairy mess
for an IDE. &#160;Good news, IDEA handles the file. &#160;Bad
news, IDEA finds a bunch of errors in the file, but when I edit the
file and insert junk, IDEA doesn't flag my typing errors. &#160;I
closed the file and try for something less nasty.<br />
<br />
I went searching for another file to edit. &#160;I found one,
although it seems that browsing in IDEA is by class, not by file.
&#160;This is a challenge in Lift when packages often have hundreds
of classes. &#160;After a lot of rooting around, I found that you
can view a project by "Scope: All" and navigate by file.<br />
<br />
I open another file, move to the line I want to edit and click on the
line. &#160;My cursor is at the click-point, rather than the end of
the line. &#160;This is kinda stupid. &#160;Why doesn't
IntelliJ just put the cursor at the end of the line (this and other
annoyances are configurable, we'll get to that in a little while)?
&#160;The editor is counter-intutive. &#160;Okay, I do some
editing. &#160;I do some code navigation.<br />
<br />
The code navigation is clearly IntelliJ's strong point. &#160;I
navigate quickly through all of my Scala classes. &#160;For library
classes, IntelliJ provides me with method signatures that are enough
for me to understand what's going on. &#160;I'm starting to warm up
to IntelliJ. &#160;I'm liking the Scala plugin. &#160;It's
doing something that I haven't seen since Java in Eclipse... seamless
class navigation. &#160;I'm starting to understand why people like
IntelliJ and the Scala plugin.<br />
<br />
I do some find and replace. &#160;Once again, IntelliJ is good at
this. &#160;Its editor makes incremental search, changing
something, and searching again a very simple task. &#160;It's not
quite as nice as Emacs, but it's better than NetBeans.<br />
<br />
And this is as good as IntelliJ gets. &#160;The rest is a freaking
horror show.<br />
<br />
I committed up my changes to Lift. &#160;I monitor Hudson and the
build is broken. &#160;It's broken in Textile. &#160;IntelliJ
frickin' saved my bogus changes to the Textile file. &#160;What the
f**k? &#160;So, I dimly remember that IntelliJ has an autosave mode
and apparently the autosave mode also marks the file as "added" to Git.
&#160;This is absolute stupidity. &#160;Unless I explicitly
save a file, it should not change on disk. &#160;So, I spend an
hour working through the preferences in IntelliJ. &#160;I disable
auto-save (this <span style="font-weight: bold;">should
not</span> be the default!!!!) &#160;I set the editor up to
work the way most other editors work. &#160;I go back to work.<br />
<br />
Even with auto-save disabled, IntelliJ saves file changes <span
 style="font-weight: bold;">automatically</span> when
the editor is exited. &#160;This alone is a disqualifier for
IntelliJ. &#160;I haven't found a way to disable this behavior.
&#160;What the f**k are the IntelliJ folks thinking? &#160;If I
want to save a file, I'll save it. &#160;If I want to discard a
file, I'll discard it. &#160;The default behavior should be the way
most other programs are: files are explicitly saved.<br />
<br />
The default editor behaviors are screwed up. &#160;The default
should be the way other editors work. &#160;If IntelliJ wants to
changed the paradigm, fine. &#160;But the mental cost of forcing me
to spend a lot of time navigating preferences makes me think the
IntelliJ folks are more interested in foisting their paradigm on me
than giving me a tool that works the way I want to work. &#160;At
the very least, there should be a simple option "Emacs mode" or
some-such that sets the various properties to work the way us old-time
Emacs kinda guys work.<br />
<br />
As a side note, I did some work with the Talligent C++ class-based
editor back in the 90s. &#160;IntelliJ seems to have a paradigm
that's part of what Talligent was doing: navigate and edit the class,
not the file. &#160;Implicitly save changes, etc. &#160;If
there was an obvious change log that could be undone in a single
operation <span style="font-weight: bold;">and </span>&#160;class-granularity
for the editor rather than file granularity (when you open a class, you
just see that class), the paradigm might work. &#160;Unfortunately,
the way IntelliJ has stradled between file and class-based editing is
an amazingly bad balance.<br />
<br />
Next thing I did was open two projects. &#160;IntelliJ opens a new
window (they call it a frame, because different names are good?) for
the new project. &#160;Navigation across classes in the projects
worked well. &#160;I was feeling good, until I exited IntelliJ.
&#160;I later reopened it and only one of my projects was open.
&#160;This is once again a wicked bad design. &#160;I IntelliJ
keeps track of stuff, then it should keep track of <span
 style="font-weight: bold;">all</span> the projects I
have open, not just the most recently edited project.<br />
<br />
Other stuff that I find anoying about IntelliJ:<br />
<ul>
  <li>Lots of flashing icons. &#160;Once I've clicked on the
icon, it should stop flashing.</li>
  <li>What are facets and why should I care?</li>
  <li>The default character set on Windows is the Windows
character set. &#160;This is brain damaged for any web-related work
(it should be UTF-8) and I haven't figured out how to change this.</li>
  <li>The icons are ugly. &#160;A commercial product, an
expensive commercial product, should look better.</li>
  <li>The JDK for a project is not automatically set.
&#160;Do what Eclipse does: if the JDK is not defined, prompt the
user.</li>
  <li>Sometimes IntelliJ just freezes without a wait cursor.
&#160;If IntelliJ is doing something, then let me know... don't
make me guess to see if the IDE has frozen.</li>
</ul>
<br />
The Scala plugin is in beta, so my comments are only applicable to the
current beta version. &#160;Ilya seems to care a lot about what
people think and seems to be working towards having the best Scala
plugin. &#160;So, the code navigation and syntax highlighting in
the Scala plugin are first rate. &#160;The stuff that doesn't work
so well for me are:<br />
<ul>
  <li>Errors are flagged for default packages until the JDK is
defined. &#160;This one tripped me up until Illy told me to define
my JDK.</li>
  <li>Errors are not flagged as I type. &#160;It seems that
the Scala plugin detects errors about 40% of the time. &#160;This
is less than optimal. &#160;Errors should be flagged correctly.</li>
  <li>XML support is marginal. &#160;Yes, this is so hard
that the Eclipse plugin punts on it. &#160;I find a lot of pauses,
long ones, when I'm typing in XML.</li>
  <li>The code formatting choices are not the right ones.
&#160;There are Scala coding guidelines that EPFL uses.
&#160;These should be the defaults for the plugin.</li>
  <li>XML is not indented properly.</li>
</ul>
When I tried IntelliJ for the second time, I really wanted to like it.
&#160;I tried very hard to care about the positive feedback that a
lot of people I respect have about IntelliJ. &#160;I wanted to say
good things so I could answer the "how's the Scala tools support?"
question more positively. &#160;I'll even go farther. &#160;If
someone wants to send me configuration steps for IntelliJ to make it
work like NetBeans or Emacs, I'll spend another week using it.
&#160;I want very much to say good things about IntelliJ, but my
experiences with it are so overwhealmingly negative that I can't find
nice things to say beyond praising Ilya's work and progress with the
Scala plugin.<br />
<br />
So, I'm not going to use IntelliJ. &#160;I'm betting the Scala
plugin will improve, but the overall horribleness of IntelliJ is so
overwhelming that I can't see using IntelliJ, even if the Scala plugin
becomes the best Scala plugin on the planet. &#160;Yes, I know that
a lot of people swear by IntelliJ. &#160;Great, for you guys, go
ahead and use it with the Scala plugin. &#160;For the folks in the
world who use programming editors the way I do, stay as far away from
IntelliJ as you can. &#160;It's a poorly designed piece of junk.<br />
&#160;
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/90-IntelliJ-a-huge-dissapointment-for-Scala-development.html" rel="alternate" title="IntelliJ a huge dissapointment for Scala development" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-01-30T18:38:39Z</published>
        <updated>2009-02-01T15:04:25Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=90</wfw:comment>
    
        <slash:comments>21</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=90</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/90-guid.html</id>
        <title type="html">IntelliJ a huge dissapointment for Scala development</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                Scala IDEs are not up to the same level of fit and polish as as Java
IDEs. &#160;This is something of a bummer. &#160;While I'm an
early adopter and I'm willing to put up with a fair amount of rough
edges, I do like having good tools. &#160;I've been using and
liking NetBeans with the Scala plugin. &#160;I've been generally
happy with it, but I've heard a lot of good things about IntelliJ, so I
decided to give it a try. &#160;IntelliJ is perhaps the worst IDE
I've used in the last 10 years, Scala or no. &#160;I'm wondering if
the IntelliJ folks even have a QA department.<br />
<br />
 Yep, those words about IntelliJ are pretty harsh. &#160;But I was
unable to get IntelliJ to work at all on my Linux machine. &#160;On
Windows, it works, but is so amazingly clunky that it's not worth
installing.<br />
<br />
I downloaded IDEA 8 and untarred it on my 64 bit Ubuntu 8.04 machine.
&#160;I fired up IDEA... and it complained that JDK_HOME was not
defined. &#160;Gosh, JAVA_HOME is. &#160;So, why can't their
scripts check for common variations on the location of the JVM... or
even just ask Java what it's home is. &#160;Not hard folks.<br />
<br />
So, I set the environment variables and fire up IDEA again.
&#160;This time, all the dialog windows are blank. &#160;No
content. &#160;I keep pressing "Enter" until IDEA opens up.
&#160;I install Git, Maven, and Scala plugins and open a Scala
project and IDEA and IDEA runs out of memory. &#160;So, I give IDEA
1GB of RAM and try again. IDEA runs out of RAM. &#160;How about
4GB. &#160;Nope... still out of memory.<br />
<br />
I tried running IDEA on my Windows box. &#160;It installed and was
able to open projects. &#160;Unfortunately, it leaves turds in the
project directory after loading the pom.xml file. &#160;Okay, I can
live with that. &#160;Then IDEA gives me a bunch of errors while
resolving the dependencies in my pom file. &#160;I was able to open
my project and start editting files. &#160;However, every time I
tried to imbed XML in my Scala code, IDEA would freeze for many seconds
at a time while using 100% CPU. &#160;Yeah, I know that handling
XML is non-trivial, but NetBeans' Scala plugin does it just fine.<br />
<br />
There's no way to browse files in IDEA. &#160;There's only class
browsing. &#160;Scala programs have far more classes in a given
package than does Java. &#160;So, I was hoping for file-based
browsing. &#160;No luck. &#160;I've got 3 or 4 screen-fulls of
classes to wade through to open the one I want... but the file name is
listed in the tabs. &#160;So, which is it folks? &#160;File
name or class name? &#160;If it's only class name, why not just
display the class as a stand-alone in editor?<br />
<br />
I also tried running IDEA on a 32 bit JVM on Ubuntu. &#160;The
blank dialog problem is gone, but in its place, the plugin manager
cannot reach IntelliJ's plugin site.<br />
<br />
So, maybe I'm missing the glory and beauty of IntelliJ, but I can't see
spending a penny on an IDE like IDEA, especially for doing Scala
development. &#160;Nope... I'm sticking with NetBeans.<br />
<br />
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/89-Beginning-Scala-is-available-on-APress-Alpha.html" rel="alternate" title="Beginning Scala is available on APress Alpha" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-01-28T16:46:13Z</published>
        <updated>2009-01-30T14:37:56Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=89</wfw:comment>
    
        <slash:comments>5</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=89</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/89-guid.html</id>
        <title type="html">Beginning Scala is available on APress Alpha</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Folks... more information on <i>Beginning Scala</i>, the Scala book I'm working on.  It's available for pre-order from APress's web site.  Additionally, draft PDFs are
available via <a href="http://www.apress.com/book/view/1430219890">APress's Alpha</a> program.
</p> <p>
For those who are wondering about the Table of Contents, here it is:
<ol>
<li>About Scala and how to install it</li>
<li> Scala syntax, scripts and the command line</li>
<li>Collections and the joys of immutability</li>
<li>Fun with Functions and never having to close that JDBC connection</li>
<li>Pattern matching and getting rid of unwanted visitor patterns</li>
<li>Actors and concurrency</li>
<li>Traits and Types, gnarly stuff for architects</li>
<li>Parsers because BNF is not just for academics anymore</li>
<li>Scaling your team and your systems</li>
</ol>
</p>

<p>I look forward to your feedback on the book!</p>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/88-Announcing-Beginning-Scala.html" rel="alternate" title="Announcing Beginning Scala" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-01-20T19:32:39Z</published>
        <updated>2009-01-21T19:56:36Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=88</wfw:comment>
    
        <slash:comments>8</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=88</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/88-guid.html</id>
        <title type="html">Announcing Beginning Scala</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                I am very excited to announce that I am writing <span
 style="font-style: italic;">Beginning Scala</span> and
it will be published by APress.<br />
 <br />
You may be asking, "Why is David, the <a href="http://liftweb.net">Lift</a>
guy, writing a Scala book?"<br />
<br />
First... let's talk about <a href="http://apress.com">APress</a>.<br />
<br />
I've been a long-time fan of APress. &#160;It's a great tech
publishing house. &#160;<a
 href="http://ablog.apress.com/?author=4">Gary</a> <a
 href="http://www.amazon.com/s?ie=UTF8&amp;search-type=ss&amp;index=books&amp;field-author=Gary%20Cornell&amp;page=1">Cornell</a>
founded APress after a less than optimal experience with other
publishers. &#160;He fashioned APress into an author's publisher
and has attracked and published some pretty amazing talent and great
books over the years.<br />
<br />
Despite that Gary is no longer at APress day-to-day, his legacy and
vision lives on. &#160;When <a
 href="http://ablog.apress.com/?author=5">Steve Anglin</a>
approached me to write a Lift book, I was initially hesitant.
&#160;I've had sub-optimal writing experiences in the past.
&#160;I've talked to most of the tech publishers about a Lift book.
&#160;But, Steve went a couple of extra miles in the process.
&#160;He found a co-author (which it turns out I didn't need.)
&#160;He spent time discussing the book market with me.
&#160;He convinced me that Gary's vision was still alive and well
at APress. &#160;APress had the environment that I wanted to work
in.<br />
<br />
Steve worked with me to put together an outline and a proposal for a
Lift book. &#160;However, the publishers thought that the market is
not yet ripe for a Lift book. &#160;So, Steve proposed that I do a
Scala book. &#160;Once again, Steve worked with me to put together
an outline and proposal. &#160;The Scala proposal was accepted (woo
hoo!)<br />
<br />
I started work in mid-December for a January 5th deadline for the first
three chapters. &#160;I slipped the deadline by a week or so
(writing during the holidays, especially when our nanny was out on
maternity leave, is something of a challenge.)<br />
<br />
The book will be 9 chapters and it will mostly cover Scala basics.
&#160;I'm focusing a lot on the joys of immutability and how the
mind-shift to immutability, function passing, and small blocks of code
can make composing large scale and defect-reduced programs super-simple.<br />
<br />
The book will not be "open source." &#160;It may be available as an
early access PDF from APress's site. &#160;We're targetting a
publication date at JavaOne. &#160;Maybe APress will even throw a
party at JavaOne.<br />
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/87-Lift-0.10-is-released.html" rel="alternate" title="Lift 0.10 is released" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2009-01-16T03:43:35Z</published>
        <updated>2009-01-18T20:34:20Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=87</wfw:comment>
    
        <slash:comments>2</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=87</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/87-guid.html</id>
        <title type="html">Lift 0.10 is released</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>Folks,
<br />
</p>
<p>After many months of "breaking changes", the Lift
team is proud to announce <br />
Lift 0.10. &#160;Lift 0.10 has frozen APIs and barring any material
problems, the <br />
0.10 APIs will be the same as the upcoming 1.0 APIs. &#160;We're
planning to <br />
release 1.0 at the end of February. <br />
</p> <span>
<p>Lift is an expressive and elegant framework for
writing web <br />
applications. Lift stresses the importance of security,
maintainability, <br />
scalability and performance while allowing for high levels of developer
<br />
productivity. Lift is a Scala web framework. <br />
</p>
<p>Over the next 6 weeks, the Lift team will be
focusing effort on cleaning up <br />
some Lift internals, improving performance, improving documentation,
and a <br />
new Lift web site. <br />
There are a ton of people who have contributed to Lift over the last
two <br />
years by writing code, by writing documentation, by asking questions,
by <br />
building Lift-based apps, and by participating in the Lift community.
&#160;I <br />
would like to extend special thanks to some folks who have made Lift
0.10 <br />
both possible and awesome: <br />
</p>
<p>&#160; &#160;- Marius... he's an awesome
developer who has amazing vision and <br />
&#160; &#160;understanding of what Lift is and should be.
&#160;If I got hit by a bus, Marius <br />
&#160; &#160;could continue to drive the Lift code base
forward. <br />
&#160; &#160;- DavidB provides great structure and process to
Lift. &#160;He runs the <br />
&#160; &#160;scala-tools.org site and keeps all the
dependencies and pieces of Lift <br />
&#160; &#160;and the greater Scala/Maven ecosystem humming. <br />
&#160; &#160;- Jorge's calm, deliberative way helps bring the
needs of all users into <br />
&#160; &#160;perspective. <br />
&#160; &#160;- Derek's JPA contributions have moved Lift into a
place where it can <br />
&#160; &#160;play in non-greenfield apps. <br />
&#160; &#160;- Tyler's energy is infectious. <br />
&#160; &#160;- Tim's energy is properly infectious. <br />
&#160; &#160;- Derek, Marius, and Tyler have conspired to
deliver some excellent Lift <br />
&#160; &#160;bookage for those who can convert LyX to PDF. <br />
&#160; &#160;- Charles who delivers apps and asks questions. <br />
&#160; &#160;- Debby who is bringing her legendary cat-herding
skills to the Lift <br />
&#160; &#160;committers. <br />
</p>
<p>So, as we spirit Lift through the final part of
the beta process, thank you <br />
all for participating in the community. <br />
</p>
<p>Changes in this version include: <br />
</p>
<p>New features: <br />
o A Currency class <br />
o Added a nifty mechanism for stateful form management (Hoot) <br />
o Added fix CSS support <br />
o Added support for other JS libraries <br />
o Added JSON forms support <br />
o Added PayPal Integration module <br />
</p>
<p>Changes: <br />
o Consolidate LiftRules <br />
o Added HTTP authentication support <br />
o Upgrade to Scala 2.7.3 <br />
o Upgrade to Scalacheck 1.5 <br />
o Upgrade to Specs 1.4.0 <br />
o Added Record/Field generic support <br />
o Changed Can to Box <br />
o Changed RequestState to Req <br />
o Updated LiftView to be more syntactically pleasing <br />
o Fixed a bug with how RequestVars and traits work <br />
o Enhanced the DateTime inputs <br />
o First pass at complete PayPal ITN and PDT stuff <br />
o Refactoring of the PayPal stuff <br />
o Updated to jQuery 1.2.6 <br />
o Redesigned Gavatar widget <br />
</p>
<p>Thanks, <br />
</p>
<p>David <br />
</p>
</span>
 
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/86-Ubuntu-released-8.10-knowing-there-was-a-nasty-defect.html" rel="alternate" title="Ubuntu released 8.10 knowing there was a nasty defect" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2008-11-30T04:29:29Z</published>
        <updated>2008-12-01T05:13:12Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=86</wfw:comment>
    
        <slash:comments>2</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=86</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/1-Business" label="Business" term="Business" />
    
        <id>http://blog.lostlake.org/index.php?/archives/86-guid.html</id>
        <title type="html">Ubuntu released 8.10 knowing there was a nasty defect</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>I had a rant about Ubuntu 8.10 being a buggy release.  Turns out that the Canonical people <a href='https://bugs.launchpad.net/ubuntu/+bug/276990'><b>knew</b> about the defect</a> and release Intrepid <i>anyway</i>.  
The problem impacts about 10% of modern laptops... ones with the most common Intel WiFi chipset.  The defect has not been fixed.  The workaround doesn't work.
What are these people thinking?</p>
  
            </div>
        </content>
        
    </entry>
    <entry>
        <link href="http://blog.lostlake.org/index.php?/archives/85-Thanks.html" rel="alternate" title="Thanks" />
        <author>
            <name>David Pollak</name>
                    </author>
    
        <published>2008-11-26T18:36:42Z</published>
        <updated>2008-12-01T05:13:07Z</updated>
        <wfw:comment>http://blog.lostlake.org/wfwcomment.php?cid=85</wfw:comment>
    
        <slash:comments>1</slash:comments>
        <wfw:commentRss>http://blog.lostlake.org/rss.php?version=atom1.0&amp;type=comments&amp;cid=85</wfw:commentRss>
    
            <category scheme="http://blog.lostlake.org/index.php?/categories/5-Scala" label="Scala" term="Scala" />
    
        <id>http://blog.lostlake.org/index.php?/archives/85-guid.html</id>
        <title type="html">Thanks</title>
        <content type="xhtml" xml:base="http://blog.lostlake.org/">
            <div xmlns="http://www.w3.org/1999/xhtml">
                <p>I've got lots of things to be Thankful for in my business life
this year.</p>
<ul>
  <li>The Lift community hit 700 people today. &#160;It's a
strong, vibrant, growing community full of smart and caring people.</li>
  <li>The Lift committers are awesome to hang with... they're so
smart and driven... and they do awesome care and feeding of the Lift
community.</li>
  <li>Scala and Lift are joys to work with. &#160;Scala is
such awesome technology and I love building cool software with it.</li>
  <li>The first Lift Workshop was great. &#160;The folks who
came asked awesome questions helped me understand how other people use
Lift.</li>
  <li>Working with Dan, Luke, Kaliya and Jorge is a real joy.
&#160;They're stellar and I learn so much from them.</li>
  <li>Jack and Alex gave me an opportunity earlier this year...
it was great working with them... and it was cool to work with an
excellent CEO.</li>
  <li>The ESME team is a wild thing to be involved with... and
I've learned more about SAP than I could have imagined.</li>
  <li>It's cool working with John on the book... he lends a lot
of balance... and Steve's a great editor, continuing in the APress
tradition.</li>
</ul>
<p>I hope you have an awesome Thanksgiving and holiday season.</p>
<p>Thanks!</p>
<p>David</p>
  
            </div>
        </content>
        
    </entry>

</feed>