Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Which language is for me?

7 views
Skip to first unread message

DvdAvins

unread,
Feb 10, 2001, 5:37:25 PM2/10/01
to
I'm planning to write a program for myself which, if I'm happy with the way it
turns out, I will likely distribute as shareware. I'm looking for as many of
the following traits as possible:

1:a functional language. I've been intrigued by functional languages for a
while, but have had no occasion to use them at work.
2: automatic garbage collection and other programmers' convenience features (I
still have to take care of my day job)
3: support for objects (not necessary, just a convenience)
4: it MUST be distributable as a stand-alone program for Windows. I'd like to
be able to distribute to Mac and Linux as well.

I'm investigating at M, Python, BETA, Scheme, Haskell, Icon, and Common Lisp.
Which would you use? Why?

DvdAvins

unread,
Feb 10, 2001, 5:41:52 PM2/10/01
to
And I forgot. There has to be either a good book in English and/or an IDE with
an excellent help system.

Basile STARYNKEVITCH

unread,
Feb 11, 2001, 2:35:35 AM2/11/01
to
>>>>> "DvdAvins" == DvdAvins <dvda...@aol.com> writes:

DvdAvins> I'm planning to write a program for myself which, if I'm
DvdAvins> happy with the way it turns out, I will likely
DvdAvins> distribute as shareware. I'm looking for as many of the
DvdAvins> following traits as possible:

Why shareware? Why don't you consider opensource (see
www.opensource.org)?

DvdAvins> 1:a functional language. I've been intrigued by
DvdAvins> functional languages for a while, but have had no
DvdAvins> occasion to use them at work. 2: automatic garbage
DvdAvins> collection and other programmers' convenience features
DvdAvins> (I still have to take care of my day job) 3: support for
DvdAvins> objects (not necessary, just a convenience) 4: it MUST
DvdAvins> be distributable as a stand-alone program for
DvdAvins> Windows.

You should definitely consider Ocaml http://www.ocaml.org/
--

Basile STARYNKEVITCH -- http://perso.wanadoo.fr/starynkevitch/basile/
email: basile dot starynkevitch at wanadoo dot fr (France)
alias: basile at tunes dot org host: http://lesours.dyndns.org/
8, rue de la Faïencerie, 92340 Bourg La Reine, phone: 1.46.65.45.53

Friedrich Dominicus

unread,
Feb 11, 2001, 3:17:01 AM2/11/01
to
dvda...@aol.com (DvdAvins) writes:

You may add OCAML to your list :). I personally am intrigued by the
flexibility of Common Lisp at the moment. Espcecially nice IDEs. I do
not know M but none of the other mentioned
languages come close to what the Common Lisp IDes offer. Anyway I do
think that a more modern FP languages is still worth considering. Most
of them have a nice Type system which some people think is a must.

Especially for Windows programming you might look at Corman Lisp.

Regards
Friedrich

Friedrich Dominicus

unread,
Feb 11, 2001, 3:17:43 AM2/11/01
to
dvda...@aol.com (DvdAvins) writes:

> And I forgot. There has to be either a good book in English and/or an IDE with
> an excellent help system.

Common LIsp ;-)
DrScheme

Regards
Friedrich

Hartmann Schaffer

unread,
Feb 11, 2001, 9:26:15 PM2/11/01
to
In article <8766ihv...@frown.here>, Friedrich Dominicus wrote:
> ...

>> 4: it MUST be distributable as a stand-alone program for Windows. I'd like to
>> be able to distribute to Mac and Linux as well.
> ...

>You may add OCAML to your list :). I personally am intrigued by the
>flexibility of Common Lisp at the moment. Espcecially nice IDEs. I do

common lisp probably violates requirement (4)

hs

Mark Carroll

unread,
Feb 11, 2001, 9:35:10 PM2/11/01
to
In article <slrn98ed...@paradise.nirvananet>,

Hartmann Schaffer <h...@paradise.nirvananet> wrote:
>> ...
>>> 4: it MUST be distributable as a stand-alone program for Windows. I'd like to
>>> be able to distribute to Mac and Linux as well.
>> ...
>>You may add OCAML to your list :). I personally am intrigued by the
>>flexibility of Common Lisp at the moment. Espcecially nice IDEs. I do
>
>common lisp probably violates requirement (4)

Not true - it's surprisingly well supported if you look into it.

-- Mark

siegfri...@kfunigraz.ac.at

unread,
Feb 12, 2001, 4:47:23 AM2/12/01
to
In article <8766ihv...@frown.here>,
Friedrich Dominicus <fr...@q-software-solutions.com> wrote:

>> I'm investigating at M, Python, BETA, Scheme, Haskell, Icon, and
>> Common Lisp.
>> Which would you use? Why?

>You may add OCAML to your list :).

But then he cannot distribute his program as Shareware for the
Macintosh.
OCAML may be nice but there are no possibilities to make a stand-alone
for the Mac.

> I personally am intrigued by the
>flexibility of Common Lisp at the moment.

I am not sure that with Common Lisp he will be able to distribute it
for the Mac and Linux. And the commercial Lisp development environement
for the Mac is very expensive.


With DrScheme (if he does not insist on a stand-alone exclusively) he
might be able to be platform independent.

But Clean is another good canditate for that task; here you can make
stand-alones for: Windows, Mac, Linux. But be aware the Graphical User
Interfaces are "Clean-typical".


On the other side I lost the believe in platform-independent programming
(and that functional programming is sooo superior). For a person alone
that is too time consuming. Someone especially a Shareware programmer
should concentrate on one platform alone.


Regards,
S. Gonzi
[If someone wants to program the Macintosh he should consider using
Mops. Mops is a mixture of Forth and the object oriented part is
Smalltalk (with the exception that late and early binding is possible).
Mops (AltiVec support) is up-to-date and freeware]


Sent via Deja.com
http://www.deja.com/

Friedrich Dominicus

unread,
Feb 13, 2001, 9:10:20 AM2/13/01
to
siegfri...@kfunigraz.ac.at writes:

>
>
> With DrScheme (if he does not insist on a stand-alone exclusively) he
> might be able to be platform independent.

According to the Help files one should be able to develop stand alone
programs (see Building a Stand-alone Executable) I did not tried it
myself but till now all the things I have used in DrScheme worked and
so I guess this will work too :)


>
> On the other side I lost the believe in platform-independent programming
> (and that functional programming is sooo superior).

This are IMHO quite different things so maybe you can say why you
don't think that FP is soo superior. I'm quite astonished over and
over again what FP adds to you toolbox. I feel that something is
misssing without FP.

Regards
Friedrich

Siegfried Gonzi

unread,
Feb 14, 2001, 8:56:36 AM2/14/01
to
Friedrich Dominicus schrieb in Nachricht <874rxyu...@frown.here>...

>> On the other side I lost the believe in platform-independent programming
>> (and that functional programming is sooo superior).
>This are IMHO quite different things so maybe you can say why you
>don't think that FP is soo superior.


As I first red the original posting "Want to make Shareware for different
platforms or so..." I remebered on my person. A year ago or so I was at the
same juduging position: How can I program a Shareware tool for different
platforms. That was only an idea of mine (I am not a programmer for my
living; so I had have the possibility to choose a language what I want).

Okay, lets see: C, C++ , no, everybody warns about that. Java, no, everybody
says Java is a crop. Oh nice, functional languages: Lisp, sorry too
expensive for the Mac; Python, sorry making a stand alone is somehow
difficult and is it really platform independent then?, Clean, huch, a good
candidate for beeing serious:

I read and read and see that they mean which Clean someone is much better
off in writing complex code. Caveats:

a) I am not ready to invest 10 years to become a little bit acquainted with
functional programming (there are so many language constructs) and can then
see that I maybe write a program in 1 day instead of 5 days with C/C++.
b) Garbage collection maybe nice but if someone wants to make some bigger
arrays he cannot do that with a functional language or he may pay a 100times
overhead.
bb) And does now really someone care about memory so he ends up with
"imperative style".

c) After a time it is impossible to follow a functional program. It is not
to live with a "black box"; often I want to follow what is going on; I set a
loop and know what is calculated; but in functional programming "pattern
thinking" is too hard.

d) Sometimes I think that is a joke if someone says: Shift to functional
programming and that is real an alternative to C. And then the C programmer
answers: Okay I will give it a try, but what about stand alones. The
functional guy: Oh, write your cute functional programming code and compile
it then to C. That is also the thread "Why functional programming will take
over the world...".
dd) Even Clean is written in C. Exercise:

Is it possible to write a so called "safe system" like Clean, with a "hell"
programming language like C. How can someone proof that? I am not a computer
scientist, so I cannot give that answer.

Wasn't it Goeddel who claims that you cannot for example proof (in your
system) that 3+3 is really 6.

ddd) Mathematica, Yorick are all written in C, but they play in another
league. I have no problem with that. Yorick is my tool which I use most
often.


I am now with Mops for that reason to learn object oriented programming.
Sure Forth is a matter of taste and it takes a time to become convinient
with the Reverse Polish Notation; even RPN is visible in the object oriented
part; for example I store a value to an array element:

VALUE I J TO: X

where TO: is the store method.


Regards,
S. Gonzi

Markus Mottl

unread,
Feb 14, 2001, 9:48:35 AM2/14/01
to
Siegfried Gonzi <siegfri...@kfunigraz.ac.at> wrote:
> I read and read and see that they mean which Clean someone is much better
> off in writing complex code. Caveats:

> a) I am not ready to invest 10 years to become a little bit acquainted with
> functional programming (there are so many language constructs) and can then
> see that I maybe write a program in 1 day instead of 5 days with C/C++.

One of our lecturers started his lecture on FPL showing us two books/folders:

"This", he said, "is the complete formal specification of SML, a
booklet of about 100 pages".

"This", he continued, "is the (informal) specification of a subset of
ADA" - which was a huge folder with about 5000 pages.

C++ is probably even worse than this. The specification of Haskell or Clean is
probably even more compact than the one of SML, because they are pure languages.

Can it be (to stay in the somewhat provocative tone that you take here)
that you were just afraid of learning something new? That you are not
really aware of the incredible amount of complexity that your brain
already manages when it has to generate C++-code?

> b) Garbage collection maybe nice but if someone wants to make some bigger
> arrays he cannot do that with a functional language or he may pay a 100times
> overhead.

Nonsense. The functional languages I know all perform well with huge
arrays. In OCaml, for example, you can have memory mapped arrays of
arbitrary size - you can even choose whether you want C- or Fortran-layout
for interoperability...

> bb) And does now really someone care about memory so he ends up with
> "imperative style".

Why do you (wrongly) assume this? Please elaborate...

> c) After a time it is impossible to follow a functional program.

Only if one is used to imperative programming solely. I find it more
difficult for imperative languages, although I have many years more
experience in them.

> It is not
> to live with a "black box"; often I want to follow what is going on; I set a
> loop and know what is calculated; but in functional programming "pattern
> thinking" is too hard.

For beginners in FPLs, yes, as in any kind of language paradigm. You did
not expect that you can use imperative patterns (which you already know)
in FPLs?

> d) Sometimes I think that is a joke if someone says: Shift to functional
> programming and that is real an alternative to C. And then the C programmer
> answers: Okay I will give it a try, but what about stand alones. The
> functional guy: Oh, write your cute functional programming code and compile
> it then to C. That is also the thread "Why functional programming will take
> over the world...".

Also not justified. OCaml, SML, Clean, Haskell (and probably others, too)
can all compile to native code directly. OCaml, for instance, supports
just about any architecture you can name (and some that you can't)...

> dd) Even Clean is written in C. Exercise:

No, the new release is rewritten in Clean itself. Of course, if you
want to bootstrap a compiler, you are forced to take an already existing
language with reasonable portability. C is the most widely-used language
in such cases. As any language that wants to be called universal, most
FPLs are rewritten in themselves as soon as a (minimum) version is
available in C.

> Is it possible to write a so called "safe system" like Clean, with a "hell"
> programming language like C.

There are surely plenty of bugs in the C-code.

> Wasn't it Goeddel who claims that you cannot for example proof (in your
> system) that 3+3 is really 6.

You mean Goedel, and he did not say that you cannot proof 3+3 = 6,
but that any system similar in power as arithmetics has true sentences
that cannot be proven. 3+3 = 6 does not seem to be such a sentence in
arithmetics as we know it.

Regards,
Markus Mottl

--
Markus Mottl, mo...@miss.wu-wien.ac.at, http://miss.wu-wien.ac.at/~mottl

Alexander V. Voinov

unread,
Feb 14, 2001, 1:02:29 PM2/14/01
to
Hi All,

Markus Mottl wrote:
> > a) I am not ready to invest 10 years to become a little bit acquainted with
> > functional programming (there are so many language constructs) and can then
> > see that I maybe write a program in 1 day instead of 5 days with C/C++.
>
> One of our lecturers started his lecture on FPL showing us two books/folders:
>
> "This", he said, "is the complete formal specification of SML, a
> booklet of about 100 pages".

Hm. What would a 'complete informal' be? :-)

>
> "This", he continued, "is the (informal) specification of a subset of
> ADA" - which was a huge folder with about 5000 pages.

Alexander

Anders Gidenstam

unread,
Feb 14, 2001, 1:37:31 PM2/14/01
to
In article <96e5s3$jrh$1...@bird.wu-wien.ac.at>,

Markus Mottl <mo...@miss.wu-wien.ac.at> writes:
> Siegfried Gonzi <siegfri...@kfunigraz.ac.at> wrote:
>> I read and read and see that they mean which Clean someone is much better
>> off in writing complex code. Caveats:
>
>> a) I am not ready to invest 10 years to become a little bit acquainted with
>> functional programming (there are so many language constructs) and can then
>> see that I maybe write a program in 1 day instead of 5 days with C/C++.
>
> One of our lecturers started his lecture on FPL showing us two books/folders:
>
> "This", he said, "is the complete formal specification of SML, a
> booklet of about 100 pages".
>
> "This", he continued, "is the (informal) specification of a subset of
> ADA" - which was a huge folder with about 5000 pages.

As a somewhat fanatic Ada supporter I cannot resist to respond to this.. =)
The Ada 95 Reference Manual and ISO standard is 503 pages, about half of
them is the annexes. And the Ada RM covers terrain where Clean programmers
(I think) dear not to tread, like real time systems and distributed systems..


Best Regards,

Anders Gidenstam
--
--------------------------------------------
"A well-written program is its own heaven;
a poorly-written program is its own hell."
- The Tao of Programming

Laurent Guerby

unread,
Feb 14, 2001, 1:48:19 PM2/14/01
to
Markus Mottl <mo...@miss.wu-wien.ac.at> writes:
> One of our lecturers started his lecture on FPL showing us two books/folders:
>
> "This", he said, "is the complete formal specification of SML, a
> booklet of about 100 pages".
>
> "This", he continued, "is the (informal) specification of a subset of
> ADA" - which was a huge folder with about 5000 pages.

The "informal" annotated Ada 95 Reference Manual is 500 pages with
half of it covering the libraries (IO, Numerics, ...), and some
examples. I don't know where the 5000 pages figure comes from ;-).

A "formal" subset of Ada is SPARK, its informal description is
probably less than 50 pages (I don't know about the formal one, but
shouldn't be that big). There is a book describing it (370 pages with
examples and lecture-type stuff):

High Integrity Ada: The SPARK Approach by John Barnes
Addison-Wesley; 1997; ISBN 0-201-17517-7

I hope your lecturer told you that you can have language with a 10
pages formal description, where any program is book long and completely
unreadable ;-).

--
Laurent Guerby <gue...@acm.org>

Anders Gidenstam

unread,
Feb 14, 2001, 3:16:28 PM2/14/01
to
In article <b9je69...@aragorn.hemma.kungalv.se>,

d96a...@dtek.chalmers.se (Anders Gidenstam) writes:
> As a somewhat fanatic Ada supporter I cannot resist to respond to this.. =)
> The Ada 95 Reference Manual and ISO standard is 503 pages, about half of
> them is the annexes. And the Ada RM covers terrain where Clean programmers
^^^^^
Ehrrm, I meant SML programmers... I don't know where I got Clean from.. ;-)

Markus Mottl

unread,
Feb 14, 2001, 4:47:45 PM2/14/01
to
Laurent Guerby <gue...@acm.org> wrote:
> The "informal" annotated Ada 95 Reference Manual is 500 pages with
> half of it covering the libraries (IO, Numerics, ...), and some
> examples. I don't know where the 5000 pages figure comes from ;-).

Well, the folders we saw (if I correctly remember it was even two of
them) definitely contained much more than 500 pages. Maybe it was the
attempt of a formal specification rather than an informal one (we did
not take a look inside - never trust your lecturers ;). I actually doubt
that the formal semantics of an imperative language the size of ADA fits
into only a few hundred pages (and to my knowledge, SML is still one of
the very few languages (maybe Scheme, too?) whose formal semantics is
completely specified).

> I hope your lecturer told you that you can have language with a 10
> pages formal description, where any program is book long and completely
> unreadable ;-).

I'd be very surprised to see people arguing that ADA programs tend to be
short and concise (it's verboseness is legend - no need to argue about
this). This does not mean that verboseness is necessarily a bad thing
if it improves readability.

Note that "formal" <> "formal": "formal" often means "standardized"
rather than "mathematically rigorous".

Ulf Wiger

unread,
Feb 15, 2001, 4:52:24 AM2/15/01
to
>>>>> ">" == Anders Gidenstam <d96a...@dtek.chalmers.se> writes:

>> "This", he continued, "is the (informal) specification of a
>> subset of ADA" - which was a huge folder with about 5000 pages.

>> As a somewhat fanatic Ada supporter I cannot resist to respond to
>> this.. =) The Ada 95 Reference Manual and ISO standard is 503
>> pages, about half of them is the annexes. And the Ada RM covers
>> terrain where Clean programmers (I think) dear not to tread, like
>> real time systems and distributed systems..

Hehe, The Erlang 4.7 specification (Draft) also covers real time
systems and distributed systems _and_ dynamic code loading;
it's 266 pages. ;-)

/Uffe
--
Ulf Wiger tfn: +46 8 719 81 95
Senior System Architect mob: +46 70 519 81 95
Strategic Product & System Management ATM Multiservice Networks
Data Backbone & Optical Services Division Ericsson Telecom AB

Julian Assange

unread,
Feb 15, 2001, 12:06:15 PM2/15/01
to
Markus Mottl <mo...@miss.wu-wien.ac.at> writes:

> Siegfried Gonzi <siegfri...@kfunigraz.ac.at> wrote:
> > I read and read and see that they mean which Clean someone is much better
> > off in writing complex code. Caveats:
>
> > a) I am not ready to invest 10 years to become a little bit acquainted with
> > functional programming (there are so many language constructs) and can then
> > see that I maybe write a program in 1 day instead of 5 days with C/C++.
>
> One of our lecturers started his lecture on FPL showing us two books/folders:
>
> "This", he said, "is the complete formal specification of SML, a
> booklet of about 100 pages".
>
> "This", he continued, "is the (informal) specification of a subset of
> ADA" - which was a huge folder with about 5000 pages.

This is good theatre, but not good truth. ADA documentation comes out
of the milspec community which appears to get paid by the page for its
standards. ADA specifies its operational semantics in a manner
detailed enough to leave nothing unspecified. You can write
flight-control code for nuclear tipped ICBM's under one ADA compiler
and have a degree of confidence that it will do exactly the same thing
on another.

--
Julian Assange |If you want to build a ship, don't drum up people
|together to collect wood or assign them tasks and
pr...@iq.org |work, but rather teach them to long for the endless
pr...@gnu.ai.mit.edu |immensity of the sea. -- Antoine de Saint Exupery

Brian Rogoff

unread,
Feb 15, 2001, 1:58:19 PM2/15/01
to
On 16 Feb 2001, Julian Assange wrote:

> Markus Mottl <mo...@miss.wu-wien.ac.at> writes:
> > One of our lecturers started his lecture on FPL showing us two books/folders:
> >
> > "This", he said, "is the complete formal specification of SML, a
> > booklet of about 100 pages".
> >
> > "This", he continued, "is the (informal) specification of a subset of
> > ADA" - which was a huge folder with about 5000 pages.
>
> This is good theatre, but not good truth. ADA documentation comes out
> of the milspec community which appears to get paid by the page for its
> standards. ADA specifies its operational semantics in a manner
> detailed enough to leave nothing unspecified.

This is also not the truth. I have a copy of ANSI/ISO/IEC-8652:1995
sitting right here at my elbow, and it certainly does leave some things
unspecified (and doesn't use an operational semantics description, if
that's what you're implying). For instance, see 6.2(11).

OTOH, the Ada 95 RM is actually useful to the average Ada programmer. Do
SML programmers use the formal spec a lot?

BTW, users spell it Ada not ADA, even though it's case insensitive (now is
it Ocaml or OCaml? :) and it isn't any more verbose than any other Wirth
descended language. And while Erlang 4.7 may have a shorter spec, I don't
think Erlang deals with real-time ("soft" RT? ha!) or systems programming
issues like Ada does (you can program at the C level in Ada).

-- Brian


Daniel C. Wang

unread,
Feb 15, 2001, 3:45:01 PM2/15/01
to

Brian Rogoff <b...@shell5.ba.best.com> writes:
{stuff deleted}

> OTOH, the Ada 95 RM is actually useful to the average Ada programmer. Do
> SML programmers use the formal spec a lot?

Yes... there's a big difference between a spec written for your average
programer and one written for someone who has been in school for too
long. Though the SML spec includes every little detail, and that sometimes
obscures the intuitions.

I think, every langauge should have two specs. First the one for compiler
writters so they can all agree about what is supposed to happen, and which
should be the one true definition of the language. This is what the SML spec
really is useful for. In fact the ML kit compiler is almost a one two one
translation of the formal definition of SML. An important property of the
"compiler spec" is that is should be smaller then the compiler source code.

The other spec should be for programmers, and it should be as larger and
ugly and informal is at likes. As long as those of us writting compilers
have the nice and concise one to read, I'm happy.

A more fair question to ask is how big is a conforming Ada frontend compared
to a decent SML frontend in terms of lines of code. That's a better measure
of language complexity.

Laurent Guerby

unread,
Feb 15, 2001, 4:31:27 PM2/15/01
to
Markus Mottl <mo...@miss.wu-wien.ac.at> writes:
> I'd be very surprised to see people arguing that ADA programs tend to be
> short and concise (it's verboseness is legend - no need to argue about
> this). This does not mean that verboseness is necessarily a bad thing
> if it improves readability.

I don't think I made my point clear: when a language specification is
short (wether formal, standard or informal), it just can be that the
language offer very small primitives, and writing a program with only
those (fully formally specified) primitives will be very tedious, and
will lead to an enormous amount of code (try programming with only S,
K and I ;-).

As for "legends", well they're just "legends" after all, not reality

Laurent Guerby

unread,
Feb 15, 2001, 4:44:49 PM2/15/01
to
"Daniel C. Wang" <danwan...@cs.princeton.edu> writes:
> A more fair question to ask is how big is a conforming Ada frontend compared
> to a decent SML frontend in terms of lines of code. That's a better measure
> of language complexity.

I don't think that's fair either (note that I'm not arguing that Ada
is simpler than SML, that's obviously false ;-). There can be a lot of
definition of "language complexity". Implementing a 6x4 turing machine
is trivial, but then is the resulting language "simple" (as opposed
to "complex") for the programmer?

Also Ada includes things to specify representation to the bit level,
this kind of thing can make programmer life much simpler, but makes
the standard longer and the job of implementors difficult. I don't
know the SML standard, but I guess this stuff is not even approached.

Robert Dewar <de...@gnat.com> wrote a few enlightening things on
comp.lang.ada, here is an excerpt:

<<
(**) One useful observation that I made during the Ada 95
language design effort was that everyone is in favor of
simplicity, and opposed to complexity, but in fact these
terms refer to lots of different things:

1. Simplicity in implementation

2. Simplicity in formal semantic description

3. Simplicity of learning for non-experts

4. Simplicity of resulting code in the language

5. Simplicity of informal (text book) description

The trouble is that these are now different criteria, which
often are in exact opposition. Here is an example.

Records are a simple concept

Arrays are a simple concept

It is useful to have records have fields of any type

It is useful to have arrays that have dynamic length

BUT, what about records that have fields that are dynamic
length arrays. Well of course you want to allow that from
the point of view of uniformity of description (and indeed
Ada takes that position). This also aids ease of use and
makes programs simpler. HOWEVER, it is a very nasty glitch
in the implementation, and certainly makes the implementation
more complex, why? because the simple paradigm of record
implementation (fixed offsets from a base address) breaks.

Now, of course we have taken what I think is the right decision
here in Ada to settle for added complexity of implementation
to simplify the use of the language, but you see from this
example that simplicity is not such a simple concept :-)

Robert Dewar
>>

--
Laurent Guerby <gue...@acm.org>

Daniel C. Wang

unread,
Feb 15, 2001, 5:55:15 PM2/15/01
to

Laurent Guerby <gue...@acm.org> writes:

> "Daniel C. Wang" <danwan...@cs.princeton.edu> writes:
> > A more fair question to ask is how big is a conforming Ada frontend compared
> > to a decent SML frontend in terms of lines of code. That's a better measure
> > of language complexity.
>
> I don't think that's fair either (note that I'm not arguing that Ada
> is simpler than SML, that's obviously false ;-). There can be a lot of
> definition of "language complexity". Implementing a 6x4 turing machine
> is trivial, but then is the resulting language "simple" (as opposed
> to "complex") for the programmer?

I'm simply trying to suggest a metric that gives you a feel for how much
stuff must be held in the head of our poor programmer to completely
understand the language. The size of the compiler *frontend* (i.e. parser
and type checker) is a good measure because the frontend is a completely
formal spec of the language. This is better than comparing english to
swiggly greek symbols.

I'm not clamming that simple to understand languages are necessarily easier
to program with.

> Also Ada includes things to specify representation to the bit level,
> this kind of thing can make programmer life much simpler, but makes
> the standard longer and the job of implementors difficult. I don't
> know the SML standard, but I guess this stuff is not even approached.

You are right they don't talk about it at all.

> Robert Dewar <de...@gnat.com> wrote a few enlightening things on
> comp.lang.ada, here is an excerpt:
>
> <<
> (**) One useful observation that I made during the Ada 95
> language design effort was that everyone is in favor of
> simplicity, and opposed to complexity, but in fact these
> terms refer to lots of different things:
>
> 1. Simplicity in implementation
>
> 2. Simplicity in formal semantic description
>
> 3. Simplicity of learning for non-experts
>
> 4. Simplicity of resulting code in the language
>
> 5. Simplicity of informal (text book) description
>
> The trouble is that these are now different criteria, which
> often are in exact opposition. Here is an example.

Yes.... these tradeoffs are quite a delicate thing to get right. SML does
well in 1 and 2. It doesn't do 4 as well as OCaml probably does. It's
okay with 5.

I have nothing against Ada, but a part of me feels like there is a smaller
language trying to get out. A more fair comparison would probably be between
Ada95 and Modula-3. The modula-3 spec although informal, is quiet concise.

Hartmann Schaffer

unread,
Feb 15, 2001, 6:24:07 PM2/15/01
to
In article <86wvar8...@acm.org>, Laurent Guerby wrote:
>"Daniel C. Wang" <danwan...@cs.princeton.edu> writes:
>> A more fair question to ask is how big is a conforming Ada frontend compared
>> to a decent SML frontend in terms of lines of code. That's a better measure
>> of language complexity.
>
>I don't think that's fair either (note that I'm not arguing that Ada
>is simpler than SML, that's obviously false ;-). There can be a lot of
>definition of "language complexity". Implementing a 6x4 turing machine
>is trivial, but then is the resulting language "simple" (as opposed
>to "complex") for the programmer?

why don't we settle the question once and for all: find volunteers (not
me) who rewrite both specs, each in exactly the same style of the other.
then compare all 4 specifications.

hs

Brian Rogoff

unread,
Feb 15, 2001, 8:49:20 PM2/15/01
to
On 15 Feb 2001, Daniel C. Wang wrote:
> Laurent Guerby <gue...@acm.org> writes:
>
> > "Daniel C. Wang" <danwan...@cs.princeton.edu> writes:
> > > A more fair question to ask is how big is a conforming Ada frontend compared
> > > to a decent SML frontend in terms of lines of code. That's a better measure
> > > of language complexity.

It's not acurate for more reasons than Laurent Guerby argues (if Ada is
syntactically more verbose than ML this will get reflected) but since you
ask we can use the Web to find

http://cs.nyu.edu/courses/spring01/G22.2130-001/gnatintro.html

which says

The front-end consists of over 400 K lines of Ada, distributed among 909
files. Gigi consists of 21 K lines of C in 30 files. The GCC back-end is more
than 500K lines of C, and includes code generators for most processors in use
today. The front-end and Gigi are fully machine-independent. The back-end
of GCC is completely language independent, and interestingly much of it is
machine-independent as well.

The front-end

The front-end of GNAT consists of the following traditional compiler
phases:

the lexical scanner.
the parser.
the semantic analyzer.
the expander.

etc...

From personal use, I can say that that is an exceptionally good compiler
w.r.t. error messages.

> > Also Ada includes things to specify representation to the bit level,
> > this kind of thing can make programmer life much simpler, but makes
> > the standard longer and the job of implementors difficult. I don't
> > know the SML standard, but I guess this stuff is not even approached.

This is one of the things I like most about Ada.

> I have nothing against Ada, but a part of me feels like there is a smaller
> language trying to get out. A more fair comparison would probably be between
> Ada95 and Modula-3. The modula-3 spec although informal, is quiet concise.

Well, I haven't used Modula-3, just read some of the docs, but I have to
say I like Ada's richer generics (BTW Appel's compiler book insinuates
wrongly that Ada doesn't do shared generics!) and I find M3's weak in
comparison. I also especially like languages with overloading, so
that's something I would miss too. I miss it in OCaml but I have some
hope that some kind of overloading will get added.

I wouldn't mind seeing a redesigned Ada either, but I'd prefer that it
kept the qualities that enable it to do what it does well. One big
separation between high and low level languages is in memory management,
and Ada is a low-level language. It's fine to run with a GC, but nothing
in Ada requires it the same way first class functions in ML do (region
based exceptions noted) nor should they.

-- Brian


Daniel C. Wang

unread,
Feb 15, 2001, 10:49:41 PM2/15/01
to

Brian Rogoff <b...@shell5.ba.best.com> writes:

{stuff deleted}


> The front-end of GNAT consists of the following traditional compiler
> phases:
>
> the lexical scanner.
> the parser.
> the semantic analyzer.
> the expander.
>
> etc...

As a datapoint the SML/NJ frontend is roughly 21k lines of code which
include the same stuff as above. Moscow ML is around 27k (which probably
includes some stuff I shouldn't be including.)

Others, can draw their own conclusions about language complexity.

George Russell

unread,
Feb 16, 2001, 6:21:35 AM2/16/01
to
"Daniel C. Wang" wrote:
[snip]

> I think, every langauge should have two specs. First the one for compiler
> writters so they can all agree about what is supposed to happen, and which
> should be the one true definition of the language. This is what the SML spec
> really is useful for. In fact the ML kit compiler is almost a one two one
> translation of the formal definition of SML. An important property of the
> "compiler spec" is that is should be smaller then the compiler source code.
[snip]
An old adage says "Where program and comment disagree, both are usually wrong."
The horn clauses in the ML specification, like the Haskell definitions of functions
in the Haskell library, are as far as I'm concerned program. The English-language
explanations are comment. I agree with Daniel C. Wang that we should have both.
However where they plainly disagree (and it should not be too hard to say when they
do; the English explanations should be written like a standard, not Finnigann's
Wake), the implementor should be at liberty to decide which of the two to follow.

I say this because there are going to be some cases where the English and not the
formal definition represent the intentions of the standard committee. For example
this happens in the current Haskell library standard. There are also a number of
things in the 1997 definition of standard ML which no-one implements because they're
ridiculous.

Siegfried Gonzi

unread,
Feb 16, 2001, 8:33:07 AM2/16/01
to
Markus Mottl schrieb in Nachricht <96e5s3$jrh$1...@bird.wu-wien.ac.at>...

>One of our lecturers started his lecture on FPL showing us two
books/folders:
>
> "This", he said, "is the complete formal specification of SML, a
> booklet of about 100 pages".
>
> "This", he continued, "is the (informal) specification of a subset of
> ADA" - which was a huge folder with about 5000 pages.

That is no a class of itself. Short doesn't mean good or better. The same
problem faces the Forth community. Forth specification itself is very short.
Sure I can write down a program with very few lines, but a year later I am
not able to read it any longer. Okay I could comment a lot, but is that the
sin of a "short" programming language?

>Can it be (to stay in the somewhat provocative tone that you take here)
>that you were just afraid of learning something new?

There are things which doesn't pay off...

> That you are not
>really aware of the incredible amount of complexity that your brain
>already manages when it has to generate C++-code?


That is no reason for functional programming.

>> b) Garbage collection maybe nice but if someone wants to make some bigger
>> arrays he cannot do that with a functional language or he may pay a
100times
>> overhead.
>
>Nonsense. The functional languages I know all perform well with huge
>arrays. In OCaml, for example, you can have memory mapped arrays of
>arbitrary size - you can even choose whether you want C- or Fortran-layout
>for interoperability...


No nonsense. A FFT (a normal FFT without tuned code) in Clean (okay the code
was not mine; but it used all the "tricks": if you are interested in I can
point you to that online manual which discusses that FFT code
implementation) with 2^18 array elements (one dimensional array) takes on my
100MHZ 603e Mac (with 256KB L2 and 64MB RAM) 120sec! And 60sec of that time
is due to garbage collection.

With Mops it takes 20sec (but even that is not optimal); 5 to 10 sec would
be optimal.


>> bb) And does now really someone care about memory so he ends up with
>> "imperative style".
>
>Why do you (wrongly) assume this? Please elaborate...

see above.

>Also not justified. OCaml, SML, Clean, Haskell (and probably others, too)
>can all compile to native code directly. OCaml, for instance, supports
>just about any architecture you can name (and some that you can't)...


I can't name Macintosh.

>> dd) Even Clean is written in C. Exercise:
>
>No, the new release is rewritten in Clean itself.

As far as I am informed is only the development environement written in
Clean. Clean kernel itself stayed unchanged in C.


Regards,
S. Gonzi

Ulf Wiger

unread,
Feb 16, 2001, 9:37:02 AM2/16/01
to
>>>>> "Brian" == Brian Rogoff <b...@shell5.ba.best.com> writes:

Brian> while Erlang 4.7 may have a shorter spec, I don't think
Brian> Erlang deals with real-time ("soft" RT? ha!)

Ah, you're being humorous. (:

Erlang does not address hard real-time because there hasn't been
a requirement to make an implementation that supports it.

Show me the language details that would prevent an Erlang
implementation for hard real-time. Erlang is based on communicating
processes with a distinct notion of time and preemptive scheduling.

Brian> or systems programming issues like Ada does (you can
Brian> program at the C level in Ada).

Yes, the everything-but-the-kitchen-sink approach tends to give
bloated specs. Wasn't this the point?

If an Erlang programmer wants to program at the C level, he uses C.

Markus Mottl

unread,
Feb 16, 2001, 9:58:35 AM2/16/01
to
Siegfried Gonzi <siegfri...@kfunigraz.ac.at> wrote:
> That is no a class of itself. Short doesn't mean good or better. The same
> problem faces the Forth community. Forth specification itself is very short.
> Sure I can write down a program with very few lines, but a year later I am
> not able to read it any longer. Okay I could comment a lot, but is that the
> sin of a "short" programming language?

Other things being equal (which they usually aren't), "short" is a "class
of itself" (using your words). Why should I use a language that needs a
significantly longer spec, but is only equally or even less expressive?
If Occam's razor were applied to programming languages, I don't think that
any mainstream (=imperative) languages would still exist afterwards...

>>Can it be (to stay in the somewhat provocative tone that you take here)
>>that you were just afraid of learning something new?

> There are things which doesn't pay off...

Can you name such things?

>> That you are not
>>really aware of the incredible amount of complexity that your brain
>>already manages when it has to generate C++-code?

> That is no reason for functional programming.

No? So it does not matter whether languages have a low degree of
complexity while being more expressive?

>>Nonsense. The functional languages I know all perform well with huge
>>arrays. In OCaml, for example, you can have memory mapped arrays of
>>arbitrary size - you can even choose whether you want C- or Fortran-layout
>>for interoperability...

> No nonsense. A FFT (a normal FFT without tuned code) in Clean (okay the code
> was not mine; but it used all the "tricks": if you are interested in I can
> point you to that online manual which discusses that FFT code
> implementation) with 2^18 array elements (one dimensional array) takes on my
> 100MHZ 603e Mac (with 256KB L2 and 64MB RAM) 120sec! And 60sec of that time
> is due to garbage collection.

> With Mops it takes 20sec (but even that is not optimal); 5 to 10 sec would
> be optimal.

Since you obviously don't program a lot in functional languages, how can
you say that the Clean-solution you had seen was optimal? Furthermore,
your example does not even make much sense, because FFT (as most
numeric code) should not cause lots of garbage. If it does, there is
something wrong with the implementation (either of the program or of
the compiler). Have you tried e.g. OCaml?

And if you are still not satisfied (it will very likely beat Mops' pants
off), I just need to interface to some Fortran-FFT routine (should take
less than an hour)...

>>> bb) And does now really someone care about memory so he ends up with
>>> "imperative style".
>>
>>Why do you (wrongly) assume this? Please elaborate...

> see above.

If I compare memory consumption of most FPLs with e.g. Java, I wonder
how anybody could claim that imperativeness makes for efficient memory
exploitation?!

>>Also not justified. OCaml, SML, Clean, Haskell (and probably others, too)
>>can all compile to native code directly. OCaml, for instance, supports
>>just about any architecture you can name (and some that you can't)...

> I can't name Macintosh.

MacOS X is fully supported (including native code). There are good reasons
not to waste time supporting native code compilation on older Macs. Evil
tongues would say that the older MacOSes wouldn't fall under the label
"architecture"... ;)

>>> dd) Even Clean is written in C. Exercise:
>>
>>No, the new release is rewritten in Clean itself.

> As far as I am informed is only the development environement written in
> Clean. Clean kernel itself stayed unchanged in C.

As I said, the new release is rewritten in Clean:

http://www.cs.kun.nl/~clean/About_Clean/Clean_2_0/clean_2_0.html

You did not expect that the Clean-people somehow magically managed to
write the first relesase of Clean in itself without having anything to
bootstrap it?

Brian Rogoff

unread,
Feb 16, 2001, 12:11:00 PM2/16/01
to
On 16 Feb 2001, Ulf Wiger wrote:
> >>>>> "Brian" == Brian Rogoff <b...@shell5.ba.best.com> writes:
>
> Brian> while Erlang 4.7 may have a shorter spec, I don't think
> Brian> Erlang deals with real-time ("soft" RT? ha!)
>
> Ah, you're being humorous. (:

Not really. But you realize that your argument (Erlang 4.7 spec is
half the size of the Ada spec so it's much better) also implies that
SML is much better than Erlang, since it's formal spec is o so much
shorter.

> Erlang does not address hard real-time because there hasn't been
> a requirement to make an implementation that supports it.
>
> Show me the language details that would prevent an Erlang
> implementation for hard real-time. Erlang is based on communicating
> processes with a distinct notion of time and preemptive scheduling.

I think you'd have to start providing memory management primitives. I
haven't seen much evidence outside of academic work that hard real time
GC has caught on. But this isn't my field of expertise, my point is that
there are a lot of things you can do in Ada (that must be in the
spec) that you can't do in Erlang.

I think to be fair we should wait until there have been a few hard real
time embedded Erlang projects, and compare the size of the new spec which
may contain additional featues.

> Brian> or systems programming issues like Ada does (you can
> Brian> program at the C level in Ada).
>
> Yes, the everything-but-the-kitchen-sink approach tends to give
> bloated specs. Wasn't this the point?

I'd hardly say that twice the size of the Erlang 4.7 spec is bloated,
especially considering that the languages address somewhat different
issues. Ada is a general purpose programming language, where one of the
general purposes is bit level mucking about.

> If an Erlang programmer wants to program at the C level, he uses C.

So add the size of the C spec to the Erlang spec when comparing the two
languages.

-- Brian


Siegfried Gonzi

unread,
Feb 16, 2001, 12:28:08 PM2/16/01
to

Markus Mottl schrieb in Nachricht <96jf6r$5pm$1...@bird.wu-wien.ac.at>...

>> That is no reason for functional programming.
>
>No? So it does not matter whether languages have a low degree of
>complexity while being more expressive?


Why are you so sure that a functional programming language is of much lower
complexity? Do you really mean that lambda-calculus is for the mass?

>
>Since you obviously don't program a lot in functional languages, how can
>you say that the Clean-solution you had seen was optimal?

a) The pure FFT implementation takes infinity
b) The Cooley-Tukey implementation was hard to follow

c) Then I tried to implement my own version; but I failed nobody was able to
teach me how I can implement a nested loop (3 loops) in Clean; even the
mailing list was of no help. And for all they say now: do it functional:
please see point a).
After 3 hours I stopped writing the FFT code, because I was unable to follow
the code anylonger.


> Furthermore,
>your example does not even make much sense, because FFT (as most
>numeric code) should not cause lots of garbage.

That are big arrays? Sorry, that was what I have got observed.

>If it does, there is
>something wrong with the implementation (either of the program or of
>the compiler). Have you tried e.g. OCaml?

For the clarification: it is not my job here to judge Clean. Nor I am
willing to say anything bad about Clean. Clean is a nice language which is
developed by engaged guys. Everybody should use that language he likes most.

I cannot try OCaml, because I own a Mac. And we astronomers use for our work
mainly IDL. Programming is more a hobby for me and maybe I will drop my
astronoy career and move to private industry; for that case I am a little
bit interested in programming.

>And if you are still not satisfied (it will very likely beat Mops' pants
>off), I just need to interface to some Fortran-FFT routine (should take
>less than an hour)...

Why should I use OCaml and how can you know that it will outperform Mops.
And even so, 5sec or 10 who cares?

>If I compare memory consumption of most FPLs with e.g. Java, I wonder
>how anybody could claim that imperativeness makes for efficient memory
>exploitation?!

Please show me that point where I ever mentioned Java.

>MacOS X is fully supported (including native code). There are good reasons
>not to waste time supporting native code compilation on older Macs.

And why are that not good reasons for Windows alike?

>Evil
>tongues would say that the older MacOSes wouldn't fall under the label
>"architecture"... ;)


I would say that from functional programming.


Regards,
S. Gonzi


George Russell

unread,
Feb 16, 2001, 1:01:24 PM2/16/01
to
Brian Rogoff wrote:
[snip]

> I think you'd have to start providing memory management primitives. I
> haven't seen much evidence outside of academic work that hard real time
> GC has caught on.
[snip]
I think part of the reason for this may be that languages with hard real time
GC are unlikely to be popular with the safety critical community, because
that community is rightly scared of a lot of other things which tend to come
with GC languages, such as memory leaks and recursion. See for example
http://catless.ncl.ac.uk/Risks/9.01.html#subj2
There are several comments in subsequent volumes of Risks. I don't
know if the summary presented there (still) represents the Department of
Defence guidelines, but I rather hope it does.

It is my opinion that a functional program in a strongly-typed
language is much less likely to have bugs than a non-functional program
solving the same problem written by people with similar experience in
the same amount of time, but GC and recursion are serious problems.
I would like to think that the ideal language would be something like
the MLKit, where the compiler with the help of the programmer proves that
there are no memory-leaks or unbounded recursions, but I don't know if
that's feasible.

Andrew Cooke

unread,
Feb 16, 2001, 1:01:54 PM2/16/01
to

Siegfried Gonzi wrote:
> Markus Mottl schrieb in Nachricht <96e5s3$jrh$1...@bird.wu-wien.ac.at>...

[...]


> That is no a class of itself. Short doesn't mean good or better. The same
> problem faces the Forth community. Forth specification itself is very short.
> Sure I can write down a program with very few lines, but a year later I am
> not able to read it any longer. Okay I could comment a lot, but is that the
> sin of a "short" programming language?
>
> >Can it be (to stay in the somewhat provocative tone that you take here)
> >that you were just afraid of learning something new?
>
> There are things which doesn't pay off...

Hi,

I see in another post that you are an astronomer that is wondering about
leaving for industry. I was the same. You certainly don't need to look
at functional programming to get a job - but if you do, you might learn
something. For example, if you spend most time programming in C or C++
or Java or VB (typical industry jobs) you get used to a certain way of
doing things. Learning FP gives you a different viewpoint - there is a
different divide between code and data, which concentrates on the
structure within the processing, rather than the structure within the
data (saying it in a very poor way).

You also start to realise that the world of programming is just as
complex and hierarchical as the world of astronomy. At the moment, for
example, this conversation isn't unlike, say, an amateur astronomer
arguing with someone working on adaptive optics ten years ago. You're
banging on about the few things you know ("but it'll only work with
bright stars and anyway there's the Hubble and in my back garden I can
see Jupiter...") with people who are developing technology that could be
revolutionary...

And as for the rest of this thread. Please. Arguing about the number
of pages in manuals! Hello? Maybe astronomers + computer sciences
should start a search for sentinent life forms in this newsgroup. :-)

Andrew

Andrew Cooke

unread,
Feb 16, 2001, 1:11:31 PM2/16/01
to

George Russell wrote:
> I think part of the reason for this may be that languages with hard real time
> GC are unlikely to be popular with the safety critical community, because
> that community is rightly scared of a lot of other things which tend to come
> with GC languages, such as memory leaks and recursion. See for example
> http://catless.ncl.ac.uk/Risks/9.01.html#subj2
> There are several comments in subsequent volumes of Risks. I don't
> know if the summary presented there (still) represents the Department of
> Defence guidelines, but I rather hope it does.

So does Ada satisfy those reqs? How do you do formal verification of
Ada code (any links?). What other languages would be suitable?

Curious,
Andrew

George Russell

unread,
Feb 16, 2001, 1:23:11 PM2/16/01
to
Andrew Cooke wrote:
[snip]

> So does Ada satisfy those reqs? How do you do formal verification of
> Ada code (any links?). What other languages would be suitable?
[snip]
Well, this isn't my field, but I would imagine that the procedure for
writing safety-critical software in Ada would start with defining a
subset of Ada you were allowed to use, and getting hold of tools which
enforced that programmers only used that subset.

Brian Rogoff

unread,
Feb 16, 2001, 1:31:00 PM2/16/01
to
On Fri, 16 Feb 2001, Siegfried Gonzi wrote:
> Markus Mottl schrieb in Nachricht <96jf6r$5pm$1...@bird.wu-wien.ac.at>...
> >> That is no reason for functional programming.
> >
> >No? So it does not matter whether languages have a low degree of
> >complexity while being more expressive?
>
> Why are you so sure that a functional programming language is of much lower
> complexity? Do you really mean that lambda-calculus is for the mass?

Personally, these meta-discussions about language complexity blah blah are
seeming like a waste of time. Post the Clean code and the timings you got,
and let's see if we can whack that into better shape. I'll step up if no
one else does but there are some Clean experts who can do better. I doubt
you'll whip C or Fortran but infinity is pretty easy to beat.

Surely, you see *something* in the functional approach, else you'd have
departed for comp.lang.forth by now.

-- Brian

Siegfried Gonzi

unread,
Feb 16, 2001, 1:59:58 PM2/16/01
to

Brian Rogoff schrieb in Nachricht ...

>Personally, these meta-discussions about language complexity blah blah are
>seeming like a waste of time. Post the Clean code and the timings you got,
>and let's see if we can whack that into better shape.

Before I end (for myself) or better leave the thread, I post for beeing
correct the above mentioned FFT implementation in Clean. It is the link to
the tutorial (therein please go to "A faster FFT ". Sorry for that long
link, that was the search result from an search engine (I couldn't find
anything shorter):
http://www.looksmart.com/r?page=/search/frames/index.html&isp=US&name=&bcolo
r=ffcc00&key=Clean+tutorial&url=http://www.deene.ufu.br/clean/clean1.html&ps
kip=10&nskip=20&se=5,8,0,1000&index=3

>I'll step up if no
>one else does but there are some Clean experts who can do better. I doubt
>you'll whip C or Fortran but infinity is pretty easy to beat.


Wer's glaubt wird selig.


Regards,
S. Gonzi


Laurent Guerby

unread,
Feb 16, 2001, 2:08:01 PM2/16/01
to
"Daniel C. Wang" <danwan...@cs.princeton.edu> writes:
> I'm simply trying to suggest a metric that gives you a feel for how much
> stuff must be held in the head of our poor programmer to completely
> understand the language.

I find this "completely understand the language" statement surprising,
why do you need to completely understand a language to use it? The
"Pascal subset" is very easy to understand (this part of Ada is a bit
cleaner and othogonal than Pascal IMHO), and you can do lots before
you need more powerful/exotic things (pointers, late binding,
exceptions, generics, tasking, real time, bit fiddling, distributed
programming, etc...).

> I have nothing against Ada, but a part of me feels like there is a smaller
> language trying to get out. A more fair comparison would probably be between
> Ada95 and Modula-3. The modula-3 spec although informal, is quiet concise.

Modula-3 is much smaller than Ada, this won't change the comparison
outcome ;-).

As for the small subset, it already exists and it is called SPARK 95,
see:

High Integrity Ada: The SPARK Approach by John Barnes
Addison-Wesley; 1997; ISBN 0-201-17517-7

--
Laurent Guerby <gue...@acm.org>

Laurent Guerby

unread,
Feb 16, 2001, 2:13:41 PM2/16/01
to
Brian Rogoff <b...@shell5.ba.best.com> writes:
> The front-end consists of over 400 K lines of Ada, distributed among 909
> files.

This is the figure for front-end + run-time, I would say runtime is
40-50% of it, and 10% for misc tools, the rest being the
front-end. Also the comment ratio is IIRC above 50% (GNAT internals
are very well documented).

But that's still much bigger than any SML implementation ;-).

--
Laurent Guerby <gue...@acm.org>

Laurent Guerby

unread,
Feb 16, 2001, 2:17:34 PM2/16/01
to
Andrew Cooke <and...@andrewcooke.free-online.co.uk> writes:
> Learning FP gives you a different viewpoint - there is a
> different divide between code and data, which concentrates on the
> structure within the processing, rather than the structure within the
> data (saying it in a very poor way).

May be just that FP gives you the right attitude about state (bletch!
;-). Don't know if my saying is much better though ;-).

> Please. Arguing about the number of pages in manuals! Hello?
> Maybe astronomers + computer sciences should start a search for
> sentinent life forms in this newsgroup. :-)

;-).

--
Laurent Guerby <gue...@acm.org>

Brian Rogoff

unread,
Feb 16, 2001, 2:26:26 PM2/16/01
to

The "no subsets" rule about Ada is passe.

Look at http://www.praxis-cs.co.uk/ for a useful subset of Ada
(SPARK). Sorry, no what-ifs or research implementations, just stuff
that is really being used.

I agree with George about the qualities of modern FPLs versus more
traditional languages, and I'm hopeful that FPLs will play a bigger role
even in embedded and hard RT in the future, but I think we should be
honest about what's currently feasible and what is currently a pipe dream.
Martin Hoffman posted some interesting stuff that he's been working on
here, that might be able to help.

OK, no more on this for me, back to FP :-)

-- Brian


Laurent Guerby

unread,
Feb 16, 2001, 2:32:26 PM2/16/01
to
Andrew Cooke <and...@andrewcooke.free-online.co.uk> writes:
> So does Ada satisfy those reqs? How do you do formal verification of
> Ada code (any links?). What other languages would be suitable?

(See my SPARK book reference.)

One thing the highest reqs put on a language and its implementation is
complete tracability from requirements to spec to code and even
sometimes to assembly code, and there you want no dead code, and if
there is runtime code coming with the implementation, it has to be
developped with the same standard than the rest of the application.

This puts your typical FP implementation out of this league, because
the actual machine model is much closer to imperative than functional
(but functional is much closer to spec...), so the assembly code
generated from FP code won't be easily traceable to source.

Also, this kind of system typically deals with real-time, state, and
very little memory and slow processors.

For the now famous Ariane 501 fireworks, the specific assembly code
(and the data range check) was easily traced to Ada code and
requirements. The code was 100% to requirements, spec and
documentation, it's just that the requirements itself were designed
for Ariane 4 and were just wrong for Ariane 5 but nobody checked this
before flight, hence our friend Murphy said boom.

> Curious,

Good ;-).

--
Laurent Guerby <gue...@acm.org>

George Russell

unread,
Feb 16, 2001, 2:43:18 PM2/16/01
to
Laurent Guerby wrote:
[snip]

> One thing the highest reqs put on a language and its implementation is
> complete tracability from requirements to spec to code and even
> sometimes to assembly code, and there you want no dead code, and if
> there is runtime code coming with the implementation, it has to be
> developped with the same standard than the rest of the application.
>
> This puts your typical FP implementation out of this league, because
> the actual machine model is much closer to imperative than functional
> (but functional is much closer to spec...), so the assembly code
> generated from FP code won't be easily traceable to source.
[snip]
I suppose this could be an argument for reviving special hardware for
running functional languages by graph reduction. Of course you'd have
to verify the new hardware, but this would surely not be harder than
verifying the VIPER chip.

However you still would need tools for avoiding or eliminating memory
leaks and unbounded recursion.

And the cost of developing hardware and (especially) the tools would
make it very difficult to get such a project off the ground, unless one
could brainwash someone suitably high up in the Pentagon . . .

Anders Gidenstam

unread,
Feb 16, 2001, 2:12:01 PM2/16/01
to
In article <3A8D700F...@tzi.de>,

I've heard about a such subset and toolset called SPARK and a quick web search
came up with http://www.praxis-cs.co.uk/.

/Anders
--
--------------------------------------------
"A well-written program is its own heaven;
a poorly-written program is its own hell."
- The Tao of Programming

Garry Hodgson

unread,
Feb 16, 2001, 3:02:49 PM2/16/01
to
Siegfried Gonzi wrote:

> After 3 hours I stopped writing the FFT code, because I was unable to follow
> the code anylonger.

fine. as long as you gave it a fair shake.

--
Garry Hodgson Once in a while
Senior Hacker you can get shown the light
Software Innovation Services in the strangest of places
AT&T Labs if you look at it right

Marcin 'Qrczak' Kowalczyk

unread,
Feb 16, 2001, 4:02:18 PM2/16/01
to
Fri, 16 Feb 2001 18:01:54 +0000, Andrew Cooke <and...@andrewcooke.free-online.co.uk> pisze:

> Learning FP gives you a different viewpoint - there is a different
> divide between code and data, which concentrates on the structure
> within the processing, rather than the structure within the data
> (saying it in a very poor way).

I would not say it that way. FP is really about data.

IMHO the FP viewpoint is that functions are special sort of data,
and that some kinds of data can be represented as functions.

Concepts which describe some processing (parsers, filtering rules,
dynamically generated contents, objects behaving in ways specific
to particular objects) are represented as first class data objects,
composed using functions instead of builtin control flow constructs.

By discouraging side effects and supporting constructing and examining
of structured data, FP encourages separation of producing / processing
/ consuming of data, materializing intermediate forms of those data.
Here FP actually makes data more concrete.

It's hard to do all transformations at once. A complex transformation
would need to explicitly take parameters belonging to all stages
(perhaps lots of them). It would need to use lots of local variables
because they are immutable. So FP encourages splitting a complex
stage into two. The intermediate form of data might be the same as
source or destination form, or some third form.

Traditional imperative programming makes functions and data separate
concepts. There are expressions and statements: statements contain
expressions, but not vice versa. There are procedures processing data,
but usually there are no procedures processing procedures nor data
containing procedures.

OOP introduces functions processing functions and data containing
functions to imperative programming. In that sense it makes the
programming more functional.

A difference in approaching functions: In OOP the structure of data
attached to "function closures" (i.e. to objects with methods) is
explicitly described, the same object contains many functions which are
accessed by names, and a function object is a special case of a data
object. In FP a function closure is anonymous, has only one function,
and a data object with runtime-dispatched behavior is expressed as
a record of several functions.

A difference in aproaching data: FP makes easy to define custom
kinds of complex data structures, but makes hard to provide generic
containers and algorithms which need mutability (e.g. hash tables or
even flat arrays). OOP makes easy to use generic containers for bulk
data, but cannot express ad-hoc pure data structures (not already
bundled with all kinds of processing of that data) as conveniently
as algebraic types.

OOP does not encourage splitting stages of processing, because
the OO style bundles operations with types of data nodes. All
processing applying to a particular type is defined at one place:
in the definition of that type. The producer / consumer matrix is
partitioned in a different direction.

In FP dependencies between parts of the program are more explicit than
in OOP. This is sometimes an advantage and sometimes a disadantage.

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

Markus Mottl

unread,
Feb 16, 2001, 5:37:33 PM2/16/01
to
Siegfried Gonzi <siegfri...@kfunigraz.ac.at> wrote:
> Markus Mottl schrieb in Nachricht <96jf6r$5pm$1...@bird.wu-wien.ac.at>...
>>No? So it does not matter whether languages have a low degree of
>>complexity while being more expressive?

> Why are you so sure that a functional programming language is of much lower
> complexity? Do you really mean that lambda-calculus is for the mass?

Because there are no side effects that you may need to trace through your
whole program. The meaning of variables in a given scope is always the
same. Thus, the meaning of functions is completely determined by their
parameters and the function body. This *significantly* cuts down the
part of code that you need to reason about.

> a) The pure FFT implementation takes infinity

Then it is wrong.

> b) The Cooley-Tukey implementation was hard to follow

Maybe because the implementation was bad?

> c) Then I tried to implement my own version;

You probably admit that you do not have much experience with FPLs. Imagine
somebody who has never used imperative languages, do you really think that
he could follow an imperative program? The main problem is that people
who come from the "imperative world", possibly with years of experience,
believe that this experience will also make them a good programmer
in FPLs. This is clearly wrong as I had to experience myself. Before
I came to FPLs I had used imperative languages for nearly 10 years, 4
of those C++ and now after not even three years of programming in FPLs
(mostly OCaml) I come to the conclusion that my previous knowledge about
programming was close to zero.

> but I failed nobody was able to
> teach me how I can implement a nested loop (3 loops) in Clean;

This is absolutely trivial. Taking a look at the archives of the
Clean list shows me that Jerzy explained you how to do FFT in a better
way. Maths *is* purely functional! Translating algorithms described in
maths into an executable computer program is much more straightforward
in functional languages, nobody would seriously doubt this.

If you want to see an example of nested loops, here we go (OCaml):

let rec loop n m f env = if n > m then env else loop (n+1) m f (f n env)

This defines a general loop construct (a nice one-liner)...

Here we test it:

let _ =
let cnt, sum =
loop 1 200 (fun i ->
loop 1 200 (fun j ->
loop 1 200 (fun k (cnt, sum) ->
cnt + 1, sum + i + j + k)))
(0, 0) in
Printf.printf "cnt: %d sum: %d\n" cnt sum

Here the imperative version (you can write imperative code in OCaml, too):

let _ =
let cnt = ref 0
and sum = ref 0 in
for i = 1 to 200 do
for j = 1 to 200 do
for k = 1 to 200 do
cnt := !cnt + 1;
sum := !sum + i + j + k
done
done
done;
Printf.printf "cnt: %d sum: %d\n" !cnt !sum

The imperative version runs admittedly twice as fast, which should,
however, not matter in most applications (you were not complaining about
minor factors). Additionally, you see that higher-order functions are very
powerful - and unfortunately not available in most imperative languages.

> even the
> mailing list was of no help.

You should have asked here... ;)

> And for all they say now: do it functional:
> please see point a).

FPLs are Turing complete so if you can do it in finite time in an
imperative language, you must also be able to do it in finite time in
an FPL. As I said: the implementation must have been incorrect.

> After 3 hours I stopped writing the FFT code, because I was unable to follow
> the code anylonger.

How about starting with simpler things first? The FFT is usually not
something that beginners start with. There are plenty of tutorials on
the web.

>> Furthermore,
>>your example does not even make much sense, because FFT (as most
>>numeric code) should not cause lots of garbage.

> That are big arrays? Sorry, that was what I have got observed.

Every FPL with reasonable support for numeric computations has arrays
with unboxed floating point numbers. This means that these arrays are
*not* scanned by the GC. Therefore, there shouldn't be any noticable
GC-impact if most of the code just moves around data between arrays
while doing some straightforward computations.

> For the clarification: it is not my job here to judge Clean. Nor I am
> willing to say anything bad about Clean. Clean is a nice language which is
> developed by engaged guys. Everybody should use that language he likes most.

Clean can exhibit much more performance than you might think (when wisely
used). Try, for example, the "sieves"-example in the distribution. Write
me as soon as you manage to implement this algorithm in C more
efficiently... ;)

> I cannot try OCaml, because I own a Mac. And we astronomers use for our work
> mainly IDL. Programming is more a hobby for me and maybe I will drop my
> astronoy career and move to private industry; for that case I am a little
> bit interested in programming.

Then you'd probably be interested in David McClain's page and software:

http://www.azstarnet.com/~dmcclain/homepage.htm

Follow the link to his language comparison. Since he does heavy-weight
dataprocessing for astronomy applications, it is surely relevant to
you. There is also a speed comparison for the BlurFit algorithm (OCaml
handily wins against a C++ implementation (GNU C++) and is about twice
as fast as IDL).

This one is also interesting:

http://www.azstarnet.com/~dmcclain/nmlpromo.htm

Btw., OCaml bytecode is pretty fast! Even if you can't use native code
on your platform, it might still be good enough for many purposes. The
best thing, of course, would be to upgrade to a decent Unix system
(MacOS X would also fit this requirement)...

> Why should I use OCaml and how can you know that it will outperform Mops.
> And even so, 5sec or 10 who cares?

David's explanations in his language comparison will surely provide
plenty of arguments...

> Please show me that point where I ever mentioned Java.

You seemed to imply that FPLs have problems with memory consumption. Why
don't you take a look at this page to see how much time and memory
various languages really need on some benchmarks:

http://www.bagley.org/~doug/shootout/craps.shtml

And try to find documents on the ICFP-contests, in which FPLs usually
beat the pants off their imperative competitors.

I cannot accept your efficiency argument (also in terms of memory)
and have convincing reasons to do so...

>>MacOS X is fully supported (including native code). There are good reasons
>>not to waste time supporting native code compilation on older Macs.

> And why are that not good reasons for Windows alike?

There are always several reasons to consider. One of them is technical,
another economical: it would probably be unwise to neglect as system
that has > 90% market share even if it is technically inferior. The
availability of a good GUI is not really such a major aspect for a
programming language (I can't judge this, my favourite environment is
bash in an xterm). I am afraid, but I cannot find any other reasons that
would speak for the old MacOS...

Daniel C. Wang

unread,
Feb 16, 2001, 8:20:03 PM2/16/01
to

Laurent Guerby <gue...@acm.org> writes:

> "Daniel C. Wang" <danwan...@cs.princeton.edu> writes:
> > I'm simply trying to suggest a metric that gives you a feel for how much
> > stuff must be held in the head of our poor programmer to completely
> > understand the language.
>
> I find this "completely understand the language" statement surprising,
> why do you need to completely understand a language to use it? The
> "Pascal subset" is very easy to understand (this part of Ada is a bit
> cleaner and othogonal than Pascal IMHO), and you can do lots before
> you need more powerful/exotic things (pointers, late binding,
> exceptions, generics, tasking, real time, bit fiddling, distributed
> programming, etc...).

Usually, you have to understand the complete langauge to understand all the
possible interactions of language features and to be an expert.

Also, sure I can program in the Pascal subset of Ada, but if the majority of
Ada programmers make their living by programming in the Ada subset, then Ada
needs to be trimmed down!

Anders Gidenstam

unread,
Feb 17, 2001, 4:41:23 AM2/17/01
to
In article <r8tsnle...@vista.cs.princeton.edu>,

"Daniel C. Wang" <danwan...@cs.princeton.edu> writes:
>
> Laurent Guerby <gue...@acm.org> writes:
>
>> I find this "completely understand the language" statement surprising,
>> why do you need to completely understand a language to use it? The
>> "Pascal subset" is very easy to understand (this part of Ada is a bit
>> cleaner and othogonal than Pascal IMHO), and you can do lots before
>> you need more powerful/exotic things (pointers, late binding,
>> exceptions, generics, tasking, real time, bit fiddling, distributed
>> programming, etc...).
>
> Usually, you have to understand the complete langauge to understand all the
> possible interactions of language features and to be an expert.
>
> Also, sure I can program in the Pascal subset of Ada, but if the majority of
> Ada programmers make their living by programming in the Ada subset, then Ada
> needs to be trimmed down!

But what if they all use different subsets of Ada?
And btw., IMHO that is one of the greatest things with Ada! I have used Ada
for more than 4 years now, and I still find new neat language features that
I didn't know before.. ;-)

Fergus Henderson

unread,
Feb 17, 2001, 6:32:07 AM2/17/01
to
Markus Mottl <mo...@miss.wu-wien.ac.at> writes:

>Siegfried Gonzi <siegfri...@kfunigraz.ac.at> wrote:
>
>> d) Sometimes I think that is a joke if someone says: Shift to functional
>> programming and that is real an alternative to C. And then the C programmer
>> answers: Okay I will give it a try, but what about stand alones. The
>> functional guy: Oh, write your cute functional programming code and compile
>> it then to C. That is also the thread "Why functional programming will take
>> over the world...".


>
>Also not justified. OCaml, SML, Clean, Haskell (and probably others, too)
>can all compile to native code directly.

You can add Mercury to that list. The latest "release-of-the-day"
version of the Mercury compiler now includes support for a
`--target asm' option, which causes it to generate assembler directly,
rather than going via C.

The implementation uses a new back-end for the Mercury compiler that
links in the GCC back-end. Note that these days "GCC" stands for
"GNU Compiler Collection", not "GNU C Compiler"; the GCC back end is
(relatively) language independent. Not suprisingly it is still
focused more towards procedural languages, rather than functional or
logic programming languages, but that just means that we need to do a
bit more work in our Mercury front-end than some of the other GCC
front-ends do, doing various transformations to handle constructs such
as parametric polymorphism, type classes, higher-order functions and
backtracking, before passing the intermediate code to the GCC
back-end.

Not all of our release-of-the-day binary distributions include the
GCC back-end version of the compiler yet, but some of them do, e.g.
<ftp://ftp.mercury.cs.mu.oz.au/pub/mercury/beta-releases/
mercury-rotd-2001-02-17.i686-pc-linux-libc2.1-gnu-O4.tar.gz>.

Note that this is still a beta release. Furthermore it is based on
an unreleased snapshot version of the GCC back-end. Also the current
binary distributions have various internal debugging checks in the
GCC back-end enabled, which may slow down compilation a fair bit.
But that will probably change when this gets officially released,
hopefully sometime soon!

--
Fergus Henderson <f...@cs.mu.oz.au> | "I have always known that the pursuit
| of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.

Markus Mottl

unread,
Feb 17, 2001, 9:43:48 AM2/17/01
to
Fergus Henderson <f...@cs.mu.oz.au> wrote:
> You can add Mercury to that list. The latest "release-of-the-day"
> version of the Mercury compiler now includes support for a
> `--target asm' option, which causes it to generate assembler directly,
> rather than going via C.

That's great news! :-)

Michael Schuerig

unread,
Feb 17, 2001, 12:05:19 PM2/17/01
to
Anders Gidenstam <d96a...@dtek.chalmers.se> wrote:

> But what if they all use different subsets of Ada?
> And btw., IMHO that is one of the greatest things with Ada! I have used Ada
> for more than 4 years now, and I still find new neat language features that
> I didn't know before.. ;-)

Then you might want to learn C++ if you don't already know it. Today's
sublanguage is template metaprogramming.

Michael

--
Michael Schuerig
mailto:schu...@acm.org
http://www.schuerig.de/michael/

Neelakantan Krishnaswami

unread,
Feb 17, 2001, 10:26:44 PM2/17/01
to
On Fri, 16 Feb 2001 19:01:24 +0100, George Russell <g...@tzi.de> wrote:
>
> It is my opinion that a functional program in a strongly-typed
> language is much less likely to have bugs than a non-functional
> program solving the same problem written by people with similar
> experience in the same amount of time, but GC and recursion are
> serious problems. I would like to think that the ideal language
> would be something like the MLKit, where the compiler with the help
> of the programmer proves that there are no memory-leaks or unbounded
> recursions, but I don't know if that's feasible.

I ran into Charity a few months ago, and that language apparently
makes it impossible to write nonterminating functions. I didn't
understand it very well since the user's manual had too much category
theory for me :), but it looked like the general idea was to push how
far you could go with just folds and unfolds.

If there were a FPL that combined this with MLKit like memory
management (possibly as a sublanguage embedded in a full ML-like
language) I guess you'd have something that satisfies most of your
conditions. You might need a tiny bit of extra syntax to allow a
controlled form of looping, and arithmetic might be a problem. I guess
SML is mostly there already; if you could somehow block the use of
exceptions or references, then forbidding the use of rec in val
bindings could block unbounded recursion.


Neel

Nicholas James NETHERCOTE

unread,
Feb 18, 2001, 7:31:53 PM2/18/01
to
George Russell <g...@tzi.de> writes:

>It is my opinion that a functional program in a strongly-typed
>language is much less likely to have bugs than a non-functional program
>solving the same problem written by people with similar experience in
>the same amount of time, but GC and recursion are serious problems.
>I would like to think that the ideal language would be something like
>the MLKit, where the compiler with the help of the programmer proves that
>there are no memory-leaks or unbounded recursions, but I don't know if
>that's feasible.

See Lars Pareto's PhD thesis "Types for Crash Prevention"
(www.cs.chalmers.se/~pareto) for some approaches to this problem.

--
Nick Nethercote
n...@cs.mu.oz.au

Ketil Z Malde

unread,
Feb 19, 2001, 2:34:09 AM2/19/01
to
"Siegfried Gonzi" <siegfri...@kfunigraz.ac.at> writes:

> a) The pure FFT implementation takes infinity

Huh? I thought it was O(n log n), which sounds finite to me, as long
as you have a finite input.

> b) The Cooley-Tukey implementation was hard to follow

I also thought the C-T *was* the FFT!?

It's been a long time since I looked at this, so I'm probably
mistaken.

-kzm
--
If I haven't seen further, it is by standing in the footprints of giants

Ulf Wiger

unread,
Feb 19, 2001, 5:44:37 AM2/19/01
to
>>>>> ">" == Brian Rogoff <b...@shell5.ba.best.com> writes:

>> Show me the language details that would prevent an Erlang
>> implementation for hard real-time. Erlang is based on
>> communicating processes with a distinct notion of time and
>> preemptive scheduling.

> I think you'd have to start providing memory management
> primitives.

I'm not at all sure that this is needed.
What you're basically saying is that you don't think that
memory management can be done behind the scenes in a hard
real-time system? I'd go as far as saying that it's a tricky
problem. ;-)

> my point is that there are a lot of things you can do
> in Ada (that must be in the spec) that you can't do in Erlang.

Yes. There are lots of things Erlang doesn't do -- often for
good reason. The classic example is that, despite of its prolog
origin, Erlang doesn't do backtracking: you can't backtrack over
hardware, and it makes prediction of real-time performance very
difficult. For similar reasons, Erlang doesn't support lazy
evaluation.


>> If an Erlang programmer wants to program at the C level,
>> he uses C.

> So add the size of the C spec to the Erlang spec when comparing
> the two languages.

No. That's like saying that in order to accurately describe a
hammer, you must also describe the details of a drill, just
because a carpenter who needs to make a small hole puts his hammer
aside and uses his electric drill. Different problems call for
different solutions.

/Uffe
--
Ulf Wiger tfn: +46 8 719 81 95
Senior System Architect mob: +46 70 519 81 95
Strategic Product & System Management ATM Multiservice Networks
Data Backbone & Optical Services Division Ericsson Telecom AB

Robert Virding

unread,
Feb 19, 2001, 6:36:58 AM2/19/01
to
In article <Pine.BSF.4.21.010216...@shell5.ba.best.com>,

Brian Rogoff <b...@shell5.ba.best.com> writes:
>
>I think you'd have to start providing memory management primitives. I
>haven't seen much evidence outside of academic work that hard real time
>GC has caught on. But this isn't my field of expertise, my point is that

>there are a lot of things you can do in Ada (that must be in the
>spec) that you can't do in Erlang.

GC is possible in hard real-time. BUT, it is not enough just to give
the collector hard bounds, that's the easy bit :-), it must exist
within a hard real-time system. A good thesis which describes hard
real-time GC and presents a implementation is:

Roger Henriksson, "Scheduling Garbage Collection in Embedded Systems"
Lund University, LUTEDX/(TECS-1008)/1-164/(1998)
Roger.He...@dna.lth.se

A good (but old) overview is:

Mats Bengtsson, "Real-Time Compacting Garbag Collection Algorithms"
Lund University,LUTEDX/(TECS-3028)/1-118(1990) & LU-CS-TR:90-61

It is defintely doable and probably a big win, but is not trival.

Robert

--
Robert Virding Tel: +46 (0)8 545 55 017
Alteon Web Systems Email: r...@bluetail.com
S:t Eriksgatan 44 WWW: http://www.bluetail.com/~rv
SE-112 34 Stockholm, SWEDEN
"Folk säger att jag inte bryr mig om någonting, men det skiter jag i".

Markus Mottl

unread,
Feb 19, 2001, 8:44:55 AM2/19/01
to
Ulf Wiger <Ulf....@ericsson.com> wrote:
> Yes. There are lots of things Erlang doesn't do -- often for
> good reason. The classic example is that, despite of its prolog
> origin, Erlang doesn't do backtracking: you can't backtrack over
> hardware, and it makes prediction of real-time performance very
> difficult. For similar reasons, Erlang doesn't support lazy
> evaluation.

If Erlang had a static type system in the spirit of Mercury, checking
of determinism would be possible. This would provide you with means to
specify your systems even more accurately and let the consistent use of
these specifications be automatically verified.

> > So add the size of the C spec to the Erlang spec when comparing
> > the two languages.

> No. That's like saying that in order to accurately describe a
> hammer, you must also describe the details of a drill, just
> because a carpenter who needs to make a small hole puts his hammer
> aside and uses his electric drill. Different problems call for
> different solutions.

Sometimes one solution is general enough to solve different problems.

Julian Assange

unread,
Feb 19, 2001, 8:50:43 AM2/19/01
to
"Siegfried Gonzi" <siegfri...@kfunigraz.ac.at> writes:

> I cannot try OCaml, because I own a Mac. And we astronomers use for our work
> mainly IDL. Programming is more a hobby for me and maybe I will drop my
> astronoy career and move to private industry; for that case I am a little
> bit interested in programming.

Please see D.McClain's language study. McClain is also a (formally) IDL
using astronomer.

http://www.azstarnet.com/~dmcclain/LanguageStudy.html

If you can use windows you might also be interested in:

http://www.azstarnet.com/~dmcclain/nmlpromo.htm

--
Julian Assange |If you want to build a ship, don't drum up people
|together to collect wood or assign them tasks and
pr...@iq.org |work, but rather teach them to long for the endless
pr...@gnu.ai.mit.edu |immensity of the sea. -- Antoine de Saint Exupery

Garry Hodgson

unread,
Feb 19, 2001, 9:31:06 AM2/19/01
to
Anders Gidenstam wrote:

> And btw., IMHO that is one of the greatest things with Ada! I have used Ada
> for more than 4 years now, and I still find new neat language features that
> I didn't know before.. ;-)

i used to feel that way about c++. except i didn't usually find them,
rather, they found me. when i least expected it.

Ulf Wiger

unread,
Feb 19, 2001, 11:31:07 AM2/19/01
to
>>>>> "-" == Markus Mottl <mo...@miss.wu-wien.ac.at> writes:

-> Ulf Wiger <Ulf....@ericsson.com> wrote:
>> Yes. There are lots of things Erlang doesn't do -- often for
>> good reason. The classic example is that, despite of its prolog
>> origin, Erlang doesn't do backtracking: you can't backtrack over
>> hardware, and it makes prediction of real-time performance very
>> difficult. For similar reasons, Erlang doesn't support lazy
>> evaluation.

-> If Erlang had a static type system in the spirit of Mercury,
-> checking of determinism would be possible. This would provide you
-> with means to specify your systems even more accurately and let
-> the consistent use of these specifications be automatically
-> verified.

Perhaps you could point me to some concrete examples of how
well that works in reality?
(Not being sarcastic -- I don't presume to think that Erlang won't
eventually be succeeded by something better.)

>> > So add the size of the C spec to the Erlang spec when
>> comparing > the two languages.

>> No. That's like saying that in order to accurately describe a
>> hammer, you must also describe the details of a drill, just
>> because a carpenter who needs to make a small hole puts his
>> hammer aside and uses his electric drill. Different problems call
>> for different solutions.

-> Sometimes one solution is general enough to solve different
-> problems.

Yes, sometimes. Therein often lies the beauty of the truly elegant
solutions: they offer an elegant solution which can be applied
well to a range of different problems. Personally, I think that
Erlang offers a very elegant solution to a wide range of problems.

One reason is that many problems have concurrency as a natural
component, and Erlang has a beautiful solution that suits many
of these problems.

In contrast, read e.g. the documentation of the SWING library:

http://java.sun.com/docs/books/tutorial/uiswing/overview/threads.html

Obviously, attacking concurrency using some languages makes
concurrency seem like something to avoid at all cost. Erlang
programmers quickly learn to extract the inherent concurrency of
a problem and build their programs around that.

Matthias Blume

unread,
Feb 19, 2001, 11:19:42 AM2/19/01
to
George Russell wrote:

> this happens in the current Haskell library standard. There are also a number of
> things in the 1997 definition of standard ML which no-one implements because they're
> ridiculous.

Which ones are you thinking of?

Matthias

George Russell

unread,
Feb 19, 2001, 11:50:00 AM2/19/01
to
I'm a bit hazy on the details, and I'm going on the comments I wrote for the parser to MLj,
because I haven't got the standard here. I think most are probably based on Kahrs' paper.

Does anyone implement the full syntax of "val rec"? This allows you to put multiple
"rec"'s in, as in
val rec rec f = fn x => f x;

Is the following legal:
signature S =
sig
type 'a t
and u = int
end
I think technically it should be illegal, but I suspect nearly all compilers allow it.

In sharing constraints, is
spec sharing longstrid
legal? I suspect everyone rejects it, because it's totally pointless.

There are also some things which various ML compilers do not do because they are quite
tricky, for example handling the "and" in
signature A = sigexp where type a=b and type c=d
as against
signature A = sigexp where type a=b and C = sigexp2.
But MLj gets this right, and I think MLWorks does too. However SML/NJ (110.7) doesn't.

Another thing I think MLj handles but SML/NJ doesn't is the production
pat := <op>vid <:ty> as pat
because : has a different precedence to what it has in
pat := <op>vid <:try>
(without as).

A lot of these would have been avoided if the authors of the standard had taken the
trouble to get their grammar through yacc before setting it in concrete . . .

Markus Mottl

unread,
Feb 19, 2001, 12:57:11 PM2/19/01
to
Ulf Wiger <Ulf....@ericsson.com> wrote:
> -> If Erlang had a static type system in the spirit of Mercury,
> -> checking of determinism would be possible. This would provide you
> -> with means to specify your systems even more accurately and let
> -> the consistent use of these specifications be automatically
> -> verified.

> Perhaps you could point me to some concrete examples of how
> well that works in reality?
> (Not being sarcastic -- I don't presume to think that Erlang won't
> eventually be succeeded by something better.)

I was referring to your comment that backtracking makes things difficult
when dealing with hardware. Advanced type systems like e.g. in Mercury,
however, allow you to specify that some predicates should only allow
one solution (i.e. they are deterministic). The compiler can prove
(by type inference/checking) that your code does not violate such
requirements. This prevents you from accidently trying to backtrack the
real world (if only we could sometimes! ;)

This means that your language could still have the full power of logic
inference while preventing anomalies as mentioned above.

> -> Sometimes one solution is general enough to solve different
> -> problems.

> Yes, sometimes. Therein often lies the beauty of the truly elegant
> solutions: they offer an elegant solution which can be applied
> well to a range of different problems. Personally, I think that
> Erlang offers a very elegant solution to a wide range of problems.

No doubt about this. Still, there are some things that just cannot be
done while it is possible in lower-level languages like C or Ada. This
does definitely not mean that I'd prefer C or Ada over Erlang...

> One reason is that many problems have concurrency as a natural
> component, and Erlang has a beautiful solution that suits many
> of these problems.

Right, that's what Erlang was designed for.

> Obviously, attacking concurrency using some languages makes
> concurrency seem like something to avoid at all cost. Erlang
> programmers quickly learn to extract the inherent concurrency of
> a problem and build their programs around that.

The capabilities of languages certainly shape one's way of going about
problems. If I needed to write distributed systems, I'd surely take
a look at Erlang to get some ideas, but this is currently just not my
application domain. Threads as provided by OCaml completely suffice to
me, and small client/server applications are also quite easy to write. If
I need more, I might choose the Ensemble-library as a work horse.

Andreas Rossberg

unread,
Feb 19, 2001, 12:48:47 PM2/19/01
to
George Russell wrote:
>
> Does anyone implement the full syntax of "val rec"? This allows you to put multiple
> "rec"'s in, as in
> val rec rec f = fn x => f x;

I think most do besides NJ.

> Is the following legal:
> signature S =
> sig
> type 'a t
> and u = int
> end
> I think technically it should be illegal, but I suspect nearly all compilers allow it.

This can be argued to be a conservative extension, though.

> In sharing constraints, is
> spec sharing longstrid
> legal? I suspect everyone rejects it, because it's totally pointless.

And I do not think this should be legal. The Definition omits stating an
explicit lower limit on the number of longstrids in this DF, but I would
say the intention clearly is 2, as for type sharing constraints.
Otherwise, why do you choose 1? Could equally well be 0, allowing

spec sharing

> There are also some things which various ML compilers do not do because they are quite
> tricky, for example handling the "and" in
> signature A = sigexp where type a=b and type c=d
> as against
> signature A = sigexp where type a=b and C = sigexp2.

This is doable even in LALR(1), but requires some rather ugly and
tedious grammar transformations.

BTW, you forgot to mention the most annoying example:

fun f x 0 = case z of p => a
| q => b
| f x y = c

Did any SML system ever get this parsed?

On the other hand, Haskell's parsing-error-terminates-layout rule is
unimplementable. I remember the OCaml grammar producing some 300
shift/reduce conflicts when fed to Yacc. And don't mention C and
friends. So I think SML's grammar is not that bad after all, even though
it is definitely the worst part of the spec (well, besides overloading).

--
Andreas Rossberg, ross...@ps.uni-sb.de

"Computer games don't affect kids.
If Pac Man affected us as kids, we would all be running around in
darkened rooms, munching pills, and listening to repetitive music."

Brian Rogoff

unread,
Feb 19, 2001, 2:02:14 PM2/19/01
to
On 19 Feb 2001, Ulf Wiger wrote:
> >>>>> ">" == Brian Rogoff <b...@shell5.ba.best.com> writes:
> > I think you'd have to start providing memory management
> > primitives.
>
> I'm not at all sure that this is needed.
> What you're basically saying is that you don't think that
> memory management can be done behind the scenes in a hard
> real-time system?

No. I said that that I'd only seen academic work on the subject, and
when I talk to people who work in those fields (and embedded systems)
GC is not even close to mainstream, despite the Sun push. I'm not even
saying it won't change; I'm just saying that if I were working in that
field I wouldn't want to be the first to try it in a non-research context.

> >> If an Erlang programmer wants to program at the C level,
> >> he uses C.
>
> > So add the size of the C spec to the Erlang spec when comparing
> > the two languages.
>
> No. That's like saying that in order to accurately describe a
> hammer, you must also describe the details of a drill, just
> because a carpenter who needs to make a small hole puts his hammer
> aside and uses his electric drill. Different problems call for
> different solutions.

Where's that quote from Dijkstra about analogies and medieval thinking? :-)

What I'm saying is that there are tasks I can do in pure Ada that require
Erlang programmers to use another language. That is why the spec is
bigger, you can describe representation of data at the bit level for
instance.

A more interesting question is on the orthogonality of the features, which
is raised by Gary Hodgson with respect to his C++ experiences. I'd say the
Ada design is relatively orthogonal, meaning you don't get bit by features
you don't know about too frequently (well, you do, but unlike C++
geting bit means you can't do something, not that you do and it causes
lots of debugging).

-- Brian


Sean Hinde

unread,
Feb 19, 2001, 6:43:40 PM2/19/01
to

"Markus Mottl" <mo...@miss.wu-wien.ac.at> wrote in message
news:96r80n$iqm$1...@bird.wu-wien.ac.at...

> Ulf Wiger <Ulf....@ericsson.com> wrote:
> > Yes. There are lots of things Erlang doesn't do -- often for
> > good reason. The classic example is that, despite of its prolog
> > origin, Erlang doesn't do backtracking: you can't backtrack over
> > hardware, and it makes prediction of real-time performance very
> > difficult. For similar reasons, Erlang doesn't support lazy
> > evaluation.
>
> If Erlang had a static type system in the spirit of Mercury, checking
> of determinism would be possible. This would provide you with means to
> specify your systems even more accurately and let the consistent use of
> these specifications be automatically verified.
>
My two penneth on this having read fairly widely back through the c.l.f.
archives.

The reason often given for the requirement for a static type system in
functional languages is that it is very difficult to write deeply nested
maps and folds of functions of partially curried functions of.. etc without
the support of a static type checker. I don't doubt that this is true as I
have just spent some time trying to write in that style in Erlang and it
took me some time to get a fairly simple tool working.

It occurred to me to wonder whether a style of programming which is so
mindbending that it requires help from a static typechecker to stand any
hope of working is neccessarily a good thing for the productivity of mortal
programmers.

Most Erlang progams seem to be written along much simpler lines with much
use of atom labels as a truly declarative self documenting replacement for
type declarations, a bunch of small helper functions which often use these
atoms as patterns to match a specific function header, and sequences of
almost imperative looking coding to string it all together e.g.

main(Input) ->
{ok, A, B, C} = do_stuff({in, Input}),
{ok, D, E} = do_some_more(B, C),
{ok, A, D, E}.

This stuff is really easy to code. Single assignment assures no nasties,
everything the program does is right there in front of the reader, and it
doesn't need *any* understanding of lambda anything to make very complex
systems.

Maybe I am missing something here but I don't really see the additional
benefit of partial currying and everything being a function of a function of
a function..

Some static type consistency analysis would be nice in Erlang as a "extra
fuzzy warm feeling" tool to check over a system for nasties before going
into production but I've not ever (until this evening) felt the need for one
to actually help me write a bit of code.

Hmmm....

- Sean


Neelakantan Krishnaswami

unread,
Feb 19, 2001, 7:51:21 PM2/19/01
to
On Mon, 19 Feb 2001 23:43:40 -0000, Sean Hinde <shind...@one2one.co.uk>
wrote:

>
> The reason often given for the requirement for a static type system
> in functional languages is that it is very difficult to write deeply
> nested maps and folds of functions of partially curried functions
> of.. etc without the support of a static type checker. I don't doubt
> that this is true as I have just spent some time trying to write in
> that style in Erlang and it took me some time to get a fairly simple
> tool working.

Here's some pragmatic advice, rather than theoretical. The problem I
have with folds in dynamically typed languages is that I am prone to
getting the order of arguments wrong. However, all my errors basically
go away instantly even in a dynamically typed language if I have
keyword arguments.

Eg, if I have <ast> as an abstract syntax tree, then being able to write
something like:

fold(<ast>, lambda: ..., app: ..., begin: ..., if: ..., set!: ...)

makes the fold pretty hard to screw up. I don't know if Erlang has
something like keyword arguments (like Lisp, Smalltalk and Dylan) but
if it does it can make using HOFs a lot simpler. OCaml wins again here
because it has labelled arguments in addition to static typing, of
course -- even with static typing a fold on a very complex algebraic
data type is easy to screw up.


Neel

thomas...@bluetail.com

unread,
Feb 20, 2001, 5:29:49 AM2/20/01
to

ne...@alum.mit.edu (Neelakantan Krishnaswami) writes:

> Here's some pragmatic advice, rather than theoretical. The problem I
> have with folds in dynamically typed languages is that I am prone to
> getting the order of arguments wrong. However, all my errors basically
> go away instantly even in a dynamically typed language if I have
> keyword arguments.
>
> Eg, if I have <ast> as an abstract syntax tree, then being able to write
> something like:
>
> fold(<ast>, lambda: ..., app: ..., begin: ..., if: ..., set!: ...)
>
> makes the fold pretty hard to screw up. I don't know if Erlang has
> something like keyword arguments (like Lisp, Smalltalk and Dylan) but
> if it does it can make using HOFs a lot simpler.

In Erlang, you can define a record to carry the arguments, e.g.:

-record(ast,{lambda,app,'begin','if','set!'}).

Then use it like:

f(#ast{lambda=X0,app=X1,'begin'=X2,'if'=X3}) -> %% match some fields of ast
%% return new ast record:
#ast{lambda=f(X1),app=g(X2),'begin'=X3,'set!'=init()}.


You can leave fields out, like in the example ('set!' in the match, 'if' in the
construction), which means they are
not matched, or default to some known value ('undefined' if nothing
else) when given in an expression.

That means you _can_ omit keywords (a bit like &optional, maybe).
So perhaps Erlang should have some way to _ensure_ that a record field
is explicitly defined.

(Actually, you can hack that today:

-record(rec,{field1=exit(undefined),field2=exit(undefined)}).

If field1 or field2 are not given, the record constructor will throw
an exception at runtime. But you'd like to get the error at compile
time in this case.)

Thomas
--
Thomas Lindgren thoma...@alteon.com
Alteon WebSystems

Markus Mottl

unread,
Feb 20, 2001, 5:44:48 AM2/20/01
to
Sean Hinde <shind...@one2one.co.uk> wrote:
> The reason often given for the requirement for a static type system in
> functional languages is that it is very difficult to write deeply nested
> maps and folds of functions of partially curried functions of.. etc without
> the support of a static type checker.

This is definitely true. Static type systems surely encourage a
higher-level programming style. When I compare the experience of
programming e.g. CL and OCaml, one can see a tendency to use "folds" and"
"maps" much more often in the latter.

> It occurred to me to wonder whether a style of programming which is so
> mindbending that it requires help from a static typechecker to stand any
> hope of working is neccessarily a good thing for the productivity of mortal
> programmers.

I disagree here: the reason why the static type checker is needed is not
that these constructs are so mindbending, but rather that it can be very
easy to e.g. pass parameters in the wrong order, pick the wrong variable
to work with, etc.

If I read through my previous sources, I find my high-level constructs
much more readable than the ones where I use explicit recursion or
else. The reason is that one can see what is meant without having to fully
follow the order of parameters in detail. This, however, also depends on
the general style of programming: using named functions instead of lambdas
usually greatly improves readability, because you don't have to read (and
understand) the body of the lambda - the name should speak for itself.

> Most Erlang progams seem to be written along much simpler lines with much
> use of atom labels as a truly declarative self documenting replacement for
> type declarations, a bunch of small helper functions which often use these
> atoms as patterns to match a specific function header, and sequences of
> almost imperative looking coding to string it all together e.g.

> main(Input) ->
> {ok, A, B, C} = do_stuff({in, Input}),
> {ok, D, E} = do_some_more(B, C),
> {ok, A, D, E}.

Why do you think that this is so much different from other functional
languages? I don't see how Erlang encourages a more declarative style
of programming here.

> This stuff is really easy to code. Single assignment assures no nasties,
> everything the program does is right there in front of the reader, and it
> doesn't need *any* understanding of lambda anything to make very complex
> systems.

We should really make a difference between good and bad programming
style. I also don't like code that makes excessive use of lambdas (=
unnamed functions) - see above. But I *do* think that higher-order
functions make life easier.

> Maybe I am missing something here but I don't really see the additional
> benefit of partial currying and everything being a function of a function of
> a function..

Maybe we should consider a real example:

let nts_in_sym acc = function NT nt -> NTSet.add nt acc | _ -> acc
let nts_in_prod (_, syms) acc = List.fold_left nts_in_sym acc syms
let nts_in_nt nt prods acc = ProdSet.fold nts_in_prod prods (NTSet.add nt acc)
let nts_in_grammar gr = NTMap.fold nts_in_nt gr NTSet.empty

This code uses three nested folds to collect all nonterminal symbols
that can be found in a context-free grammar (both left- and right hand
side). The function names speak for themselves: "nts_in_grammar" does what
we have just explained. It makes use of "nts_in_nt", which collects both
the LHS and RHS, which again traverses all productions with "nts_in_prod",
which again traverses all symbols in each production with "nts_in_sym".

Take a look at the last line: if you are used to reading fold-heavy code,
this reads "collect all nts for each nt in grammar gr starting with the
empty set of nonterminals". The same applies to the other folds. I'd be
very surprised if a version without higher-order functions made things
clearer, but you are welcome to contribute one...

It is important to note that there are many different types in this
code: terminals, nonterminals, maps and sets of nonterminals, sets of
productions, lists of symbols, etc. Without a static type system, it
could be very easy to make stupid little mistakes even if the intended
meaning of the code seems obvious. I use the static type checker to
verify my mental image of the code rather than to reduce the complexity
of higher-order functions (which are not problematic as such).

E.g. if I had written

let nts_in_grammar gr = NTMap.fold nts_in_nt NTSet.empty gr

I would probably not notice the error (compare with code above), but I'd
still know what this *should* mean. The static type checker will point
out to me that my mental image diverges from the meaning of the code.

Markus Mottl

unread,
Feb 20, 2001, 5:51:14 AM2/20/01
to
Neelakantan Krishnaswami <ne...@alum.mit.edu> wrote:
> Here's some pragmatic advice, rather than theoretical. The problem I
> have with folds in dynamically typed languages is that I am prone to
> getting the order of arguments wrong.

Yes, I think this is one of the main sources of errors with higher-order
functions. Static type checkers can almost always (unfortunately not
always) spot those.

> However, all my errors basically
> go away instantly even in a dynamically typed language if I have
> keyword arguments.

I agree again: this shows how important it is for the *human* that the
code gives him more hints to verify his mental image: if you have to
write a label next to the expression to which it refers, this makes
it more explicit what you are thinking of. This is also the reason why
unnamed functions should be avoided - out of psychological reasons.

Andrew Cooke

unread,
Feb 20, 2001, 6:34:34 AM2/20/01
to

Sean Hinde wrote:
> It occurred to me to wonder whether a style of programming which is so
> mindbending that it requires help from a static typechecker to stand any
> hope of working is neccessarily a good thing for the productivity of mortal
> programmers.

It's only mindbending if you have to keep many different levels of
abstraction in your head at once. Static types are a way of avoiding
this - you no longer have to think "Hmmm, this is a filter that maps an
image to an image and an image takes a point and produces a colour so
this really takes an image and a point and returns a colour which means
this takes a function that takes a tuple of Doubles and returns a Clr
Double and..." to work out why something isn't working.

Instead, you get a high-level error message that makes things nice and
clear at the same level of abstraction you are working at. In contrast,
when I was debugging similar code in Lisp I kept having to look at
low-level details, work out what kind of structure that was, and then
translate back up to the high level component etc etc (I guess using
classes or structs rather than tuples and lists would help).

Unfortunately, in my limited experience, this can break down a little
with Haskell when type aliases are used as they seem to be treated more
as syntactic sugar that can get lost in errors - I seem to get error
messages referring to lower level types. But that might be just me
doing something wrong or getting confused.

Andrew

George Russell

unread,
Feb 20, 2001, 6:48:19 AM2/20/01
to
Andrew Cooke wrote:
[snip]

> Instead, you get a high-level error message that makes things nice and
> clear at the same level of abstraction you are working at. In contrast,
> when I was debugging similar code in Lisp I kept having to look at
> low-level details, work out what kind of structure that was, and then
> translate back up to the high level component etc etc (I guess using
> classes or structs rather than tuples and lists would help).
>
> Unfortunately, in my limited experience, this can break down a little
> with Haskell when type aliases are used as they seem to be treated more
> as syntactic sugar that can get lost in errors - I seem to get error
> messages referring to lower level types. But that might be just me
> doing something wrong or getting confused.
[snip]

RANT MODE ON. Yes indeed. I found SML/New Jersey's type errors confusing
enough, but when you get Haskell's class inference going on as well, type
error messages become really difficult. If we ever want functional programming
languages to become popular, this problem is going to have to be addressed.
I think that if the Pentagon* were paying me to develop a user-friendly Haskell
type-error-message-reporter I would concentrate on two things:
(1) it should be possible to open a window containing the source,
point at a variable and ask "All right, what type
do you think this is then?" At the moment the best approach without this
(which I recommend) is to put in explicit type annotations and see where the
compiler falls over, but this still can be cumbersome.
(2) I think to help the user debug type class woes, the causes of which are
Legion, you probably need something quite sophisticated, like an expert system
or Bayesian analysis or both. More research is needed . . .

* - or Microsoft, maybe?

George Russell

unread,
Feb 20, 2001, 7:05:21 AM2/20/01
to
Andreas Rossberg wrote:
[snip]

> > There are also some things which various ML compilers do not do because they are quite
> > tricky, for example handling the "and" in
> > signature A = sigexp where type a=b and type c=d
> > as against
> > signature A = sigexp where type a=b and C = sigexp2.
>
> This is doable even in LALR(1), but requires some rather ugly and
> tedious grammar transformations.
Yes I know, I've done it.

>
> BTW, you forgot to mention the most annoying example:
>
> fun f x 0 = case z of p => a
> | q => b
> | f x y = c
>
> Did any SML system ever get this parsed?
>
> On the other hand, Haskell's parsing-error-terminates-layout rule is
> unimplementable. I remember the OCaml grammar producing some 300
> shift/reduce conflicts when fed to Yacc. And don't mention C and
> friends. So I think SML's grammar is not that bad after all, even though
> it is definitely the worst part of the spec (well, besides overloading).
I agree that many other languages are not wonderful either. But it's a pity
that the Definition of SML didn't get it right, given that LALR grammars are not
exactly rocket science these days.

Peter Hancock

unread,
Feb 20, 2001, 7:08:15 AM2/20/01
to
>>>>> "Andrew" == Andrew Cooke <and...@andrewcooke.free-online.co.uk> writes:

> Sean Hinde wrote:
>> It occurred to me to wonder whether a style of programming which is so
>> mindbending that it requires help from a static typechecker to stand any
>> hope of working is neccessarily a good thing for the productivity of mortal
>> programmers.

> It's only mindbending if you have to keep many different levels of
> abstraction in your head at once.

To me, that's the core of the difficulty of programming.

> Static types are a way of avoiding
> this -

"Avoid" is going too far, surely. "Help deal with this" might be better.

What you said was really interesting. It hadn't occurred to me that
types help with multiple levels of abstraction.

You focus on comprehensible error messages. Really? And you've been
using Haskell? Which implementation?

Peter Hancock

unread,
Feb 20, 2001, 7:19:50 AM2/20/01
to
>>>>> "George" == George Russell <g...@tzi.de> writes:

> (1) it should be possible to open a window containing the source,
> point at a variable and ask "All right, what type
> do you think this is then?"

Funnily enough, there's a snazzy editor/PDE for a language a bit like
Cayenne, which allows you to do almost exactly that. (Thomas
Hallgren's Alfa.)

Having used this system, I've really missed it when programming in Haskell.
It's really useful (maybe even essential) with dependent types.

I want to be able to have "holes" in a program, with the type checker
keeping track of the type constraints as you fill them in.

I agreed with what you said about Haskell's class system making error messages
impenetrable.

Which implementation gives the best error messages?

Andrew Cooke

unread,
Feb 20, 2001, 8:10:21 AM2/20/01
to

Assuming only the second of these last two paragraphs is ironic, I've
been using hugs + ghc just because they are what I found in Debian. ghc
seems to have the better errors (imho), but if I can't sort things out I
load tehs ource into hugs and try typing sub-expressions until I get
something that works (with random insertions of fromIntegral, usually).
On very bad occassions I've actually written the sub-expression that I
can't get hugs to accept back into source and run ghc on it to get a
better error message.

I can't understand why hugs doesn't give me the (or rather "a", given
type aliases and classes) type for an expression that I type in - this
is a useful feature of ML that seems like it should be easy to
implement.

But much of the problems I've had are down to overloading, and I'd
rather have overloading and problems than no overloading. It's the
curious neither-here-nor-there status of type aliases that annoys me
more (again with the rider that at the moment it's more likely I'm
misunderstanding things than a "real" problem).

Andrew

Peter Hancock

unread,
Feb 20, 2001, 8:16:00 AM2/20/01
to
>>>>> "Andrew" == Andrew Cooke <and...@andrewcooke.free-online.co.uk> writes:
> I can't understand why hugs doesn't give me the (or rather "a", given
> type aliases and classes) type for an expression that I type in - this
> is a useful feature of ML that seems like it should be easy to
> implement.

In case you don't know, if you type ":t (expression) " or something
like that, you get the type. (Try typing :?.)

Andrew Cooke

unread,
Feb 20, 2001, 8:43:56 AM2/20/01
to

excellent! thanks! :-)

Andreas Rossberg

unread,
Feb 20, 2001, 8:43:47 AM2/20/01
to
Andrew Cooke wrote:
>
> ghc seems to have the better errors (imho)

:-)

> I can't understand why hugs doesn't give me the (or rather "a", given
> type aliases and classes) type for an expression that I type in

It does, but you have to use the :t command:

Prelude> :t 5+6
5 + 6 :: Num a => a
Prelude>

- Andreas

Matthias Blume

unread,
Feb 20, 2001, 10:02:22 AM2/20/01
to
Neelakantan Krishnaswami wrote:
>
> On Mon, 19 Feb 2001 23:43:40 -0000, Sean Hinde <shind...@one2one.co.uk>
> wrote:
> >
> > The reason often given for the requirement for a static type system
> > in functional languages is that it is very difficult to write deeply
> > nested maps and folds of functions of partially curried functions
> > of.. etc without the support of a static type checker. I don't doubt
> > that this is true as I have just spent some time trying to write in
> > that style in Erlang and it took me some time to get a fairly simple
> > tool working.
>
> Here's some pragmatic advice, rather than theoretical. The problem I
> have with folds in dynamically typed languages is that I am prone to
> getting the order of arguments wrong. However, all my errors basically
> go away instantly even in a dynamically typed language if I have
> keyword arguments.

Of course, keyword arguments being a form (however weak) of static typing...

Cheers,
Matthias

Marcin 'Qrczak' Kowalczyk

unread,
Feb 20, 2001, 11:25:27 AM2/20/01
to
20 Feb 2001 13:16:00 +0000, Peter Hancock <p...@dcs.ed.ac.uk> pisze:

> In case you don't know, if you type ":t (expression) " or something
> like that, you get the type.

You can also type
:set +t
and then type expressions.

--
__("< Marcin Kowalczyk * qrc...@knm.org.pl http://qrczak.ids.net.pl/
\__/
^^ SYGNATURA ZASTĘPCZA
QRCZAK

John van Groningen

unread,
Feb 21, 2001, 6:04:24 AM2/21/01
to
In article <96ja5h$l6sp7$1...@ID-23354.news.dfncis.de>, "Siegfried Gonzi"
<siegfri...@kfunigraz.ac.at> wrote:

> ...
> No nonsense. A FFT (a normal FFT without tuned code) in Clean (okay the code
> was not mine; but it used all the "tricks": if you are interested in I can
> point you to that online manual which discusses that FFT code
> implementation) with 2^18 array elements (one dimensional array) takes on my
> 100MHZ 603e Mac (with 256KB L2 and 64MB RAM) 120sec! And 60sec of that time
> is due to garbage collection.
>
> With Mops it takes 20sec (but even that is not optimal); 5 to 10 sec would
> be optimal.

This FFT is far from optimal. On a 450 Mhz G4 Macintosh it takes 10.6
seconds using the copying garbage collector and 9.3 seconds with the
marking collector.

A naive version of the FFT implemented using lists and the sine and cosine
computations in the main 'loop' (but with strictness annotations) is about
as fast (11.0 and 8.8 seconds).

The slow performance (of the first program) is caused by using arrays of
possibly unevaluated boxed reals ({Real}) instead of arrays of unboxed
reals ({#Real}).
If you add the following type for function 'forThisBlock':

forThisBlock :: !Int !Int !Real !Real !*{#Real} !*{#Real}
-> (!{#Real},!{#Real});

and change function 'FFT' into:

FFT re = power (Fourier (2.0*3.14159265) re im);
where {
im :: *{#Real};
im = createArray (size re) 0.0
};

the program runs in 3.9 seconds (copying gc) or 3.4 seconds (marking gc).

An fft using arrays I wrote runs in 2.2 seconds (also for 2^18 complex
double precision reals). By improving the memory access pattern (to reduce
the number of cache misses), this time was reduced to 1.0 second.

>..
> >> dd) Even Clean is written in C. Exercise:
> >
> >No, the new release is rewritten in Clean itself.
>
> As far as I am informed is only the development environement written in
> Clean. Clean kernel itself stayed unchanged in C.

No, the front end of the Clean 2.0 compiler (everything before strictness
analysis) is written in Clean.

Regards,
John van Groningen

Brian Rogoff

unread,
Feb 22, 2001, 12:25:18 PM2/22/01
to
On Tue, 20 Feb 2001, George Russell wrote:
> RANT MODE ON. Yes indeed. I found SML/New Jersey's type errors confusing
> enough, but when you get Haskell's class inference going on as well, type
> error messages become really difficult.

Interesting. Earlier you stated that, inasmuch as extant FPLs have either
ML style modules or Haskell style type classes, that you preferred the
latter on account of their lower complexity. Is that still the case? If
so, then you must like the capability a lot if it offsets this dislike.
This seems like yet another one of those "great debates" of FP, like
static/dynamic, lazy/strict, pure/impure except it's not really like
modules and type classes are "opposite" in some way.

I agree that the error diagnosis capabilities of many FP implementations
leave a lot to be desired. Of course, if you're shooting for a 25 KLOC
front end I don't imagine the error handling will ever be that good :-).

-- Brian


George Russell

unread,
Feb 22, 2001, 1:04:32 PM2/22/01
to
Brian Rogoff wrote:
>
> On Tue, 20 Feb 2001, George Russell wrote:
> > RANT MODE ON. Yes indeed. I found SML/New Jersey's type errors confusing
> > enough, but when you get Haskell's class inference going on as well, type
> > error messages become really difficult.
>
> Interesting. Earlier you stated that, inasmuch as extant FPLs have either
> ML style modules or Haskell style type classes, that you preferred the
> latter on account of their lower complexity. Is that still the case? If
> so, then you must like the capability a lot if it offsets this dislike.
[snip]
This inference is correct. I think the functionality of type classes way
outweighs the trouble I have getting them through the type checker.
Of course others have every right to disagree, especially if their experience
differs.

In the same way I think the convenience of polymorphism and type inference
outweighs the fact that it also can produce fairly horrible error messages.
(Though not as bad as can happen when type classes are in the game as well.)

Sean Hinde

unread,
Feb 23, 2001, 9:46:28 AM2/23/01
to

"Markus Mottl" <mo...@miss.wu-wien.ac.at> wrote in message
news:96thr0$955$1...@bird.wu-wien.ac.at...
> Sean Hinde <shind...@one2one.co.uk> wrote:

> I disagree here: the reason why the static type checker is needed is not
> that these constructs are so mindbending, but rather that it can be very
> easy to e.g. pass parameters in the wrong order, pick the wrong variable
> to work with, etc.

OK, You have much more experience of this than me

> If I read through my previous sources, I find my high-level constructs
> much more readable than the ones where I use explicit recursion or
> else. The reason is that one can see what is meant without having to fully
> follow the order of parameters in detail. This, however, also depends on
> the general style of programming: using named functions instead of lambdas
> usually greatly improves readability, because you don't have to read (and
> understand) the body of the lambda - the name should speak for itself.

If you are talking about simple HOFs using maps and folds over regular lists
then I do agree and use them in my own Erlang code. Erlang also allows one
to make lists of arbritrary terms of any type at all. I generally find it
easier and clearer to write my own recursion to deal with all the different
actions (or even side affects) resulting from matching any arbritrary entry
(including breaking out of the recursion at arbritrary places). I don't
think this sort of thing is even possible in most statically typed FPLs.

I must also say that it took me some time even after writing some reasonably
complex code to get to the point where I felt ready to commit to my first
fun. It is a declared objective of Erlang to be extremely easy to learn: I'd
say that most Erlang programmers get used to doing it in the nice easy
vanilla style so they really understand recursion before getting heavily
into the higher order stuff (and therefore are quoted to be productive in
less than a month). The emphasis with other FPLs seems to be very much in at
the deep end. (But that is probably another thread).

> > main(Input) ->
> > {ok, A, B, C} = do_stuff({in, Input}),
> > {ok, D, E} = do_some_more(B, C),
> > {ok, A, D, E}.
>
> Why do you think that this is so much different from other functional
> languages? I don't see how Erlang encourages a more declarative style
> of programming here.

Can you provide an example of a function which looks like this in say
O'Caml? I am a bit lost in lets and dos at the moment.

> Maybe we should consider a real example:
>
> let nts_in_sym acc = function NT nt -> NTSet.add nt acc | _ -> acc
> let nts_in_prod (_, syms) acc = List.fold_left nts_in_sym acc syms
> let nts_in_nt nt prods acc = ProdSet.fold nts_in_prod prods (NTSet.add
nt acc)
> let nts_in_grammar gr = NTMap.fold nts_in_nt gr NTSet.empty
>

> Take a look at the last line: if you are used to reading fold-heavy code,
> this reads "collect all nts for each nt in grammar gr starting with the
> empty set of nonterminals". The same applies to the other folds. I'd be
> very surprised if a version without higher-order functions made things
> clearer, but you are welcome to contribute one...

This looks very nice. Exactly the sort of problem all this is designed to
solve no doubt :)

I guess that the typical problem domain of Erlang and most of the OTP
applications included with the distribution doesn't predominantly involve
processing of these nice structures (only perhaps the various compilers and
these don't appear to use HOFs). Much of OTP deals with "messy" data and
highly complex concurrency problems rather than lots of nice good fun list
twiddling...

There is at the moment a concurrent thread on the Erlang mailing list (which
appears to have asynchronous message passing with this thread ! ) about use
of HOF in Erlang. This was kicked off by a newbie question and resulted in a
storm of learned debate about recommended use of HOF and dynamic code
change. The conclusion seemed to be use Funs for short lived simple maps and
folds but not for much else.

Maybe as the usage of the language develops outside the telecoms domain we
will see the use of HOFs in more sophisticated ways become more and more
part of the everyday vernacular.. And then we'll need that type checker :).

> It is important to note that there are many different types in this
> code: terminals, nonterminals, maps and sets of nonterminals, sets of
> productions, lists of symbols, etc. Without a static type system, it
> could be very easy to make stupid little mistakes even if the intended
> meaning of the code seems obvious. I use the static type checker to
> verify my mental image of the code rather than to reduce the complexity
> of higher-order functions (which are not problematic as such).

I'm absolutely in favour of anything which make my code easier to maintain
and have fewer bugs. Static type checking is part of that and I'm all in
favour (hence my interest in any other FPLs). Deeply nested HOFs I'm less
convinced about though your example is persuasive for that sort of problem..

I am certainly looking forward to the outcome of various Erlang research
projects:

Formal Verification http://www.sics.se/fdt/Erlang/ (Code written in ML and
Java).

Erlang Type system http://www.csd.uu.se/~svenolof/analyze-erlang.ps.gz

- Sean


Markus Mottl

unread,
Feb 23, 2001, 11:30:26 AM2/23/01
to
Sean Hinde <shind...@one2one.co.uk> wrote:
[snip]

> I generally find it easier and clearer to write my own recursion to
> deal with all the different actions (or even side affects) resulting
> from matching any arbritrary entry (including breaking out of the
> recursion at arbritrary places).

It is always a good idea to find out whether there are common patterns
that one can factor out of ones code, including HOF-patterns. My favourite
HOF is "fold", because you can replace many other HOFs with it: iteration
(accumulator is "()"), "map", "rev" and many others. This makes it a very
good choice in interfaces if you have a fancy datastructure and don't
want to implement all the other stuff: the user can still do almost
everything with it.

> I don't think this sort of thing is even possible in most statically
> typed FPLs.

What is not possible? If you mean breaking out of recursions, this is
certainly possible: use exceptions.

[snip]


> I'd say that most Erlang programmers get used to doing it in the nice
> easy vanilla style so they really understand recursion before getting
> heavily into the higher order stuff (and therefore are quoted to be
> productive in less than a month). The emphasis with other FPLs seems to
> be very much in at the deep end. (But that is probably another thread).

No, I don't think so. Why should anybody want to start with HOFs before
having seen recursion (no matter what the language)? And yes, I think
most people can get productive within a month in (most) FPLs if they
seriously try to learn it.

There is even a paper on prototyping that compares several (many)
languages with Haskell and shows that Haskell indeed allows beginners
to get productive fast:

http://www.haskell.org/practice.html

Read "Haskell vs. Ada vs. ...".

>> > main(Input) ->
>> > {ok, A, B, C} = do_stuff({in, Input}),
>> > {ok, D, E} = do_some_more(B, C),
>> > {ok, A, D, E}.
>>
>> Why do you think that this is so much different from other functional
>> languages? I don't see how Erlang encourages a more declarative style
>> of programming here.

> Can you provide an example of a function which looks like this in say
> O'Caml? I am a bit lost in lets and dos at the moment.

I assume that "ok" is some kind of atom: if it is not matched, execution
will somehow abort or similar, right? I leave this away in the ML-code,
because you can use normal exceptions to indicate what goes wrong, which
may be a cleaner way to do it. You *could* even do it the Erlang-way,
but this would give you tons of warnings, because the compiler knows that
you are only partially matching against some atom (this is evil). You
could turn these warnings off, but I strongly recommend you (from own
experience): mistrust yourself, trust the compiler...

let main input =
let a, b, c = do_stuff input in
let d, e = do_some_more b c in
a, d, e

You can, of course, catch possible exceptions in other code parts...

>> Take a look at the last line: if you are used to reading fold-heavy code,
>> this reads "collect all nts for each nt in grammar gr starting with the
>> empty set of nonterminals". The same applies to the other folds. I'd be
>> very surprised if a version without higher-order functions made things
>> clearer, but you are welcome to contribute one...

> This looks very nice. Exactly the sort of problem all this is designed to
> solve no doubt :)

Do I hear a slight criticism here that this kind of application domain
(formal grammars) is "not really useful" (assuming that only ATM-switches
are "real world")?

You might want to know that the mentioned code is part of a machine
learning system that is intended to solve pretty complex real world
problems (still under heavy development, but it has already proven
its usefulness).

> I guess that the typical problem domain of Erlang and most of the OTP
> applications included with the distribution doesn't predominantly involve
> processing of these nice structures (only perhaps the various compilers and
> these don't appear to use HOFs). Much of OTP deals with "messy" data and
> highly complex concurrency problems rather than lots of nice good fun list
> twiddling...

I think the biggest misunderstanding that people from the "real world"
about academic work too often have is that "formal" <> "useful". The
main reason why one wants to use formal things is to be able to get
representations of the world which can be manipulated by computers more
easily. Especially in my application domain it shows immediately if you
pick wrong formalizations: performance of machine-learning systems then
simply sucks...

Maybe many of the things that you found "messy" so far were only
so, because nobody has yet managed (or even tried) to find good
formalizations?

> I'm absolutely in favour of anything which make my code easier to maintain
> and have fewer bugs. Static type checking is part of that and I'm all in
> favour (hence my interest in any other FPLs). Deeply nested HOFs I'm less
> convinced about though your example is persuasive for that sort of problem..

Especially if datastructures become very complicated, you will be happy
to have higher-order functions. E.g. you want to map a function over a
binary tree: would you really want to use explicit recursion for every
application? This would be tremendously error-prone, and there are
without doubt datastructures that are significantly more complicated
than binary trees (not even to mention lists).

Ulf Wiger

unread,
Feb 23, 2001, 12:21:33 PM2/23/01
to
>>>>> "-" == Markus Mottl <mo...@miss.wu-wien.ac.at> writes:

-> I assume that "ok" is some kind of atom: if it is not matched,
-> execution will somehow abort or similar, right? I leave this away
-> in the ML-code, because you can use normal exceptions to indicate
-> what goes wrong, which may be a cleaner way to do it.

Typical Erlang programs are written in line in line with the
"let it crash" philosophy, meaning that you specify the correct
behaviour in your program in such a way that erroneous results will
trigger a run-time error. (if not caught, ) This causes the process
to crash. It is then restarted by a supervisor process. This often
takes care of the problem, and is a very nice way of implementing
robustness in a non-stop system. If the restart doesn't solve the
problem, you get very explicit problem reports, which help you
identify and solve the problem by hand.

In our experience, most problems arise from misunderstanding of
requirements, or from unanticipated situations (which are legion
in complex, massively concurrent systems.)


-> I think the biggest misunderstanding that people from the "real
-> world" about academic work too often have is that "formal" <>
-> "useful".

I personally don't think I do, but perhaps I should leave that for
others to judge. (:

What I do find in this particular "real world", namely industrial
programming, is that -- to be blunt -- time to market is everything.
While this doesn't preclude formal methods by any means, it is
always scary to bet on things that have not been tested successfully
in a commercial environment (or more specifically: in _your own_
type of commercial environment). Even Erlang, having been invented at
Ericsson, had to struggle for acceptance as something other than
a research vessel.

You'll be glad to know that we (AXD 301 = the real world ;) are
actively working with researchers to introduce more formal methods
into our existing environment. I'm sure we will learn a lot on both
sides.

/Uffe
--
Ulf Wiger tfn: +46 8 719 81 95
Senior System Architect mob: +46 70 519 81 95
Strategic Product & System Management ATM Multiservice Networks
Data Backbone & Optical Services Division Ericsson Telecom AB

Joachim Durchholz

unread,
Feb 23, 2001, 12:26:16 PM2/23/01
to
Markus Mottl <mo...@miss.wu-wien.ac.at> wrote:
>
> > Much of OTP deals with "messy" data and highly complex
> > concurrency problems rather than lots of nice good fun list
> > twiddling...
>
> [...]

>
> Maybe many of the things that you found "messy" so far were only
> so, because nobody has yet managed (or even tried) to find good
> formalizations?

Very true. Most data structures written in industry are badly formalized
*and* badly designed (in terms of "identifying the abstractions behind
some concrete set of requirements"). The problem is that building
"clean" data structures is both difficult and lots of work, so in
industry (where there's a high pressure of getting something delivered
quickly, and there's minimal allowance for thinking things over) data
structures tend to be messy indeed. The Windows API is just a very
well-known example of this; the interfaces of hardware chips aren't much
better, nor are the interfaces of ODBC drivers, SQL, or a whole lot of
other interfaces.
The problem is that once such a messy interface is in existence, it
tends to require maintenance for the next few decades :(

Regards,
Joachim
--
This is not an official statement from my employer.


Markus Mottl

unread,
Feb 23, 2001, 7:55:39 PM2/23/01
to
Ulf Wiger <Ulf....@ericsson.com> wrote:
> Typical Erlang programs are written in line in line with the
> "let it crash" philosophy, meaning that you specify the correct
> behaviour in your program in such a way that erroneous results will
> trigger a run-time error. (if not caught, ) This causes the process
> to crash. It is then restarted by a supervisor process. This often
> takes care of the problem, and is a very nice way of implementing
> robustness in a non-stop system. If the restart doesn't solve the
> problem, you get very explicit problem reports, which help you
> identify and solve the problem by hand.

It may be necessary for some systems to not crash under any circumstances
and resume operation immediately if things go wrong (or at least try
to). But doesn't it seem a bit heavy-weight to use complete processes to
handle this? A global exception handler will suffice in many occasions. Of
course, if you want to make use of redundant hardware to take over
control, things are different, but I wouldn't say that this is the
usual case.

If I remember correctly, the INRIA team used such a kind of "robustifier"
(global exception handler) in the ICFP-contest two years ago: they knew
that the judges would drop their entry if it crashed on a test set. So
they always kept a valid (not necessarily optimal) answer in a cache and
could therefore try to resume operation or print out the cached solution
if required (e.g. if an uncaught exception escaped the system).

> In our experience, most problems arise from misunderstanding of
> requirements, or from unanticipated situations (which are legion
> in complex, massively concurrent systems.)

Agreed.

> What I do find in this particular "real world", namely industrial
> programming, is that -- to be blunt -- time to market is everything.

Yes, this is not new to me...

The fierce competition unfortunately slows down innovation, because
companies just don't have time to invest significantly into R&D: others
could grab their market share and then the game's up.

This usually leads to ad-hoc solutions. As one colleague who works for
a major software company put it: things are released as soon as the
features kind of work. The rest is left to maintainance and support...

> While this doesn't preclude formal methods by any means, it is
> always scary to bet on things that have not been tested successfully
> in a commercial environment (or more specifically: in _your own_
> type of commercial environment). Even Erlang, having been invented at
> Ericsson, had to struggle for acceptance as something other than
> a research vessel.

It may be difficult to convince management that formal methods are not
just like "other" methods. They may initially require more resources,
but usually pay off greatly in the long run. But as managers might say
in such occasions: in the long run we are all dead (J.M. Keynes used
this quote in a different context, though)...

> You'll be glad to know that we (AXD 301 = the real world ;) are
> actively working with researchers to introduce more formal methods
> into our existing environment. I'm sure we will learn a lot on both
> sides.

This is a great idea! Let's see what will come out - maybe in a few
years we will have Erlang with static typing :-)

Sean Hinde

unread,
Feb 23, 2001, 8:24:21 PM2/23/01
to

"Markus Mottl" <mo...@miss.wu-wien.ac.at> wrote in message
news:976372$d2k$1...@bird.wu-wien.ac.at...

> Sean Hinde <shind...@one2one.co.uk> wrote:
> [snip]

> What is not possible? If you mean breaking out of recursions, this is
> certainly possible: use exceptions.

I meant having arbitrary collections of different data structures and types
in a single list. Type classes in Haskell seem to provide a way to do this
but at the expense of much extra work to come up with a static type for all
possible things we will ever want to put there.

> [snip]


> >> > main(Input) ->
> >> > {ok, A, B, C} = do_stuff({in, Input}),
> >> > {ok, D, E} = do_some_more(B, C),
> >> > {ok, A, D, E}.
> >>

[snip]


> I assume that "ok" is some kind of atom: if it is not matched, execution
> will somehow abort or similar, right? I leave this away in the ML-code,
> because you can use normal exceptions to indicate what goes wrong, which
> may be a cleaner way to do it. You *could* even do it the Erlang-way,
> but this would give you tons of warnings, because the compiler knows that
> you are only partially matching against some atom (this is evil). You
> could turn these warnings off, but I strongly recommend you (from own
> experience): mistrust yourself, trust the compiler...

Yep. The ok is an atom and is designed to cause an exception if do_stuff
really breaks. Variables start with upper case and atoms with lower case
(another Erlang feature I like - The variables Leap out of the page).

Matching the ok is used as an early warning of runtime problems - "Let it
Crash early" is an often recommended way to assist finding any errors in an
Erlang program. (If a real Erlang system encounters a crash like this in
service it will be localised to one thread which is automatically restarted
by a supervisory tree of other threads. This goes for all runtime errors -
not just type errors). It is not perfect but it does help to find the vast
majority of errors on the first run of the program (a few seconds after the
type checker would :) ), and almost all other errors are simply not fatal to
the system.

Simply put these things are the ploy used to quickly find the bugs a static
type checker would. And they work well.

> let main input =
> let a, b, c = do_stuff input in
> let d, e = do_some_more b c in
> a, d, e

Thanks. I now see how this let .. in stuff works. The solution seemed
immediately obvious when I learnt Erlang. Hmm, why.. Probably because I
didn't need to reason about the 'in' business (in what? what is in it? do I
need to keep all these in's in my mind at once? Let alone what is the
objective..). The question didn't even raise itself with Erlang; all I did
was unquestioningly program as I would in awk or any other normal looking
imperative language - except there was a comma separator rather than a
semicolon, and I could only use the variable once.

The point is I felt immediately at home.

> Do I hear a slight criticism here that this kind of application domain
> (formal grammars) is "not really useful" (assuming that only ATM-switches
> are "real world")?

You might have :)

> You might want to know that the mentioned code is part of a machine
> learning system that is intended to solve pretty complex real world
> problems (still under heavy development, but it has already proven
> its usefulness).

Sounds nice.

> I think the biggest misunderstanding that people from the "real world"
> about academic work too often have is that "formal" <> "useful". The
> main reason why one wants to use formal things is to be able to get
> representations of the world which can be manipulated by computers more
> easily. Especially in my application domain it shows immediately if you
> pick wrong formalizations: performance of machine-learning systems then
> simply sucks...
>
> Maybe many of the things that you found "messy" so far were only
> so, because nobody has yet managed (or even tried) to find good
> formalizations?

Ok. I'm getting somewhere. You (and Joachim - thanks) are explaining how one
of the true benefits of all this stuff works in practice. That is that if
you provide tools which make it easier for the programmer to create
beautiful data structures then they are much more likely to do so, and
therefore produce programs which will have less spaghetti, require less
maintenance and be easier to change. I can live with that!

> > I'm absolutely in favour of anything which make my code easier to
maintain
> > and have fewer bugs. Static type checking is part of that and I'm all in
> > favour (hence my interest in any other FPLs). Deeply nested HOFs I'm
less
> > convinced about though your example is persuasive for that sort of
problem..
>
> Especially if datastructures become very complicated, you will be happy
> to have higher-order functions. E.g. you want to map a function over a
> binary tree: would you really want to use explicit recursion for every
> application? This would be tremendously error-prone, and there are
> without doubt datastructures that are significantly more complicated
> than binary trees (not even to mention lists).

It seems that huge amount of research into static typing is getting to a
conclusion and soon it will become de-rigeur for languages to have generic
types and static typing (even Java it seems).

I am interested to see what comes next. Much more research into concurrency
would be nice. The research into automatic verification looks very
interesting. I wonder if we will create higher and higher level languages or
abstractions for specific problem areas so that ever more complex systems
can be reasoned about and maintained by smaller numbers of programmers (with
the tool itself formally verified).

Sleep required!

- Sean


Markus Mottl

unread,
Feb 24, 2001, 8:59:45 AM2/24/01
to
Sean Hinde <shind...@one2one.co.uk> wrote:
> I meant having arbitrary collections of different data structures and types
> in a single list. Type classes in Haskell seem to provide a way to do this
> but at the expense of much extra work to come up with a static type for all
> possible things we will ever want to put there.

You can certainly have those, e.g.:

let lst = [`Int 42; `String "Foo"; `Whatever (Some 3.14)]

You have to tag the data, of course, but you need not necessarily declare
a type: polymorphic variants are pretty elegant here.

Still, IMHO one of the reasons why things can go wrong in "real world"
projects is that people just don't write down clear specifications of
their datastructures, not even as comment. But if you do so using the
type system, you get verification of the sound use of this specification
for free.

> It is not perfect but it does help to find the vast majority of
> errors on the first run of the program (a few seconds after the type
> checker would :) ), and almost all other errors are simply not fatal
> to the system.

The reason why you think that errors show up after a few seconds is
probably that you haven't yet found all bugs in your programs... ;)

Honestly, for my application domain it is just not good enough to "wait
for things to crash". It may well happen that the system computes on and
on with values that only seem to make sense but really have the wrong
type. E.g., you hand around a list in the assumption that it is sorted,
but it isn't. Users will trust the result, which might have disastrous
consequences.

> Simply put these things are the ploy used to quickly find the bugs a
> static type checker would. And they work well.

The really nasty logical errors show up too late. Using static type
checking to enforce logical consistency saves me hours of work debugging
my sources. In fact, I haven't yet used the debugger for real work so
this is only an estimate...

> Ok. I'm getting somewhere. You (and Joachim - thanks) are explaining how one
> of the true benefits of all this stuff works in practice. That is that if
> you provide tools which make it easier for the programmer to create
> beautiful data structures then they are much more likely to do so, and
> therefore produce programs which will have less spaghetti, require less
> maintenance and be easier to change. I can live with that!

Yes, that's it. An expressive type system with automatic type inference
just makes it much easier to specify things. I can easily imagine that
people used to programming in dynamic languages consider it less of a
benefit to write down clear specifications, because (as they think) nobody
will read them anyway. In statically typed languages it's the compiler
that reads your specifications and verifies your code against them.

> I am interested to see what comes next. Much more research into concurrency
> would be nice.

It's happening - in fact I'd say that this field is currently under
heavy research.

Sean Hinde

unread,
Feb 25, 2001, 8:56:58 AM2/25/01
to

"Markus Mottl" <mo...@miss.wu-wien.ac.at> wrote in message
news:978eoh$2t9$1...@bird.wu-wien.ac.at...

> Sean Hinde <shind...@one2one.co.uk> wrote:
> > It is not perfect but it does help to find the vast majority of
> > errors on the first run of the program (a few seconds after the type
> > checker would :) ), and almost all other errors are simply not fatal
> > to the system.
>
> The reason why you think that errors show up after a few seconds is
> probably that you haven't yet found all bugs in your programs... ;)

I do not believe that I will ever find all possible bugs in my programs. I
also do not believe that a static type checker will guarantee that I will
find all my bugs (I don't think anyone ever quite got away with that claim
for static type checking).

So, for a long running system (AXD - fair example) it is simply not good
enough to assume that there are no bugs which can cause a crash. The very
successful approach to this in Erlang is to have a tree structure of linked
supervisor processes which simply restart the broken part of the system with
almost no overall service impact. This is what I meant by almost no other
errors being fatal to the system. It an elegant yet pragmatic solution, and
covers more than just type errors.

> Honestly, for my application domain it is just not good enough to "wait
> for things to crash".

But you are writing a program which runs and produces a result of some
calculation. That is fine but is probably not what the majority of very
complex programs are designed to do (i.e. run for much longer).

> The really nasty logical errors show up too late. Using static type
> checking to enforce logical consistency saves me hours of work debugging
> my sources. In fact, I haven't yet used the debugger for real work so
> this is only an estimate...

I understand how static type checking can find certain classes of logical
errors. It does not guarantee that you get the right answer (or the answer
to the right question) ;). Particularly concurrency brings any number of new
ways for a program to be logically incorrect..

> Yes, that's it. An expressive type system with automatic type inference
> just makes it much easier to specify things. I can easily imagine that
> people used to programming in dynamic languages consider it less of a
> benefit to write down clear specifications, because (as they think) nobody
> will read them anyway. In statically typed languages it's the compiler
> that reads your specifications and verifies your code against them.

I do see the clear benefits of this for data structures and am looking
forward to being able to apply the new Erlang type analyser to my work.

Regards,

Sean


Nicholas James NETHERCOTE

unread,
Feb 26, 2001, 2:20:21 AM2/26/01
to
"Sean Hinde" <shind...@one2one.co.uk> writes:

>"Markus Mottl" <mo...@miss.wu-wien.ac.at> wrote in message
>news:978eoh$2t9$1...@bird.wu-wien.ac.at...
>> Sean Hinde <shind...@one2one.co.uk> wrote:
>> > It is not perfect but it does help to find the vast majority of
>> > errors on the first run of the program (a few seconds after the type
>> > checker would :) ), and almost all other errors are simply not fatal
>> > to the system.
>>
>> The reason why you think that errors show up after a few seconds is
>> probably that you haven't yet found all bugs in your programs... ;)

>I do not believe that I will ever find all possible bugs in my programs. I
>also do not believe that a static type checker will guarantee that I will
>find all my bugs (I don't think anyone ever quite got away with that claim
>for static type checking).

But the static type checker will immediately find every type error that's in an
obscure corner of the program that only gets executed on one in a million
cases, which I believe is Markus's point.

--
Nick Nethercote
n...@cs.mu.oz.au

Jerzy Karczmarczuk

unread,
Feb 26, 2001, 4:15:56 AM2/26/01
to
Markus Mottl wrote:

{Just a fragment of a long discussion}

> ... Why should anybody want to start with HOFs before


> having seen recursion (no matter what the language)? And yes, I think
> most people can get productive within a month in (most) FPLs if they
> seriously try to learn it.

Higher-order functions are MUCH OLDER than the implementation of
recursion.

They are vital for all numerists who want to have generic integration
codes (of any function).

Generic sorting based on "plugged-in" comparison function is another
example.

An operating system loader is a higher-order function whose arguments
are user/system modules.

This list may be longer. I don't see too many reasons to try to
establish too strong links between H.O.F and functional programming
(as we understand it now). Of course, the programmers' psychology is
another issue...


Jerzy Karczmarczuk
Caen, France

Ulf Wiger

unread,
Feb 26, 2001, 3:46:09 AM2/26/01
to
>>>>> "-" == Markus Mottl <mo...@miss.wu-wien.ac.at> writes:

-> Ulf Wiger <Ulf....@ericsson.com> wrote:
>> Typical Erlang programs are written in line in line with the
>> "let it crash" philosophy, meaning that you specify the correct
>> behaviour in your program in such a way that erroneous results
>> will trigger a run-time error. (if not caught, ) This causes the
>> process to crash. It is then restarted by a supervisor
>> process. This often takes care of the problem, and is a very nice
>> way of implementing robustness in a non-stop system. If the
>> restart doesn't solve the problem, you get very explicit problem
>> reports, which help you identify and solve the problem by hand.

-> It may be necessary for some systems to not crash under any
-> circumstances and resume operation immediately if things go wrong
-> (or at least try to). But doesn't it seem a bit heavy-weight to
-> use complete processes to handle this? A global exception handler
-> will suffice in many occasions. Of course, if you want to make
-> use of redundant hardware to take over control, things are
-> different, but I wouldn't say that this is the usual case.

I don't know if it's that heavyweight. We have 3-500 static processes
per node (processor), and 1-300 dynamic ones.

In some cases, we implement special error handling in a process.
A call control thread, for example needs to make sure that any
resources that have been allocated are released again. While the
presumably most "Erlang-ish" way would be to have the resource handler
monitor the call handling thread, and free any resources belonging to
that thread, we opt to have a single error handler for this particular
type of thread. This error handler will free any resources and, if
the protocol specification requires it, notify the user.

In other words, we have a generic error handling mechanism which works
without requiring much at all in terms of programming: simply that
programmers focus on the correct case, and make sure that incorrect
cases cause a run-time exception. As you know, pattern matching
makes this kind of programming almost second nature.
In the few cases where more sophisticated error handling is called for,
we can easily achieve that by trapping the run-time exception.

-> It may be difficult to convince management that formal methods
-> are not just like "other" methods. They may initially require
-> more resources, but usually pay off greatly in the long run. But
-> as managers might say in such occasions: in the long run we are
-> all dead (J.M. Keynes used this quote in a different context,
-> though)...

I think that management is probably not too adverse towards formal
methods, but today "formal methods" is basically spelled out as UML.
And convincing people that UML just _might_ not be the answer to all
their software development woes seems, in the present climate, a bit
tricky.

Ulf Wiger

unread,
Feb 26, 2001, 3:53:31 AM2/26/01
to
>>>>> "-" == Joachim Durchholz <joac...@gmx.de> writes:

-> Markus Mottl <mo...@miss.wu-wien.ac.at> wrote:
>> > Much of OTP deals with "messy" data and highly complex >
>> concurrency problems rather than lots of nice good fun list >
>> twiddling...
>>
>> [...]
>>
>> Maybe many of the things that you found "messy" so far were only
>> so, because nobody has yet managed (or even tried) to find good
>> formalizations?

-> Very true. Most data structures written in industry are badly
-> formalized *and* badly designed (in terms of "identifying the
-> abstractions behind some concrete set of requirements"). The
-> problem is that building "clean" data structures is both
-> difficult and lots of work, so in industry (where there's a high
-> pressure of getting something delivered quickly, and there's
-> minimal allowance for thinking things over) data structures tend
-> to be messy indeed.

I've seen another picture in several projects having to tackle
large and complex problems: being fully aware that a sloppy design
will kill them in the long run, they spend too much time on top-down
modelling, trying to get everything just right... only to discover
very late (when "only the coding remained") that they either hadn't
fully understood the problem, or didn't understand how their
carefully conceived models would execute once fully implemented.

As a result, many large projects find out too late that they have
serious problems in their design.

The trick is to find a good balance between careful modelling and
experimentation.

Ulf Wiger

unread,
Feb 26, 2001, 4:23:03 AM2/26/01
to
>>>>> "-" == Markus Mottl <mo...@miss.wu-wien.ac.at> writes:

-> Honestly, for my application domain it is just not good enough to
-> "wait for things to crash". It may well happen that the system
-> computes on and on with values that only seem to make sense but
-> really have the wrong type. E.g., you hand around a list in the
-> assumption that it is sorted, but it isn't. Users will trust the
-> result, which might have disastrous consequences.

Since Sean is also in the telecoms world, I think he will agree that
this certainly goes for telecoms applications as well.

One classic example is billing. One of the things we must test very
carefully is that our system will never _ever_ overbill the users
Indeed, if something goes wrong, it is a bit less terrible if the
operator receives less revenue (i.e. users are under-billed), but
for obvious reasons, our customers (the operators) don't see this
as a desirable feature.

Just to be clear: when we say "let it crash", we don't mean this
in the sense of Microsoft's let-it-crash-freeze-up-or-reboot-and-
every-now-and-again-require-a-reinstall.

I believe that we have pretty much the same philosophy: that the
code should handle the correct case, and incorrect cases must be
elimiated. We simply have different ways of accomplishing that.

-> The really nasty logical errors show up too late. Using static
-> type checking to enforce logical consistency saves me hours of
-> work debugging my sources. In fact, I haven't yet used the
-> debugger for real work so this is only an estimate...

We also have nasty logical errors to seek out and elimiate. They
usually arise from different design teams not having communicated
well enough, or from designers not fully understanding the often
complex, and sometimes even contradictory, requirements.

Having assisted some colleagues in trying to formally describe and
verify a few of our components, I'm led to believe that a type
checker simply isn't enough to identify the logical errors that
cause us the most headaches.

Also, having written some of the tricky support code for
distributed application start, redundancy, resolving database
inconsistencies on the fly, and in-service upgrade, I still
remember the headaches when trying to grasp the problem on the
drawing board first. We didn't get really good progress until
we started hacking together prototypes. We could discuss the
issues until there was no more oxygen in the room, debating what
could happen, what was very likely to happen, what we should focus
on, and what we were even required to do.

I'm not saying that formal methods, type checking, etc. are not
important, or sometimes even critical. My experience suggests that
on of the most important aspects of a language is ease of
prototyping, especially when tackling the really mind-bending
problems. Once I get my brain around it, I will want to describe
the solution more formally. I've learned that for some of these
problems, just arriving at a good formal description of the solution
is a research project in its own right. My hope is that we'll be
able to make room for both approaches and still get a product to
market in time.

Ketil Z Malde

unread,
Feb 26, 2001, 4:43:50 AM2/26/01
to
"Sean Hinde" <shind...@one2one.co.uk> writes:

> "Markus Mottl" <mo...@miss.wu-wien.ac.at> wrote:

>> What is not possible? If you mean breaking out of recursions, this is
>> certainly possible: use exceptions.

> I meant having arbitrary collections of different data structures and types
> in a single list. Type classes in Haskell seem to provide a way to
> do this

No. What you do, is define an "Any" data type as a "discriminated
union" of the types you're interested in, as in

data Any = I Int | F Float | S String

Then you can write a function that can be applied to an "Any":

do_something :: Any -> ...
do_something (I i) = ...i...
do_something (F f) = ...f...
do_something (S s) = ...s...

Now you can

list :: [Any]
:
map do_something list

> but at the expense of much extra work to come up with a static type for all
> possible things

"Much extra work"? You have to explicitly specify all the different
types you wish to store in your list, but that's about it. I know
this is a matter of opinion, but I think that both this specification,
as well as the separation of the function from the recursion makes the
code (and the intention behind it) more easy to read.

> we will ever want to put there.

("Ever"? You can easily add new type constructor to the type,
and the compiler will happily inform you where you need to update your
code elsewhere in the program.)

> It seems that huge amount of research into static typing is getting to a
> conclusion and soon it will become de-rigeur for languages to have generic
> types and static typing (even Java it seems).

The interesting thing is that it seems to me that object orientation
and static typing - at least the kind found in traditional languages -
don't mix very well.

> The research into automatic verification looks very interesting.

Is this practical - or even feasible - without solid type checking?

> I wonder if we will create higher and higher level languages or
> abstractions for specific problem areas

That's sorta the cornerstone of Lisp (and to some (lesser?) extent
other languages); let the language grow to fit the problem domain, in
essence building a domain specific language. I think it's a good
idiom, although C-brainwashed engineers tend to prefer to work the
details themselves, and scorn automatically generated code beyond what
"#define" can accomplish.

-kzm
--
If I haven't seen further, it is by standing in the footprints of giants

It is loading more messages.
0 new messages