Tuesday, 24 November 2009

More about Java Closures

Surprize, surprize! Hear, hear!
One year ago, Mark Reinhold, Principal Engineer at Sun Microsystems, announced At the Devoxx conference in Antwerp, Belgium that the next major release of Java, JDK 7, would not include closures. At the same conference this year, however, Reinhold announced in a surprise turn around the Java would be getting closures after all in JDK 7.*

More specifically, they adopt the BGGA proposal (look here) but without the non-local return (look here) and control invocation statements. This leaves Java without any destructor or C# style using statements support!

What can I say? I can only reinstate what I said in my previous post: comparing to the development of the C# language (look here ** for an interesting inteview about LINQ and its supporting language features) the Java language looks increasingly mouldy (ouch!!!).

But maybe I'm mistaken? maybe there will be some support for modern ressource management in Java but it's decoupled from the closure proposal? Let's hope so.

Update: well, I didn't hope in vain, there will be a feature for this: Automatic Ressource Management (see here)!!! Moreover, we'll got a little bit of type inference for the right hand generic expressions with new (as Google Collections provides it) with a "diamond" operator (?) <>, and strings in the switch statement (as in Groovy). All in all you cannot complain, I'd say, and some bloggers (ehm...) shouldn't be too quick to bash Java 7!

--
* I found the news here: http://www.artima.com/forums/flat.jsp?forum=276&thread=274496
** http://www.infoq.com/interviews/LINQ-Erik-Meijer, BTW I found an interesting quote of general interest there:

Actually, if you look at where I'm going, I'm getting more and more into old school object orientation with interfaces and so on, going away from functional programming. If you are passing a high order function you are passing one thing, one closure. If you're passing an interface or a class, you are passing many because you are passing a whole V table. These can all be recursive and so on. I'm rediscovering object oriented programming and I feel that maybe I wasted some of my time doing functional programming and missed out on objects.

You see, it's not only the functional programminch which is gonna be the Big Next Thing! I think that we cannot just condemn OO and go all for the functional. OO has its merits when structuring code, and a hybrid OO/functional approach seems to be a good thing to me!

Wednesday, 11 November 2009

Songs in code

Won't explain what they are, because it's obvious. These two made me laugh:

Bob Marley's (and Groovy's):
  4.times{
!woman == !cry
}
and REM's (and SQL's):
  DROP TABLE MyReligion
but normally they are boring, uninspired or plainly wrong, like this one:
  while(young)
{} // loops forever
Come on, the whole thing is that young is a volatile variable, which will somehow, sometimes be set to false! ;-)

Friday, 30 October 2009

Java's Closures Debate for C++ Eyes


Years ago Sun described Microsoft's delegate extension proposal for Java as:

Many of the advantages claimed for Visual J++ delegates -- type safety, object orientation, and ease of component interconnection -- are simply consequences of the security or flexibility of the Java object model.
....
Bound method references are simply unnecessary. They are not part of the Java programming language, and are thus not accepted by compliant compilers. Moreover, they detract from the simplicity and unity of the Java language.*

blah, blah, blah, marketing drivel! I don't know what is more annoying here: 1. the object-oriented orthodoxy, or 2. the complacency that "we know it all better! Be that as it may, but now James Gosling (Mr Java himself) says he'd always wanted closures instead of anonymous inner classes in Java, and there is not one, but whole 3 (!!!) proposals how to include functions as first class citiciens of the Java language! So much for the "simply unnessary" argument...

And there is considerable controversy around the very idea of closures, somehow similiar to the C++ debate around Concepts we discuseed recently, deeming it unnecessary and "too complicated". As we are lucky to get lambda functions in C++0x and don't complain the least, the debate in Java community made me curious. Come on, why not to have closures? Even C# has some!

So what is a closure? For the sake of this blog entry it is something like a lambda function in C++ (or Python or Groovy), i.e. an anonymous, freestanding function:

  auto print = [] (int x) { cout << x; }
Now let's do it in Java.

1. Proposals

So let's have a look at the three proposals.**

a) BGGA (Bracha, Gafter, Gosling, Ahé)

This is the most ambitious proposal. It introduces a new type into the language: a function type, and a totally new notation for it. This notation remainds me of Haskell's or of the lambda calculus types.

{T => U} for a function from T to U
{T => U => V} (or is it {T,U => V}?) for a function from T and U to V
I think this notation is one of the purposes why many in the Javaland doesn't like this proposal a bit. The second one will be surely the nonlocal control statements (returns, breaks etc). Come again, non-what? Well, it means that for example the return statement doesn't return from the closure but from the scope which invoked the closure! They don't bind to the closure but to the environment! Why should that be good for? Wait till next section for expanation, dear reader.

An usage example:
  {Integer => void} print = { Integer x => System.out.println(x); }
b) CICE (Concise Instance Creation Expressions)

This is the simplest of the three proposals. Basically it's only a syntactic sugar for defining anonymous classes on the run, nothing more. No first class functions! No obscure functional programming theory!

An usage example:
  public interface IPrint { public void invoke(Integer x);} // exacltly 1 method!
IPrint print = IPrint(Integer x) { System.out.println(x); }
It's the simplest of the proposals, but for my mind, the most annoying one: you have always to refer back to some interface definition, and it sucks!

c) FCM (First Class Methods)

This is a kind of middle ground between the previous two: it introduces first class functions, but doesen't have the nonlocal binding for closures return statement and the irritatinmg lambda-type notation.

An usage example:
  #(void(Integer)) print = #(Integer x) { System.out.println(x); }
From all the three syntactically I like the BGGA proposal the best, as you can just write your code in a familiar code-block manner, without the FCM's hash or CICE's interface tag.

2. The Debate

To put it mildly, sometimes I find the debate somehow childish. Here the typical arguments:***

pro: If the don't implement closures, I'll never code any line of Java an will go to Scala
con: If they implement the closures, I'll just break down and cry... I cannot change to any other language, but I'll hate you all for that!
Come on people! It's just a language feature! And you don't have to use it at all if you don't like it. Beside this, it's not the developers that choose languages, it's the managers! If they can be convinced that a language offers some substantial benefits, it will be adopted. But not because you like Scala or something else better!

Will the closures make Java too complicated? Would they really

"...complicate the language beyond normal usability: mainstream programmers will turn away from Java, so the argument goes, and move on to simpler programming languages
...
Java will turn into a guru language used only by experts in niche areas
"**?

So tell me which the simpler languages for the JVM are! I can see none (nonscripting one) which would be simpler. Guru language? Are you kidding me? The closures are an attempt to make Java less verbose, so everyone should be happy. So why the fear?

One (non PC) answer might be, that the "too complicated" camp is perfectly happy with the language as it is now, doesn't mind the lack of elegance, and don't want learn new mechanisms. And maybe there is some point where there are to much mechanisms (or paradigms) in the language? Me, as a C++ guy, I'm accustomed to the "multiparadigm design", as C++ is a real behemot in that respect. I just try not to think about the mechanisms I'm not using now.

Maybe in Javaland this isn't so simple, as the programmers were lectured for years that there is only one paradigm in the world: the object oriented one. This would explain why some people think that the addition of generics stressed the complexity of language to the limits (the other explanation is the design choices for backward compatibility, in particular the wildcards).
So it seems to be either the the irritation caused the generics or the unusual nonlocal returns in BGGA which provoked the strong feelings, dont you think?

3. Discussion


But let's get more technical: why do we need closures in Java? The answer is probably: because Ruby has got it! The Java community seems still to be in a collective Ruby trauma, and emulating Ruby features is a good enough reason in itself. As they used to say behind the Iron Curtain: to learn form Ruby is to learn how to win! So now, just as in Ruby (or Groovy and C# for that count) we'll be able to write in Java:

  Utils.forEach(names, { Integer x => System.out.println(x); }); // BGGA

So, that's kind what we've always had in C++ with STL and lambda libraries.

But that's not all there is! In each of the three above proposals there is a second part, which allows some kind of finer-grained resource management, i.e. a kind of "destructors for the modern times". I can only say "finally", because Java's resource management is just a big pain in the rear.

BGGA tries to achieve this goal by nonlocal control statements mentioned above, which will then allow to implement the "execute around" pattern as so called "control abstractions"** , but are somehow not very intuitive. In the BGGA proposal the keyword this will be lexically bound and will automatically refer to an instance of the enclosing type in which the closure is defined. For me, Groovy solves the problem of nonlocal bindings somehow clearer - introducing two members for a closure: owner (refering to the enclosing object) and delegate (defining the lexical binding). In tis way wee can always explicitely say what type of lexical binding we need, the default value of delegate being owner!

The other proposals try to address the same question as well: CICE by ARM (Automatic Resource Management Blocks - a special type of block where a dispose method will be automatically applied when leaving it) and FCM by JCA (Java Control Abstractions - this one is more like the "execute around" pattern mentioned above, and requires nonlocal lexical bindings as BGGA does).

At this point let us try to draw some conclusions.

Firstly: with C# having the lambdas in its 3.0 version****, and C++0x having lambdas and the auto specifier, leaving closures out of Java 7 would let Java looking pretty old in comparison!

But don't despair, there is a library solution out there (http://code.google.com/p/lambdaj/). Maybe a library solution will be suffiecient in this case? I don't know, the syntax doesn't look very intuitive, but it's probably the best you can get.

Secondly: what I find the most instructive lesson here is however, that we can see that the old notion of destructor isn't so old-fashioned after all! C# has meanwhile its using statement and Java deserves (and needs) some destructor-like mechanism as well! So much for the (former) "modern languages".

--
* form SUN's rebuttal of delegates - http://java.sun.com/docs/white/delegates.html, where they claim that delegates (i.e. C# equivalent of C++ member function pointers) are bad, because the anonymous classes can do all the same ans are object oriented too! A typical case ob the object-craze of the nineties IMHO

** I will only skim the surface here, as my aim is only the look-and-feel. If you need more information a good place to start is: http://www.javaworld.com/javaworld/jw-06-2008/jw-06-closures.html ("Understanding the closures debate - Does Java need closures? Three proposals compared", by Klaus Kreft and Angelika Langer, JavaWorld.com, 06/17/08)

*** rephrased ;-U from the discussion here - http://infinitescale.blogspot.com/2007/12/bgga-closures-end-of-many-java-careers.html, but seen in that form on other places in the Web

**** Let us digress a little: in C# we'd define the above lambda like that:

  Function<int, void> p = name => Console.WriteLine(name);
or use it directly like that:
  names.FindAll(name => name != "Marek")
.ForEach(name => Console.WriteLine(name));

Note that in C++ the lambdas aren't templates (they are monomorphic, i.e. we must define the argument types) but in C# they are! To achieve the same in C++ you have to use a template lambda library.

I mean the C# language is looking increasingly cool, perhaps I should learn it, as everybody can program Java these days???

Thursday, 27 August 2009

Tony Hoare and the meaning of life (well, almost...)

You know, I was always wondering about programming - is it an art, a craft, or is it an engineering discipline? Some crazy hackers maintain it be an art, more down-to-earth types oscillate between craft and engineering.

My personal feeling was that it couldn't be engineering - I missed the scientific part of it, it was too "soft". For me software engineering appeared rather to be a set of rules of thumb for organizing our mental work (functions, classes, modules...), something from the realm of cognitive science perhaps :-). For example I couldn't take my multithreading program and prove it not to deadlock in a future (i.e not yet written, but planned) installment of this blog...

1. The presentation

And then, some months ago, I came across that presentation* given on QCon 2009 Conference by Sir C.A.R. Hoare (aka Tony Hoare of the Hoare logic, Quicksort, and CSP fame) about relationships between programming and computer science.

Computer Science is about how programs run and how correct programs can be constructed *
By the way, I used to dislike the all-present video presentations, which seem to be replacing the old-fashioned articles as programmer's information source of choice. Well, to put it frankly, I hated them! Instead of beeing able to quickly scoop the essentials and then read the article if it'd interest me, I'm now forced to hear for hours to some uninspiring presentations and often to some really horrible accents to boot, as to discover that in the end only the title of the video was interesting!

But on the other side, with the video presentations I'm no able to hear people like Linus Thorvald** and Tony Hoare in person, and it proved to be very rewarding to me in both cases. Watching Tony Hoare was a great pleasure - he's a wonderfully gentle and good humored old man, I'd say my idol of sorts. And as he's got his first degree in philosophy, so he's bound to have some interesting insights in the question at hand.

His answer is both simple and compelling (I'm rephrasing it here):
Software Engineering is an engineering discipline because it uses Computer Science, and Computer Science is a science because its results are exploited and confirmed by software products!*
Sounds at first rather convincing, doesn't it? But wait, for a philosophy major, isn't he overlooking something?

2. Circulus Vitiosus?

Well, embarassingly, it's looking suspiciously similiar to a circular argument , right? For SW Engineering gets justified by the CS but the CS is justified by SW Engineering? It certainly appeared like this to me at the first glance So let us have a closer look at it:

science is: "the systematic study of the structure and behaviour of the physical world, especially by watching, measuring and doing experiments, and the development of theories to describe the results of these activities "***
Does this apply here? Well, maybe, if for "physical world" we substitute the human-built things like hardware and binaries. But wait, don't we rather work with mental constructs instead (you know, languages, functions, classes)? Well, yes, but they are models, like math is a model in civil engineering. In the end it's all about how the binary runs!

engineering is: "to design and build something using scientific principles"***
This one seems to fit perfectly. So both parts of the argument are corrct, but it is a circular one? Let it translate it form English into the language of logic:
(CS usedIn SWEng => SWEng is Eng) and (CS usedIn SWEng => CS is Sc)
You see it's not really circular, as it's two separate propositions, and they are just rephrasing the two above definitions (check it!). Because science is defined as a special, rigorous kind of examination of the physical world, and engineering uses science when dealing with this world directly! But wait again, it's not said that we are allowed to use only scince in engineering, or ist it?

3. The Engineer an the Scientist

This leads us to another interesting aspect of that presentation, which was the comparison between science and engineering, and how they relate to each other. Somehow explaining the above realtionship (I must paraphrase again):

so it's first:
scientists are interested in pure truths, i.e. programs which doesn't have errors, while an engineer must compromise, i.e. live with programs that have got some errors,

and second:
scientists are interested in certainity, while an engineer lives in incertanity, must take risks and perform risk management,

and thus:
scientists should be women, engineers should be men (Yes, he really made this little joke:)

There are several other comparisions along these lines in the presentation, and furthermore, even a gradation between the two extremes like applied scientist or scientific engineer are introduced. So there is (almost) a continuum of positions between the two extremes of pure CS scientist an a common hacker.

And that fact harbors some kind of consolation, particularly if I'm in a very pedestrian project and must do the most boring things. Just remember, you can always move up the ladder, and use more science, more absolute truths, and thus (as the ancients believed) come in contact with more beauty. An that's maybe the ultimate "consolatio philosophiae“, or do you think this is an exaggeration on my part?

--
* all citations are not original but rephrased by yours truly, so if they are wrong it's my fault! Original source: Tony Hoare, "The Science of Computing and the Engineering of Software", QCon Conference, Jun 11, 2009 , London: http://www.infoq.com/presentations/tony-hoare-computing-engineering

** for example this presentation by Linus was fun: http://www.youtube.com/watch?v=4XpnKHJAok8&feature=player_embedded

*** the definitions are taken from "Cambridge Advanced Learner's Dictionary", as I was looking for simplicity: http://dictionary.cambridge.org/

Tuesday, 28 July 2009

Two C++ curiosities with a deeper meaning

Lately, I was quite surprised by two things in the realm of programming, both of them C++ related. The first one is the new attribute syntax for C++09*, which I curiously failed to notice in the new standard proposal as I first had a look at it.

1. The first one


What are attributes? No, they aren't class data members with a convenient access syntax in this case (like Groovy's attribute syntax - or was it Python?).

I personally only knew attributes as an ugly Microsoft Windows COM-specific hack, by virtue of which you can inject COM related information into C++ code. Look at this example:

  #define _ATL_ATTRIBUTES 1
#include <atlbase.h>
#include <atlcom.h>
#include <string.h>
#include <comdef.h>
  [module(name="test")];
  [ object, uuid("00000000-0000-0000-0000-000000000001"), library_block ]
__interface IFace
{
[ id(0) ] int int_data;
[ id(5) ] BSTR bstr_data;
};
  [ coclass, uuid("00000000-0000-0000-0000-000000000002") ]
class MyClass : public IFace
{
private:
int m_i;
BSTR m_bstr;
  public:
MyClass();
~MyClass()
    int get_int_data();
void put_int_data(int _i);
BSTR get_bstr_data();
void put_bstr_data(BSTR bstr);
};
Doesn't it send shivers down your spine? You might say I'm not consequent, because I just lashed out on excessive XML configuration files (here), but when presented with the alternative, I don't like it either! And now, there are annotations in Java too, doing a similiar thing... What I can say, I was growing up with the classical paradigm of the standalone programm using external functionality through libraries. But nowadays you don't program just for the machine or the OS, you program for same giant framework! Did you hear the phrase "programming by bulldozer"? And to my mind there's no satisfactory model of how to do this! For me both the configuration file madness and mixing code with meta information are both somehow unsatisfactory. Look at this example JBoss Seam action class:
  @Stateless@Name("manager")
public class ManagerAction implements Manager {
@In @Out private Person person;
@Out private List<Person> fans;
}
Well, what do you think, does it look OK? We have (nearly) POJOs here (i.e. no framework class derivation) which is the Holy Grail in Java programming lately, but the code is littered with annotations. To me they are no better than the old C++ event macros used in some very old Windows frameworks!

Now the question arises: is that a cognitive bias caused by the preceeding simple (and thus elegant) programming model? Remember, even Herb Sutter, when charged with the task of making .NET programming possible with C++, didn't embrace the traditional program + library model! He rather created a language extension, the C++/CLI langauge dialect. Maybe he was constrained to do so by his commision of getting Managed C++ up to speed, but on the other side, in the design paper he argued it's the natural way and compliant with the spirit of C++. Personally I didn't like this language extension a bit, opting for a carefully designed library or framework oriented solution, but maybe it's simply not possible???

Sorry, I digressed. So back to the subject!

The second species of attributes I knew were the Gnu attributes, looking like that:
  void kill(int) __attribute__((__noreturn__)); //GCC specific
but I never used them either, because I thought they were only of any use with som Gnu-specific langauge extensions, which is always avoided like the plague. And do you know how the new standard compliant attributes look like now? Look ("C++09 Working Draft n2798", 10.2008, Chap. 7.6.):
  class C
{
virtual void f [[final]] ();
};

It's a crossbred of Microsoft an Gnu annotations, isn't it? That's why everyone is happy, and why the syntax is really ugly. And do you know what? There are a fistful of annotations defined in the standard (but vendors are allowed to add new ones) and one of them is, you guess it, final! Could someone tell me why should this one be an annotation and not a keyword - is it supposed to be matter in specific environments? Or are we making the way clear for vendor specific language extension? So maybe the whole annotation thing is in there to placate the major vendors: Microsoft and Gnu? Because as I got it (correct me please if I'm wrong!) there isn't a mechanism to plug in an attribute processor as in Microsoft COM-attributes or Java's annotations, so the whole construct is aimed at the compiler writers.

Summing up: first, Java annotation syntax, as seen in the Seam example above, seems to be more pleasing to the eyes, and second, I didn't really grasp the need for standardized annotations, except for vendor's conveniency.

2. The second one

The second curious thing I stumbled upon is the removal of Concepts (or should say of the "Concepts" concept?) from the C++09 standard proposal. As I read**, it was the standard library where the Concepts were first removed from. Come again? As I had a look at the draft, all the std library chapters were strewn with concepts, every one of them in pretty blue (or was is green?) colour.

And wasn't the Concepts supposed to be the best thing since sliced bread? I mean not for me, as I had a look at it one, and didn't want to learn it (in patricular the whole concept_map stuff!!!), but for the compiler writers - they could at last avoid the horrendous error messages for type errors in the template instatiations. Beside of that, it was Bjarne's pet project, and I thought that all Bjarne's PhD and post-doc students were working at it!

And now, out of the blue, the whole feature was cancelled! So maybe there's a limit to the pushing of the type system? C++ is a relentless type-monster already, and sometimes programming it feel like writing a mathematical proof to me. Thus building another level of type definitions on top of the generic meta types is maybe too much of the good thing. But, OK, the idea is not to take out the "duck typing" altogether from the templates, but to strike a delicate balance: add an minimum of concept decalarations and get the best error messages and type security possible. Is that task simply to complicated and too big or is it only the current design of the mechanism which is flawed?

As Bjarne said in the paper which finally did the deathly blow to the Concepts***:

Concepts were meant to make generic programming easier as well as safer. It is part of a whole collection of features aimed at simplifying GP, together with template aliases, auto, decltype, lambdas, etc. However, "concepts" is a complex mechanism and its language-technical complexity seems to be leaking into user code. By "language-technical complexity" I mean complexity arising from the need of compiler/linker technology rather than complexity from the solution to a problem itself (the algorithm).

My particular concern is that in the case of concept maps, in the name of safety we have made templates harder to use. We require programmers to name many entities that would better be left unnamed, cause excess rigidity in code and encourage a mindset in programmers that will lead to either a decrease in generic programming (in favor of less appropriate techniques) or to concepts not being used (where they would be useful). We have overreacted to the problems of structural typing. ***
This means that exaclty what I wasn't willing to learn leaked out into the user space! Bjarne made a series of proposals how to avoid it, but my general feeling after having read the paper was that the concept's design is somehow flawed, and cannot be fixed by some quick workarounds. So it's no wonder that the commitee had to make a tough decision. And that after years of work! And nobody have seen it coming all these years? Don't you think it's unacanny - how little we can do as to design a complicated language feature and to avoid mistakes? Or maybe we see here how badly the standardisation process is working. These problems were there for a much longer time and nobody said a word! Because of lack of time, because of politics, or simply because noone really understood that topic? So it had to be the creato of C++ himself to blow the whistle:

The use of concepts is supposed to help people write and use a wide range of templates. The current definition of concept maps and the philosophy that seems to go with them makes it harder.

Addressing this is important. I suspect that the alternative is widespread disuse of concepts and libraries using concepts. I would consider that a major failure of C++0x. ***

I'd say he killed his pet project out of sense of responsibility.

And where is the promised deeper meaning? As I said previously: there's maybe a limit to the type system. Because for me it felt sometimes like constructing inaccessible cardinals on top if the regular ones (wiki) in the set theory - just very, very subtle. And maybe the horrendous error messages for templates are just the proverbial price of the (type) freedom, and we have better to pay it? When you read Bjarne's article*** you see, that the gratest problems are encountered in sublassing and conversions - so C++ is much more "modern" a language than most of us would like to believe, as it allows us so much of the type freedom using the type system itself to achieve it!

And maybe the design problem relatively simple to solve, but the archaic linker technology we inherited from C is simply too old for that? As it reads:

"... complexity arising from the need of compiler/linker technology rather than complexity from the solution to a problem itself (the algorithm)"***
---
* Danny Kalev "Introducing Attributes", http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=440
** Danny Kalev "The Removal of Concepts From C++0x", http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=441
*** Bjarne Stroustrup "Simplifying the use of concepts", 2009-06-21, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2906.pdf

Saturday, 27 June 2009

For German Speakers only...

Hi everyone! As it comes, I stumbled recently upon an interesting C++ website, which I quite enjoyed, and even happened to learn something new in the process! Its address is:

http://www.kharchi.eu/wiki/doku.php?id=cpp:start

I particularly liked the coverage of some more modern topics liker my favourite theme of Web programming in C++, embedded C++ scripting, or the string tutorial covering conversions between different encodings (and not to forget the link to the Pirates Party :)). Don't get me wrong, it's not the uber C++ webpage, but it's a cute, interesting little thing!

Unfortunatlely it's all in German :-((. Good for me (see, learning languages pays off sometimes), bad luck for the rest of you. So if you're speaking German, have a look at it!

Speaking about languages, there's a little story as a goodie: on some project several years ago I had to update an open source tool for copying entire websites. It was thousands and thousands lines of plain, spaghetti-style C code. As this wouldn't be bad enough, all the comments that were there weren't in English, no, they were all in French!!! Hadn't I learnt some French for my holidays, I couldn't possibly have this assignment finished! Without comments the code was absolutely incomprehensible! However it worked fine, even if it wasn't any OO or structured programming thing. Why? For all we know it shouldn't ;-))).

Thursday, 28 May 2009

Windows not so bad after all?

This post is for my distinguished hacker colleague Stefan Z. Do you remember how we were always complaining that you cannot do any serious development on Windows, as the following standard Unix command line isn't posible?
    cat out.txt | grep ERROR
Well, as I'm doing Windows programming now, I recently found out that it's possible after all! Incredible but true! Hovever the syntax is somehow different:
    type out.txt | findstr ERROR
On things like that I see how fast the time is passing! A couple of years before, I'd never believe that Windows would ever catch on. I think, the tide change came with XP.

But wait, it comes even better! Here's a script for checking if a process is running and killing it if so:

   tasklist /FI "IMAGENAME eq myProcess.exe" | findstr myProcess.exe
if ERRORLEVEL 1 GOTO next

echo "-- kill running myProcess"
taskkill /F /IM myProcess.exe

next:
echo "-- starting the XXX process"
Even a sleep is possible (athough it's arguably very ugly):
    @ping 127.0.0.1 -n 2 -w 1000 > nul

And here (in the IT-Dojo) you can see that the Windows command promtp has some interesting history mechanisms!