ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Ken Wood <kw...@i2.com>
Subject Re: What is a 'declarative' language [ was Re: [VOTE] vote on general direction ...]
Date Mon, 26 Mar 2001 23:23:26 GMT
Very nice points. I, too, have been somewhat puzzled
by the "can't have if-then-else" because Ant is declarative.

But, while I was only briefly exposed to Prolog, I remember
enough to understand the idea now that you bring it up. Another way of
phrasing this is that you are defining goals, and 'rules to
reach the goal'. So if one rule fires successfully, non
of the other rules ever need to fire. And if the first rule
failed to resolve a goal, the next rule is tried... and
thus, as you point out, branching.

There have been a few times, here and there, where
I really wanted to be able to branchb based on some
important criteria.... but I ended up not doing it,
or making a clumsy workaround - like multiple xml
files, and logic external to the files to decide
which to invoke...

And, lists would definitely be nice...

I ran into the need for lists recently when faced with this:

  a. build.xml defines a basic set of atomic operations
     to perform, and uses properties to determine where
     to get certain files, and where to put them.

  b. distribute.xml invokes various actions from 'build.xml'
     passing in values to the properties build.xml needs

distribute.xml is invoked from a batch file or command
line with the right -Dxxx=yyy args to pass the required
parameters to build.xml

Now, I wanted to have 'distribute.xml' check to
see if the 4 properties that SHOULD be defined
were in fact defined. If not, dipslay a message, otherwise
call the build.xml I wanted to do something like

  <target name="distribute" if="INSTALL_DIR,MEDIA,INSTALLER,ZIP_NAME">

     // do the work here by calling various build.xml targets

  </target>

But, I found that, as expected, 'if' only can deal with ONE property.
So, to do this I'd need a daisy chain of targets, each one checking
to see if ONE property existed, and if so, invoke the next target
that checked the next property, etc... Very hard to read, tedious to
write... so I gave up.


Bottom line - lists, iteration over lists, and branching 
would be nice, and can be done in a 'declarative' way.

Steve Loughran wrote:
> 
> >
> > The stuff I did find was about Prolog, so I'm in the process of reading it
> > all. I'll report back when I have something concrete and useful to add to
> > the discussion.
> 
> okay, I have to own up as to having done a fair bit of Prolog in the mid/lat
> eighties, first as an undergrad at Edinburgh Uni, later on in cube land when
> we still all thought that natural language and AI would solve everyone's
> problems. I've been avoiding joining in the discussion so far, as it was as
> amusing as watching VB programmers trying to explain the concept of
> 'inheritance' to each other, having nothing but VB as a common language.
> 
> Prolog is declarative. And it's a representation of logic (First order
> predicate calculus, horn clause subset). And it's a resolution process
> (depth first searching).
> 
> The resolution process is the key -in prolog, if a declaration proves false,
> the system backtracks to its last choice point and tries the next path
> 
> So you could have some declaration like (I think I've forgotten some of the
> syntax, but things starting with capital letters are variables which are
> bound to when needed.)
> 
> delivers :- builds, tests, deploys.
> 
> builds :- compiles([source,tests])
> 
> %% compile a file passing in a list of options
> compiles([H]) :- javac(H, flags([optimise(true)|debug(false)])).
> compiles([H|T]) :- compiles([H]),compiles(T).
> 
> tests :- junit(options).
> 
> deploys :- deploys-internal, deploys-staging.
> deploys:- failure-handler(deployment).
> 
> deploys-staging:- is-reachable("http:/staging/"),
> ftp-put("staging","./dist").
> deploys-staging:- echo("staging not reachable), fail.
> 
> deploys-internal:- is-reachable("http:/internal/"),
> ftp-put("internal","./dist").
> deploys-internal:- is-reachable("http:/internal:8080/"),
> ftp-put("internal","./dist").
> 
> failure-handler(Stage) :- page("my-pager",["failure in",Stage]);
> 
> So, this looks very like an ant build file, with build test and deploy
> targets. And the execution process is similar -we wont deploy unless the
> tests suceed. But look at the deployment process, where I have two targets
> (clauses) of the same name for deploys-staging. If anything goes wrong with
> the first one, the one where we upload stuff, the system backtracks to the
> last choice point -in this case the second clause. so it runs down there
> instead. And if deployment completely goes pear shaped I would get paged
> 
> So, here is a declarative language with decision making 'implicit in the
> code'
> 
> Then look at the compile task(s). There I am using list recursion as an
> alternative to direct iteration. So you can pass a list of sub-actions to
> 'compile' and it will do them one by one.
> 
> So even though it is declarative it still supports iteration -in a
> predictable order, and branching. And it also has a very wierd way of going
> wrong -where a single typo is enough to send the engine into reverse,
> backtracking and then heading off down some obscure path. That and the
> maintenance grief it could cause is why I am not proposing a Prolog like
> language as the build tool language. Where prolog would be good is in
> letting you specify the 'when things go wrong' process, but, outside of
> deployment, where can things go wrong that you can handle gracefully?
> 
> Actually the list based invocation is nice. We need more list aware
> languages :-)
> 
> -steve

Mime
View raw message