A few observations Re: Clean

rinus plasmeijer rinus@cs.kun.nl
Tue, 7 Apr 1998 00:25:23 +0200


Hi Adrian,

>To the Clean Team & world at large,
>
>For the last few weeks I've been trying out Clean on a Power Mac
>and I must say that overall I'm pretty impressed. The Clean team
>have obviously made a real effort to produce a package that meets
>the needs of 'real world' applications programmers, rather than
>simply being a research tool for academia. (It seems that you need
>a Computer Science degree just to install Haskell!!)

Thanks for the compliment!


>However, without wishing to appear unduly negative, I have noted
>down a few minor 'gripes' that I have and wonder what the Clean Team
>(or any other Clean users) might have to say about any of these issues.

We like to hear these things.

>Gripe 1 - List Expressions
>--------------------------
>Clean syntax for lists is a little awkward (and especially confusing
>for people who regularly use several different functional languages).
>e.g.
>  The expression [x:xs] is a list of lists in most functional languages
>  that I'm aware of.
>Couldn't the ':' be made to behave more like a normal operator, rather
>than being part of the punctuation of list expressions. This would make
>porting programs to Clean very much simpler and less confusing.

We decided many years ago that it would be nice to recognise list, records etc by their brackets. Any list expression can be spotted right away because it looks like [...].
You are right that the major disadvantage is that it is different from other languages and from that point of view not such a good decision.
For easy porting you can define your own infix Cons operator and simply change every ':' to this operator.

>Perhaps to retain compatibility with current Clean a pragma could be
>introduced to enable this feature for those who want it.

Why not.


>Gripe 2 - Memory Allocation
>---------------------------
>When compiling a program you have to specify how much heap space and
>stack space to use separately. The problem with this is how can you
>really know the best values. In most cases these will depend entirely
>on what data the program gets. It would help if just 1 value
>(total memory to use) was supplied and the run-time system made best
>possible use of this memory using stack-heap collision detection.
>(Or better still, if the OS allows, the application could just grab
>memory as required at run time. I suspect MacOS won't let you do this
>though, since even the latest versions of this supposedly wonderful OS
>don't seem to be able to sort out memory fragmentation without a
>shutdown.)

This is indeed the problem.

>Gripe 3 - Arity in Function Types
>---------------------------------
>The Clean system requires that the types assigned to functions aggree
>with the arity of the function definition. Why? I can't think of any
>reason the programmer should need to know a functions arity.

You are right. The reasons is that the compiler demands this (for reasons of efficiency) because it can't find it out when module boundaries are crossed.

>I appreciate that at the machine level implementation it is necessary to
>know how many arguments a 'graph-rewriting' routine actually requires,
>but surely this information could be generated automatically by the
>compiler and hidden away somewhere in the Clean System Files.

That indeed would be a solution. But this would slow down the compilation process because the additional information has to be read in.
For your information: I/O handling is one of the major botylenecks in the compilation process.

>This may seem a minor point, but it causes me real grief when I use
>synonyms for function types (as I often do). It would appear that
>whoever wrote the parser combinators detailed in chapter II.5 of the
>'Functional Programming in Clean' book had the same problem.

I agree that it would be nice if we could solve this problem.
It is small but annoying.



>Gripe 4 - Module System
>-----------------------
>I like the Clean style of Module interfaces (.dcl files) a lot.
>Its definitely preferable to the 'bag of names' approach used in Haskell,
>but do the interfaces really have to be in separate files. Having to
>maintain two files per module isn't too bad in GUI environment, but I
>guess most users would prefer to just work with one file or window per
>module. One of the main headaches with C is having to maintain all
>those wretched header files, now Clean requires us to do the same.
>Instead, couldn't each module have separate 'public' and 'private'
>sections in one file.

The module system will be different in the new 2.0 release.
We noticed that there are two kinds of use of definition modules:
for library modules (for which the dcl approach works fine) and for modules which together form a unit. For the latter your suggestion might be more appropriate.   

>(This isn't such a trivial point, many commercial companies operate a
>QA system that requires a whole load of paper work to be raised every
>time a source file changes. If both the .icl and .dcl files need
>changing then twice as much paper work needs to be raised.)
>
>Gripe 5 - No 'Ordering' primitives
>----------------------------------
>Clean provides the usual set relational operators, but doesn't have the
>equivalent of Haskell's Ordering comparison function for 'built in'
>types (which is very useful I think).

It is. Would be nice to have in version 2.0.

>If you want it you can define it thus..
>
>// Function to compare two Ord's
>cmpOrd :: a a -> Ordering | Ord a
>cmpOrd x y | x<y = LT
>           | x>y = GT
>                 = EQ
>
>but this may require two invocations of relational operators
>(1.5 on average I suppose), which may slow things down a little.
>
>Gripe 6 - Documentation
>-----------------------
>I have noticed that the currently appears to be very little
>supporting documentation for new language features and libraries.
>I know generating documents is awfully time consuming (I spend far more
>time doing this than actually writing software), but if you want Clean
>to be accepted for use in commercial environments high quality user
>documentation is essential.

We are working on that. Version 1.3 will have a revised reference manual.
Peter Achten is working on documentation for the new object I/O library. 

>Gripe 7 - No Acorn RiscOS port
>------------------------------
>Sorry, but I'm an Acorn fan. I know there's not many Acorn users in
>the world, but those that there are tend to be fairly computer literate
>(thats why they're Acorn users). I'm sure many of them would be happy
>to give Clean a try if it was available to them.

Yes, I understand. We simply do not have enough manpower.


>
>----------------------------- End Gripes -----------------------------
>But I'm not finished yet...
>I have couple suggestions for future Clean releases:
>
>1/ It would be really useful if the Clean IDE provided help with
>   'configuration control' for maintainance of large projects.
>   e.g. keep certain base line releases un-corrupted
>        provide a tool for keeping track of change records.
>   (This sort of thing is more or less mandated by QA these days).

I fully agree.


>2/ Provide a means for automatic generation of simple test harnesses
>   for individual modules. Perhaps by allowing the insertion of test
>   'assertions' which are simply boolean expressions which must
>   evalute to True. It would be fairly simple to convert the list
>   of assertions into a simple program which evaluates each expression
>   and reports any which turn out False. You could even get the IDE
>   to run the test harness each time a module is compiled.
>   (Again, this sort of thing is more or less mandated by QA these days
>    and doing it manually is a real chore).
>   P.S. I know Functional Programmers would prefer to 'prove' software
>   is ok using predicate calculus and structural induction or some such
>   thing, but I'm talking about the real world here :-)

All of your suggestions made sense.
We see what we can do.
First things first, i.e. the release of version 1.3 (comming out soon) and the work on version 2.0.

Thanks for your comments.

Rinus