There is a mathematical reality we cannot avoid, from which
special-case syntax and backwards-compatibility acrobatics cannot save
us.  The problem is in our thinking.  We didn't specify what depends
on what.  We thought we did, but it turns out we were fooling
ourselves all along.

The dependency graph is at root a clear and simple concept.  Defining
node relations is also clear and simple:

  task :a => :b

Child nodes are on the left, pointing to parent nodes on the right.
Task a depends on task b.  Clear.  Simple.  Now, are we certain that
we want to create a superstructure around this concept, and if so,
what exactly will it be?

Trans suggested that this

    task :a => [:x, :y, :z]

should be translated into this

    task :a => :z
    task :z => :y
    task :y => :x

while this

    task :a => [[:x, :y, :z]]

is translated into this

    task :a => :x
    task :a => :y
    task :a => :z

OK, but there are a million ways in which a programmer can
insufficiently define dependencies.  This will not come close to
saving us.  Let's take just one scenario from this example.

Nodes x,y,z are added *in that order* to the parent a (excuse me for
speaking in graph terms).  We can still be accidentally depending on
that.  The problem in our thinking is not solved.

Do we want

    task :a => :x
    task :a => :y
    task :a => :z

to be equivalent to

    task :a => :z
    task :a => :x
    task :a => :y

Yes or no?  If a programmer wants them to mean different things, how
shall we accommodate him?

Again I am taken back to the cold, hard, mathematical reality of the
graph.  We must think carefully about whether it actually represents
the necessary relations.  Nothing can do this for us, not tricks of
grammar or syntax, which may even obscure the relations.

There is already a historical precedent with Makefiles.  A new syntax
could have been added to Makefiles, but none was.  The Makefiles had
bugs, but instead of timidly skirting around the problems while
praising the gods of backwards compatibility, people faced them
head-on, solving them one at at time.  It is my hope that rubyists
will do the same.

While I endeavor to keep an open mind, I am not entirely convinced
that everyone clearly sees what the problem is (I am speaking of the
various conversations I've had about parallelism, not here
specifically).  The problem is not obvious at all.  It requires some
reflection.  I understand the value of backwards compatibility, which
is why drake==rake for -j1.  In this circumstance, however, it appears
to me that the answer is forced upon us by the sheer mathematics of
the situation.