Hi Steve,

On May 13, 2009, at 5:10 PM, Steve Appling wrote:

I'm still not sure that I understand the motivation to change from using createTask to the keyword style syntax. I think this looks less like normal groovy code (which makes it harder to initially understand). Perhaps I'm just ranting about DSLs in general, which are always a balance between convenience and ease of learning.

What distinguished those approaches is rather subtle. I can't provide any killer argument. But let's look at 0.5.2:

You create as task with createTask("name"). But you can access the task with name (unquoted). You could also argue the latter is not normal groovy code (and may be you do). The alternative would be to say task("name") or with 0.6 tasks.getByName("name"). But I think it is nice to access a task like a variable. It is not just convenient for the writer, it is also nicer and better to read. One major motivation for Adam to change the 0.5.2 behavior was the mismatch between using strings for creating task vs. the unquoted name for accessing them (Adam, please correct me if I'm wrong). And I think the new syntax is therefore more consistent and nicer (better) to read. It is kind of funny. Some people (the developers in any case :)) really like it. And we were almost surprised that not everybody liked this change. But we had our reasons for this and it was not just DSL hype :)

That said, if you are going to use a keyword style syntax, I would prefer a keyword to create a new task that looked more like a verb - perhaps createTask or newTask. I think the keyword task is confusingly close to the Project.task methods and Project.getTasks. If I was going to the javadoc to try to understand what methods in project were available to me, I would find this confusing.

We had a discussion a while back about the general approach for the DSL.

See: http://markmail.org/message/uiejxtpqwbsa74sc

Some experienced DSL writers recommended strongly to go for declarative vs. describing operations. And I agree with them. Again I think this is nicer and better to read.

The Project.task and getTasks method are replaced by the methods of the new tasks container (e.g. project.tasks.all/getByName/...). At least it is consistent to what we do in configurations/dependencies/ repositories.

There is already a method to add actions to a task. Why is the "<<" syntax needed? It just seems like more non-obvious magic. Could you not just use:
  task hello.doLast { stuff to do }

Now here I will use the normal groovy code argument :)

List list = []
list << 'String' // normal Groovy code

I think to use doLast you would have to use parentheses: task(hello).doLast { ... }

Another argument is: what are the major use cases? If I create a custom task, I just want to add an action and I don't care about doLast and doFirst. It is rather confusing in this context to use doLast and doFirst (and in fact doFirst and doLast has confused quite a few people at the beginning). Of course what we could do would be to provide an additional method do, which is equivalent to doLast. But then we would still have the parentheses problem.

I do like the idea of making more of a distinction between action closures and configuration closures. The 0.5.2 syntax was confusing initially.

I'm happy that there is at least one aspect which you like.

Many thanks for your feedback

- Hans



Hans Dockter wrote:
We plan to make another change to the Task DSL before we release 0.6.
At the moment the behavior that if you pass a closure to an existing task, the closure is used for configuring the task object. If you pass a closure to a task when creating a task, this closure is used as an action. The reason for this behavior is that we wanted to make Gradle behave as convenient as possible for the major use cases. If you create a simple task like HelloWorld, you usually don't want to configure it but want to add an action. And if you are accessing a task provided for example by the Java plugin, you usually want to configure it. The pay-off for this behavior, is that it can be a bit confusing at the beginning. And it is different from the normal Gradle behavior, which always uses closure assigned to objects for configuring them. The use case that made us change our mind about what is the best behavior, is when you don't create simple tasks but tasks of a custom type (e.g. Jar). In such a case you often want to configure the tasks when you create it (in contrast to simple tasks).
We plan therefore to change the DSL in the following way:
task hello << { <action> }
task hello { <configure> }
task myJar(type: Jar) { <configure> }
existingTask << { <action>} // equivalent to existingTask.doLast
existingTask { <configure> }
We were also thinking about using the work 'do' instead of <<. That would be nice to read. But this is not trivial to implement in Groovy. And the << operator is already used in Groovy for adding elements to a list, which is something similar to adding an action to a task.
Feedback is very welcome
- Hans
--
Hans Dockter
Gradle Project lead
http://www.gradle.org

--
Steve Appling
Automated Logic Research Team

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

  http://xircles.codehaus.org/manage_email



--
Hans Dockter
Gradle Project lead
http://www.gradle.org





---------------------------------------------------------------------
To unsubscribe from this list, please visit:

   http://xircles.codehaus.org/manage_email


Reply via email to