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

Applications: Imperative vs. Functional

12 views
Skip to first unread message

Henrik Bäärnhielm

unread,
Apr 1, 1999, 3:00:00 AM4/1/99
to
Can anyone give some examples of applications where a Functional
approach is better than an Imperative one, and vice versa?


Thanks! :)

--
*****************
Henrik Bäärnhielm
d98...@d.kth.se
*****************

Henrik Bäärnhielm

unread,
Apr 9, 1999, 3:00:00 AM4/9/99
to

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 10, 1999, 3:00:00 AM4/10/99
to
Henrik =?iso-8859-1?Q?B=E4=E4rnhielm?= (d98...@d.kth.se) wrote:
: Can anyone give some examples of applications where a Functional

: approach is better than an Imperative one, and vice versa?

I think functional style is always more desirable. Would you prefer to
try to understand a function that always returned the same results for
the same inputs or one that depends on some global and/or concurrent
state modifications?

Having said that, in my experience with object oriented programming
and to a lesser extent functional programming, a sufficiently
complicated application can be well expressed in a functional style or
an imperative style equally well. For example a GUI which presents an
illusion of state to a user requires well isolated state interactions
in an imperative language like Smalltalk or Java using well known
"design patterns" (hence the book of that name). But the equivalent
GUI can be implemented in a functional programming language that is
equally expressive.

Maybe the only real decision comes down to the performance
requirements of an application, the experience of the developers in
either style or language, and the risks of failure if something new is
attempted.

--
Patrick D. Logan mailto:patric...@home.com

"I have a mind like a steel... uh... thingy."

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 10, 1999, 3:00:00 AM4/10/99
to
pat...@c837917-a.potlnd1.or.home.com wrote:

: Henrik =?iso-8859-1?Q?B=E4=E4rnhielm?= (d98...@d.kth.se) wrote:
: : Can anyone give some examples of applications where a Functional
: : approach is better than an Imperative one, and vice versa?

: Maybe the only real decision comes down to the performance


: requirements of an application, the experience of the developers in
: either style or language, and the risks of failure if something new is
: attempted.

Two other factors:

One other factor is how expressive the language is, i.e. how much code
has to be written to accomplish some unit of work, whether imperaitve
or functional.

Another major factor I have left out is how quickly the application
should be developed (and maintained after it is released). An
interactive dynamic language and environment has an edge for this
factor, balanced by the other factors.

Henrik Bäärnhielm

unread,
Apr 12, 1999, 3:00:00 AM4/12/99
to
pat...@c837917-a.potlnd1.or.home.com wrote:
> Having said that, in my experience with object oriented programming
> and to a lesser extent functional programming, a sufficiently
> complicated application can be well expressed in a functional style or
> an imperative style equally well. For example a GUI which presents an
> illusion of state to a user requires well isolated state interactions
> in an imperative language like Smalltalk or Java using well known
> "design patterns" (hence the book of that name). But the equivalent
> GUI can be implemented in a functional programming language that is
> equally expressive.

Are you saying that a GUI is a good example where a functional approach
is better than an imperative one?
I don't quite understand your argument for that... :( Can you explain a
bit more?


> Maybe the only real decision comes down to the performance
> requirements of an application, the experience of the developers in
> either style or language, and the risks of failure if something new is
> attempted.

Yes, I was thinking that the speed could be the critical thing for a
functional language, but I also read that the variables in an imperative
language represent things in the world very well, because they mark the
state of the things in a good way, and of course that's why there are
variables. In functional languages there are no variables, at least you
can't assign them values. Isn't there any application where that is used
or something, so the imperative paradigm would be better than the
functional?

Also, I can only think of 3D-graphic systems where speed is very
necessary. Isn't there any other good applications?


Thank you

Henrik Bäärnhielm

unread,
Apr 12, 1999, 3:00:00 AM4/12/99
to
pat...@c837917-a.potlnd1.or.home.com wrote:
> One other factor is how expressive the language is, i.e. how much code
> has to be written to accomplish some unit of work, whether imperaitve
> or functional.

And programs in functional languages are often an order of magnitute
shorter, isn't that right?
But can there be any difference in the size of the compiled programs?
Mustn't there always be the same machine-code?
So what applications could take advantage of how much code you have to
write? Big applications in general maybe, but are there any good
examples?

To me, it seems resonable that you need to think more for every line of
code, if you have to write a lesser amount of code, so there would not
be any difference in how fast the programs are written. Am I right?



> Another major factor I have left out is how quickly the application
> should be developed (and maintained after it is released). An
> interactive dynamic language and environment has an edge for this
> factor, balanced by the other factors.

Are there such good IDEs for both paradigms? If so, is this question
then really important for the choice of programming paradigm?
If not, what applications need to be developed quickly and maintained a
while after? To me it sounds like big applications in general, but is
there any more specific examples?


Thanks

Paul Hudak

unread,
Apr 12, 1999, 3:00:00 AM4/12/99
to Henrik Bäärnhielm
> To me, it seems resonable that you need to think more
> for every line of code, if you have to write a lesser amount
> of code, so there would not be any difference in how fast
> the programs are written. Am I right?

There was at least one study done many years ago that showed that on
large software projects the amount of code developed per day was
independent of the language used, and that the number was surprisingly
small, like around 7 LOC/day. In other words, whether you program in
assembly language, Cobol, or C, a programmer will write on average 7
lines of code per day over the long haul. (I did not include Haskell or
ML in this list because the study predated them, but I'm pretty sure it
included the Algol languages such as C and Pascal, so one might try to
extrapolate from there. Of course, there is also the issue of defining
what a LOC is...)

-Paul

--
Professor Paul Hudak
Dept of Computer Science Office: (203) 432-4715
Yale University FAX: (203) 432-0593
P.O. Box 208285 email: paul....@yale.edu
New Haven, CT 06520-8285 WWW: http://www.cs.yale.edu/~hudak.html

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 12, 1999, 3:00:00 AM4/12/99
to
Henrik =?iso-8859-1?Q?B=E4=E4rnhielm?= (d98...@d.kth.se) wrote:

: pat...@c837917-a.potlnd1.or.home.com wrote:
: > Having said that, in my experience with object oriented programming
: > and to a lesser extent functional programming, a sufficiently
: > complicated application can be well expressed in a functional style or
: > an imperative style equally well. For example a GUI which presents an
: > illusion of state to a user requires well isolated state interactions
: > in an imperative language like Smalltalk or Java using well known
: > "design patterns" (hence the book of that name). But the equivalent
: > GUI can be implemented in a functional programming language that is
: > equally expressive.

: Are you saying that a GUI is a good example where a functional approach
: is better than an imperative one?
: I don't quite understand your argument for that... :( Can you explain a
: bit more?

I am saying:

(1) a GUI is a system that presents the illusion of state to a user
and so is an interesting test case for comparing imperative and
functional programming.

(2) object oriented programming done well encapsulates state changes
pretty well.

(3) functional programming done well can implement "state-full"
systems such as a GUI.

(4) a good OO program and a good functional system are equally
expressive in implementing a GUI.

: I also read that the variables in an imperative language represent


: things in the world very well, because they mark the state of the
: things in a good way, and of course that's why there are
: variables.

I have done a lot of OO imperative programming over the years and I
think claims of "representing the way the world really is" are
overblown. The overriding software engineering issues outweigh the
"real world" notions.

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 12, 1999, 3:00:00 AM4/12/99
to
Henrik =?iso-8859-1?Q?B=E4=E4rnhielm?= (d98...@d.kth.se) wrote:

: To me, it seems resonable that you need to think more for every line


: of code, if you have to write a lesser amount of code, so there
: would not be any difference in how fast the programs are written. Am
: I right?

No, because you do not need to think more per line of code. Since each
line of code is more expressive, there are some things you do not need
to think about at all. And with an interactive environment, you can
think more incrementally. : : > Another major factor I have left out


is how quickly the application : > should be developed (and maintained
after it is released). An : > interactive dynamic language and
environment has an edge for this : > factor, balanced by the other
factors.

--

Jerzy Karczmarczuk

unread,
Apr 13, 1999, 3:00:00 AM4/13/99
to
Henrik Bäärnhielm:

...

> And programs in functional languages are often an order of magnitute
> shorter, isn't that right?
> But can there be any difference in the size of the compiled programs?
> Mustn't there always be the same machine-code?
> So what applications could take advantage of how much code you have to
> write? Big applications in general maybe, but are there any good
> examples?
>

> To me, it seems resonable that you need to think more for every line of
> code, if you have to write a lesser amount of code, so there would not
> be any difference in how fast the programs are written. Am I right?


I don't understand this "always the same machine code". The differences
between well and badly optimized code might be enormous, and the
possibilities to optimize things depend on the language. For example,
- to reuse a discussed example - Pascal code may implement tail
recursion optimization in a more straightforward way, because the stack
is allocated by the calling procedure, so it may *not* be allocated if
the compiler finds it useless. For "C" functions, with variable number
of
parameters, it is the callee who is in charge of the stack allocation.
Difficult to optimize the calls in a portable way! The code is longer,
less efficient. (Those who think that "C" is the nec-plus-ultra of
speed due to the excellent low level optimization may have bad
surprises.)

Functional languages should permit - in principle - a better
optimization,
because their computation model is simpler. Look at the excellent
discussion of those things in the description of the STG machine.

OK... Let's assume that we really want to get all the speed and power
from functional languages, which demands the application of trade
tricks: monads, UNQ arrays in Clean, high-brow Okasakisms in the design
of your data structures, etc. It slows down your design and your coding,
and finally you won't economise your human time by resigning from
using the Dark Side of the Imperative Force, right?

MOSTLY WRONG. (IMHO)
I still remember that the debugging of a Fortran program took me
once two weeks, just to find *one* stupid error due to a bad sequencing
of operations.


Jerzy Karczmarczuk
Caen, France.


****************************************************************
* Confucius might have said:
* "Programming languages are like beautiful women:
* Take your favourite language. What is more important for you:
* Its fabulous semantic power of expression, or -
* The quality of its visual interface?"
****************************************************************

Ulf Wiger

unread,
Apr 14, 1999, 3:00:00 AM4/14/99
to
>>>>> "Henrik" == rnhielm <Henrik> writes:

Henrik> pat...@c837917-a.potlnd1.or.home.com wrote:
>> One other factor is how expressive the language is, i.e. how
>> much code has to be written to accomplish some unit of work,
>> whether imperaitve or functional.

Henrik> And programs in functional languages are often an order of
Henrik> magnitute shorter, isn't that right? But can there be any
Henrik> difference in the size of the compiled programs? Mustn't
Henrik> there always be the same machine-code? So what applications
Henrik> could take advantage of how much code you have to write? Big
Henrik> applications in general maybe, but are there any good
Henrik> examples?

I don't see machine code size as an issue when it comes to
productivity. The machine code is generated by the compiler.
Typically, it's not the same machine code, but it ought to be
reasonably equivalent from a functional point of view.

Current Erlang projects do not use Erlang-to-native compilers,
but rather byte-code compilers. A compiled Erlang module is very small.

We have made comparisons of programmer productivity between different
projects. Roughly speaking, productivity in lines of code per
manhour is the same, regardless of language. Thus, if you can
reduce the number of lines of code by a certain factor, you tend
to get the corresponding increase in productivity.


I'd like to think that the AXD 301 ATM switch is a stellar
example of this, but since average programmers usually don't
churn out ATM switches on a daily basis...

Some of the components of Erlang/OTP (http://www.erlang.org),
for example:

- mnesia, a distributed real-time database management system
ca 20,000 lines of Erlang;
- ORBER, an OMG CORBA 2.0 ORB, 13,000 lines of Erlang,
140 lines of C, 140 lines of Java;
- inets, a HTTP server, 5,000 lines of Erlang.

Another good example is Eddie, a robust web server farm,
http://www.eddieware.org


Henrik> To me, it seems resonable that you need to think more for
Henrik> every line of code, if you have to write a lesser amount of
Henrik> code, so there would not be any difference in how fast the
Henrik> programs are written. Am I right?

Not quite true. You need to spend as much time thinking about how
to solve the actual problem, choosing algorithms, deciding on
fault tolerance and exception handling. Once you know what the
solution should look like, you spend *less* time worrying about
how to translate it into an actual program, since the language
expresses the solution more elegantly.


/Uffe
--
Ulf Wiger, Chief Designer AXD 301
Ericsson Telecom AB tfn: +46 8 719 81 95
Varuvägen 9, Älvsjö mob: +46 70 519 81 95
S-126 25 Stockholm, Sweden fax: +46 8 719 43 44

kin...@sp2n21.missouri.edu

unread,
Apr 14, 1999, 3:00:00 AM4/14/99
to
In article <3711F31A...@yale.edu>,
Paul Hudak <paul....@yale.edu> wrote:
>
[somebody else whose attribution now appears to be lost wrote:]

>>
>> To me, it seems resonable that you need to think more
>> for every line of code, if you have to write a lesser amount
>> of code, so there would not be any difference in how fast
>> the programs are written. Am I right?
>
>There was at least one study done many years ago that showed that on
>large software projects the amount of code developed per day was
>independent of the language used, and that the number was surprisingly
>small, like around 7 LOC/day.

I would also suggest that you don't necessarily need a very careful study
of code production to get numbers something like these. For a wild and
crazy start, let's pretend that programmers are just basically marginal
typists, and could push out 15 words per minute (with no errors) for 8
hours per day. They would then produce 7200 words per day. Playing with
grep and wc on the Linux kernel sources, I'll guess that there are about 8
word-like things in the average line of source, so the Typist Programmer
could produce something like 900 LOC/day. It is to laugh, of course.

First off, real programmers don't spend 8 hours a day being continually
productive, for starters. And even in their productive time, they have to
read (or discuss) requirements and specs, read other code in the project,
bang out the program text, test what they write, and debug based on their
testing. Being realistic, I think programmers spend about half of their
time in non-work-related activities, and half of their work related
activities are probably reading or discussing requirements and specs.

So 8 hours per day of programmer time may not produce as much as 2 hours
per day of real coding (on average). So the Typist Programmer is now down
to maybe 200 LOC/day, if every line of code were golden from the start.
As if.

First off, programmers spend time in going from the spec to a code plan;
that's got to be at least half of the time of coding, so we're down to
maybe an hour per day (~100 lines) in the depths of the write-test-debug
cycle, on average. I'll make a guess that once you get down to brass
tacks, only 10% of the time in that cycle produces final text, on average,
so that the end result of the average programmer's day is on the order
of 10 lines of debugged code.

While you can certainly quibble with the detail of this analysis, I think
that the basic outline is clear: 8 hours at work is 4 hours of useful
activity, and the actual time spent in the act of producing code is rather
less than that. Of course, not all bugs are found right away, but that
only means that the production of code A is interleaved with the
production of B, C, and D, possibly introducing yet more inefficiency into
the analysis...

Another way of getting a similar estimate is to think of the production
rate of professional writers. A syndicated columnist, who might be
considered the equivalent of a star programmer, writes 3 columns a week
and little else; if those columns are 1000 words each, that means the net
production is 600 words per working day, or maybe 30 sentences per day for
a George Will type. A sentence isn't a line of code, but I'll claim that
they're at least vaguely comparable, and this rate of production is also
pretty humbling.

[snip]

>(I did not include Haskell or
>ML in this list because the study predated them, but I'm pretty sure it
>included the Algol languages such as C and Pascal, so one might try to
>extrapolate from there. Of course, there is also the issue of defining
>what a LOC is...)

A more reasonable metric would be to define productivity in terms of how
long it takes to provide a solution to a given well-posed problem from a
decent specification. Unfortunately, this immediately produces two
problems.

The first problem is that most programs written in most languages probably
never had a decent specification to begin with. So even comparing the,
e.g., Haskell solution (which could resemble or even contain its own
specification) with a BASIC equivalent might not tell you very much; they
could be very different things if you look beyond their behavior. The
second problem is that many "real" specifications effectively include
performance requirements for the program that might not be achievable
using a given programming language at a given point in time.

jking

Henrik Bäärnhielm

unread,
Apr 15, 1999, 3:00:00 AM4/15/99
to
Jerzy Karczmarczuk wrote:

> I don't understand this "always the same machine code". The differences
> between well and badly optimized code might be enormous, and the
> possibilities to optimize things depend on the language. For example,
> - to reuse a discussed example - Pascal code may implement tail
> recursion optimization in a more straightforward way, because the stack
> is allocated by the calling procedure, so it may *not* be allocated if
> the compiler finds it useless. For "C" functions, with variable number
> of
> parameters, it is the callee who is in charge of the stack allocation.
> Difficult to optimize the calls in a portable way! The code is longer,
> less efficient. (Those who think that "C" is the nec-plus-ultra of
> speed due to the excellent low level optimization may have bad
> surprises.)

Well, I only meant that there is some piece of machine code for every
operation in a high-level language, and you can't get the code smaller
than the size of that piece, but of course you can get it bigger if the
optimizer is not ideal. Thus, if we assume the optimizers are equally
good for the imperative and the functional language, then the programs
would take up the same amount of space, even if the functional language
are more expressive and you can write less amount of code.
But an overwhelming majority also says that the time to code is
proportional to the lines of code, which is a plus for for functional
languages of course, and if you say that it is often possible to
optimize functional languages better than imperative languages, then
that also speaks for the functional languages...

But then, there must be SOME negative sides of functional languages
versus imperative languages, musn't it? Or why doesn't everyone use
them?
Also, my original question was about some applications where functional
languages are better than imperative ones and vice versa, but the
discussion has been quite teoretic so far... isn't there anyone who can
answer my original question?


Thank you

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 15, 1999, 3:00:00 AM4/15/99
to
Henrik =?iso-8859-1?Q?B=E4=E4rnhielm?= (d98...@d.kth.se) wrote:

: Also, my original question was about some applications where


: functional languages are better than imperative ones and vice versa,
: but the discussion has been quite teoretic so far... isn't there
: anyone who can answer my original question?

I don't think there is a cut and dry answer. I think it is a matter of
taste to a large degree. Different people with different experiences
will have different preferences.

crippa

unread,
Apr 15, 1999, 3:00:00 AM4/15/99
to

I think you are over simplifying things now.

1. "every operation in a high-level language" might be very different
between different languages and by this carry out a different amount
of work and also have a different low-level languages representation.

This imply that in many cases you just can't compare what is
accomplished
by high-level constructs from two different languages at the level of
machine code, byte code etc.

2. "every operation in a high-level language" is just a small part
(small neighborhood) of the whole application. So how large
neighborhood
is the compiler, or the programmer going to take into consideration
when
trying to make the most optimized code ? Taking the whole application
into consideration there is, with a high probability, just one
optimal
low-level code representation for a certain machine.

But no programmer would ever try to write this optimal application
because
then he/she would be last in the complexity of the code. And no
compiler
(to my knowledge) can make the optimal code of a sufficiently large
application.

One can make the metaphore of a chess game. When considering the
neighborhood of
3 steps ahead maybe Sf6 is the most optimal next move, but
considering the
larger neighborhood of 4 steps ahead maybe a complete different move
Dg8 is the
optimal one.

Conclusion: When trying to find the speed achieved when using a certain
programming
language we have to look at different sizes (different
scale) of
low-level neignborhoods and see how much of the application
that is
carried out by this neighborhood. And in the end look at the
whole
application.

> But then, there must be SOME negative sides of functional languages
> versus imperative languages, musn't it? Or why doesn't everyone use
> them?

> Also, my original question was about some applications where functional
> languages are better than imperative ones and vice versa, but the
> discussion has been quite teoretic so far... isn't there anyone who can
> answer my original question?
>

> Thank you
> --
> *****************
> Henrik Bäärnhielm
> d98...@d.kth.se
> *****************

Med vänliga hälsningar (<-- Swedish)

/Christofer

---------------------------------------------------------------
Christofer Törnkvist Phone: +46 8 719 96 99
Software Architecture Lab. Fax: +46 8 719 89 88
Ericsson Telecom AB http://www-sarc.ericsson.se/
S-126 25 Stockholm, Sweden Email: cri...@erix.ericsson.se
---------------------------------------------------------------

Simon Helsen

unread,
Apr 15, 1999, 3:00:00 AM4/15/99
to James Hague
>>But then, there must be SOME negative sides of functional languages
>>versus imperative languages, musn't it? Or why doesn't everyone use
>>them?

This question is peculiar similar to the title of an article by Phil
Wadler in Sigplan Notices a few months ago (and for those following
comp.lang.functional regularly, this should be "deja vu") It is titled
"Why no one uses functional programming languages". In it, you'll find a
pool of reasons (and non-reasons) why no one uses them (or only
marginally). Whether Wadler is right or not, nobody can tell, but at
least it would be worth to take his arguments into account (and as for
Erlang, you may argue that they have proven many of them to be right...)

>I can think of three primary reasons that functional languages haven't
>become mainstream:
>
>1. The programming style and concepts are very different than what has
>been mainstream for the last thirty years. Pascal, C, C++, Modula-2, and
>Java are all fundamentally similar. Languages like ML can reduce C++
>experts to rank beginners for a good while.

Well, I don't beleive that. Those C++ "experts" will mostly acknowledge
the elegance of a language like ML and are likely capable of learning it
very fast. Of course, there is a large bulk of programmers who probably
don't get it, and I mean that literally. They've often never heard of ML
or Haskell and just follow what their "bosses" say (many of these bosses
might even be C++ experts, but look at the reasons Wadler gives and
you'll understand their position)

>2. There's a lack of good tutorials and source code for declarative
>programs other than theorem provers and compilers. If someone wanted to
>write something as simple as a Tetris game in Haskell, then getting into
>the proper mindset and learning how to approach the task functionally--and
>the lack of even vaguely similar code--makes it feel as if they're working
>on a research problem. Meanwhile, the C++ hacker can pound out a
>solution. Is it obvious how to write a breadth-first search in Haskell,
>for example?

As far as documentation is concerned you might be right. However, whether
this is a consequence or cause of the problem, I don't know... As for the
breath-first search, this is I'd say much easier to code in Haskell than
in C as Haskell (and ML for that matter) provide a very elegant way of
describing structures like trees via the expressive type system.

>3. To write a usable application of moderate complexity that doesn't run
>from the command line, you almost always need to write some OS-specific
>interface code in an imperative language. To write a vi clone in Caml,
>you'll need to do some Curses interfacing, for example. This comes down
>to "to write professional programs in Haskell/ML/Clean, you also need to
>know C." So functional programmers often tend to be those who have been
>through the imperative wringer and are looking for something better. You
>have to wait for people to come to their senses (something also true of
>the Lisp world).

Perhaps, but I think there is already a relatively large group of
(decision-making) people who realize the benefits of functional
programming, but also know about the problems using it in meanstream
software development (again, take a look at Wadlers article)

http://cm.bell-labs.com/cm/cs/who/wadler/papers/sigplan-why/sigplan-why.ps.gz

Simon

.................. Simon Helsen ..................
- Programming Languages Research Group -
- University of Freiburg, Germany -
- mailto:she...@acm.org -
- http://www.informatik.uni-freiburg.de/~helsen/ -


Doug Landauer

unread,
Apr 15, 1999, 3:00:00 AM4/15/99
to
kin...@sp2n21.missouri.edu () wrote:
>
> I would also suggest that you don't necessarily need a very careful study
> of code production to get numbers something like these. [...]
> pretend that programmers [...] push out 15 words per minute [...]
> spend about half of their time in non-work-related activities [...]

No real quibble with kingjw's estimates, but ... does this remind
anyone else of the following old joke?

For a couple of years now, I've been blaming it on iron
poor blood, lack of vitamins, dieting and a dozen other maladies.
But now I found out the real reason. I'm tired because I'm
overworked. The population of this country is 237 milion and 104
million are retired. That leaves 133 million to do the work.
There are 85 million in school, which leaves 48 million to do
the work. Of this, there are 29 million employed by the federal
government. This leaves 19 million to do the work. Four million
are in the Armed Forces, which leaves 15 million to do the work.
Take out the 14,800,000 people who work for the state and city
governments and that leaves 200,000 to do the work. There are
188,000 in hospitals, so that leaves 12,000 to do the work.
With 11,998 people in prisons now, that leaves just two people
to do the work. You and me. And you're sitting there surfing
the internet.


> jking

And isn't it an eery coincidence that jking only needs an "o" added
in the right place ...
--
Doug Landauer land...@apple.com (work)
land...@scruznet.com (not-work)

kin...@sp2n21.missouri.edu

unread,
Apr 15, 1999, 3:00:00 AM4/15/99
to
In article <landauer-150...@landauer.apple.com>,

Doug Landauer <land...@apple.com> wrote:
>kin...@sp2n21.missouri.edu () wrote:
>>
>> I would also suggest that you don't necessarily need a very careful study
>> of code production to get numbers something like these.

[snip by jking]

>No real quibble with kingjw's estimates, but ... does this remind
>anyone else of the following old joke?

I'd say what I wrote was the opposite of the old joke...but if there are
any real masochists out there, they could wade through over 300 comments
on slashdot (http://www.slashdot.org/) where one LOC thread has become
quite the rage.

More seriously, they also posted a poll asking slashdot readers (who are
basically young, hard core geeks) how many lines of code *they*'ve written
in the last year. Hardly an unbiased poll...but the median slashdot
reader claims to have written "only" 5000 LOC in the last year.
Programming is hard.

jking

Ian S. Nelson

unread,
Apr 15, 1999, 3:00:00 AM4/15/99
to
Simon Helsen wrote:

I think something like ML can be scary. I would have never looked into it if
my university wasn't so big on it. And it was rough at first. After getting
through the learning curve it's easy to look back at it and say how great it
is, before hand I didn't see a lot of real benefit in it. Then you take that
kind of mentality (I don't know if I am typical or not but I usually assume I
am) and you combine it with the money issues and politics in business and
functional programming isn't in a good position. Are you going to send your
people to learn about some new fangled funtional programming techniques (which
don't have a big record of delivering winning products to market) or are you
going send them to enhance their current skill set? What if you've spent
thousands of dollars training them in "object oriented programming" and they
haven't delivered big pay offs?


>
> >2. There's a lack of good tutorials and source code for declarative
> >programs other than theorem provers and compilers. If someone wanted to
> >write something as simple as a Tetris game in Haskell, then getting into
> >the proper mindset and learning how to approach the task functionally--and
> >the lack of even vaguely similar code--makes it feel as if they're working
> >on a research problem. Meanwhile, the C++ hacker can pound out a
> >solution. Is it obvious how to write a breadth-first search in Haskell,
> >for example?
>
> As far as documentation is concerned you might be right. However, whether
> this is a consequence or cause of the problem, I don't know... As for the
> breath-first search, this is I'd say much easier to code in Haskell than
> in C as Haskell (and ML for that matter) provide a very elegant way of
> describing structures like trees via the expressive type system.

This was my other reason for the lack luster popularity of functional
programming in industry... Breadth-first searches and list reversal functions
are great but they are just a tiny piece of an application. Code reuse is
important anymore, in java I can get a liitle program up and running with a
dialog box and buttons and a web browser window built in to it in minutes. The
same task in ML would require a lot more work because there aren't, to my
knowledge, any available components that do that stuff. I'd end up writing
wrappers around TK or something (using C code...) and possibly writing my own
HTML parser and all sorts of good stuff.
We need a big repository of reusable functional components. Functional
programming would be much more compelling if there were pieces so you could put
together some fairly sophisticated applications quickly. Even if people don't
use them, it's great marketing and people notice it. We need demonstration
products. I think this is partially why perl, python, and other imperative
scripting languages are so popular now, there are so many reusable components
that you can always reduce the amount of work needed to do something complex.
You want to show a web page, boom, there is a web browser component. You want
to access a database, take you pick of database accessors..
It's bad enough to ask people to switch paradigms but the new one doesn't have
anything that looks like it's going to help them get their windows application
out the door faster.


pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
Ian S. Nelson (nel...@ibm.net) wrote:

: I think something like ML can be scary. I would have never looked
: into it if my university wasn't so big on it... Are you going to


: send your people to learn about some new fangled funtional
: programming techniques (which don't have a big record of delivering
: winning products to market) or are you going send them to enhance
: their current skill set? What if you've spent thousands of dollars
: training them in "object oriented programming" and they haven't
: delivered big pay offs?

A big part of the problem is that people seem to be getting trained in
the popular language but they are not getting educated in how to think
about computation. I was fortunate that early on I took a couple of
"principles of programming languages" courses and that my university
was big on Lisp. I learned not to just appreciate Lisp but to
understand the semantics of all kinds of programming languages, what
they have in common, and how they differ.

Someone who "learns C++" or "learns Java" does not learn how to be
effective over the long haul.

Simon Helsen

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to James Hague
>Hmmm...I don't think it's quite so simple as that. It's not that ML is a
>difficult language, just a very different one. If someone learned C or
>Pascal in college, and has been a professional C++ programmer for five
>years, then ML is going to be quite a shock. It's the programming style,
>not the syntax.

I know what you mean, but if an imperative programmer is only a little
open-minded (and perhaps this is more the problem than anything else),
she/he would be interested to see how things can be done in a different
way. Of course, if you're mind is preset that C++ is *the* only "real"
programming language (refering to a very old reference ...), ML or
anything new cannot be good. As for Java, I don't consider it really new
and many other factors (unrelated to the language and very important as
well - look back at Wadler's arguments) have been important in the
popularization of Java (for instance, that Sun, as a major industrial
player, was behind it etc.)

During my college-time, I also first learnt Pascal/C and was introduced
later to ML and Prolog. I was sceptical in the beginning, but seeing a
3-line prolog program doing quick-sort was *very* convincing and the week
of painfull debugging a C-program due to a non-initialized pointer for a
networking cours-project at around the same time, shut the door for me. I
know that there are many imperative languages who wouldn't have caused
this problem, it was just all coming together...

>In every team project I've worked on--and in most C/C++ programs I've ever
>looked at--there's a tendency to write large subroutines. Common concepts
>are factored out early on, but it's often easier to write a hundred or
>more lines of code in one routine than to figure out how to properly
>modularlize it. And yes, everyone knows that this is not an ideal way to
>write code, but it's business as usual.

if "the business as asual" argument holds, than I suggest we go back to
Fortran or Assembly like in the good old days were "real programmers"
still debugged by scanning a 4 Megabytes Coredump...

>With functional languages, and other languages such as Forth, it is not
>only considered poor style to write large routines, it is unbearable. So
>some form of factoring is a requirement, not a mythical ideal. Yes,
>breaking up a problem is a good thing, And yes, it leads to better code.
>But it does require more thought up front. I can see that some people
>wouldn't want to do that, especially if they know they can solve the
>problem by pounding out one fifty line routine.

"Wanting" is not an issue. Really, if people would think more up front
(and I am not even talking about fancy SE techniques, but just about
thinking in advance on structuring a program, and then start coding), much
of todays software wouldn't be so buggy.

>That's an arbitrary example, and maybe only a minor one. But there are
>more social differences between imperative and declarative programming
>than may be first apparent.

Yes, perhaps you're right, I can see some relation. Compare this to a
typical parliament in a democratic society:

/ functional \
logical imperative
++++
chair

Simon

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
James Hague (jha...@dadgum.com) wrote:

: In every team project I've worked on--and in most C/C++ programs


: I've ever looked at--there's a tendency to write large subroutines.
: Common concepts are factored out early on, but it's often easier to
: write a hundred or more lines of code in one routine than to figure
: out how to properly modularlize it. And yes, everyone knows that
: this is not an ideal way to write code, but it's business as usual.

This is common in my experience too. All too common.

: With functional languages, and other languages such as Forth, it is


: not only considered poor style to write large routines, it is
: unbearable. So some form of factoring is a requirement, not a
: mythical ideal. Yes, breaking up a problem is a good thing, And
: yes, it leads to better code. But it does require more thought up
: front. I can see that some people wouldn't want to do that,
: especially if they know they can solve the problem by pounding out
: one fifty line routine.

: That's an arbitrary example, and maybe only a minor one. But there


: are more social differences between imperative and declarative
: programming than may be first apparent.

I do not think this is minor at all. I think this observation of yours
is central.

Jerzy Karczmarczuk

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
Henrik Bäärnhielm strikes again:

...

> But then, there must be SOME negative sides of functional languages
> versus imperative languages, musn't it? Or why doesn't everyone use
> them?

> Also, my original question was about some applications where functional
> languages are better than imperative ones and vice versa, but the
> discussion has been quite teoretic so far... isn't there anyone who can
> answer my original question?

Patrick Logan says that there is no universal answer, that people
and their preferences are different.

Christofer Törnkvist point out that the efficiency is a relative issue,
depending on the granularity of the program (and on the programmer's
ambitions...)

James Hague sent a longer, and very well structured response. Some
points
are ambiguous, for example:


> Is it obvious how to write a breadth-first search in Haskell,
> for example?

I think that for those for whom this is difficult, its coding in "C"
might be even more, provided the *language* knowledge is comparable.
You mean: queues (FIFO) are less obvious in Haskell than in Cobol?

===

OK, here you are my 2 eurocents, they are cynical on purpose (btw.
eurocents are cynical by definition...):


1. Functional languages belong to the Academia. They are free, and
nothing is patented nor copyrighted. So, they must be useless
for the Real Programmer. (This is a cynical, stripped version of
the last of Phil Wadler's non-arguments...). In one word, the
reason is PREJUDICE. (This is not the same as stupidity, and
if I could compare it with anything, I would -- trembling --
compare it to racism.)

2. Somebody might wish to kill me because of this, but here we go:
Functional languages are for INTELLIGENT PEOPLE.
Not all professional programmers are...
At first glance, jumping into the FP domain you LOSE something,
the ubiquitous destructive assignment, the side effects. You
gain a lot, but you have to *learn* the recursive iterators,
monads, eventually the lazy semantics. The learning curve is
steep. How many Real Programmers have time enough for learning
(even if they find Time Enough for Love: do you recognize this
title?...)

The -- MUCH more serious -- argument that the Real programmers
write huge subroutines, which is difficult in Haskell, might be
a secondary proof of my nasty and anti-human hypothesis.


Jerzy Karczmarczuk
Caen, France

PS. BTW, I find a little bit hilarious the attitudes of this kind:

"I know almost nothing about functional languages, please
suggest something.
But I REQUIRE!!! the Open Source Full Freedom.
(It is obvious that next week I will start distributing
my software based on the MODIFIED original sources.)"


$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
$ Confucius might have said:
$ "Programming languages are like young, handsome men...
$ My dear Ladies, how long will you continue to think that
$ A. <<He is huge, brutal and without any elegance. So, he must
$ be efficient and powerful.>>
$ B. <<He is very fast in all circumstances, and it is good.>>
$ (Because you forgot that sometimes the smoothness of your
$ interactions is more important than speed, and you forgot
$ also that the pleasure comes often from writing the program,
$ and not from running it.)
$ C. <<All 'em are essentially equal, if you strip some irrelevant
$ decorations.>>
$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$

gazzani

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to

Henrik Bäärnhielm wrote:
> But then, there must be SOME negative sides of functional languages
> versus imperative languages, musn't it? Or why doesn't everyone use them?

This puzzles me. Why people don't use functional languages? I have been
working with Clean for some time. The programs are concise, the code is
highly optimized. Richard O'Keefe of Prolog fame developed a Neural
Network both in C, in Haskell and in Clean. He says that his C compiler
uses a lot of inline code... Even without inline code, Clean is only three
times
slower than C. I have seen programs where the Clean compiler comes
to a draw with not so optimizing C compilers, like Windows-gcc, lcc
and MS VC++. I don't have much experience with Haskell, but people
claim that it is even faster than Clean...

IMHO, functional languages are conceptually difficult to learn. In C,
one learns a few ideas (iteration, if then else, function call) and s/he does

a lot of things... It is true that writing a good program in C is harder than

writing a good program in Clean. However, it is definitely easier to
write simple code in Pascal or C, if simple code is all that you can write.

If a novice writes poor code for handling matrices, Clean won't compile.
S/he will not have a chance of debuging the program, because Clean
will post that nasty error message (unique type* required but not offered at
the
indicated position-- How I hate this!), and won't compile. If s/he makes the
same mistake in Delphi, Pascal will compile his/her program, run it,
then it will issue a runtime error. The person is placed into the debug,
traces the execution, finds the error, run the program, and prowdly shows
the result to the boss. In the mean time, Clean programmer is staring
at the message "Unique type required but not offered".

I had a student who was writing a simple file handling program. There
was a share violation in his program. Guess what! Clean signaled the
error, opened the (in)famous window, and signaled the share violation
(as "unique type required but not offered", of course). The student couldn't
see how to offer the asterisk to the cute compiler, and gave up after
15 minutes of trials. The same student opened the Delphi, wrote the
same program, made the same mistake (I was observing everything).
Delphi compiled the program without a single warning, and generated
the executable application. The results were wrong, of course.
He noticed the error, entered the debug, and started looking for the
problem. A person seldom gives up if s/he is active, looking for an
error. One week later, he found the error, and fixed it. He still doesn't
know how to offer the asterisk to Clean compiler :)

I know that I will offend a lot of people for daring to post this in a list
dedicated to functional programming, but let's face it: Languages like
Clean are fast, concise, increase the productivity of the expert (expert =
person who knows how to offer unique type at the indicated position :),
safe, all errors are detected at runtime, etc... C is easier to learn.
Therefore, there are a lot of people who knows C, and few people who
knows Clean (substitute Haskel for Clean, and you won't change the
equation...)

Don't take me wrong. I like functional programming, like you.
However, to most people, it is difficult. Not many persons know how
to offer unique types at the indicated position...

A. Costa &
Alcimar Soares

P. S. Please, Clean team! You have done a great work. We admire you
for that. You have done a lazy language that is (almost) as fast as C.

"To common people, the best language of the world is the one that
s/he knows better."


Nick Kallen

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
> This puzzles me. Why people don't use functional languages? I have been
> working with Clean for some time. The programs are concise, the code is
> highly optimized. Richard O'Keefe of Prolog fame developed a Neural
> Network both in C, in Haskell and in Clean. He says that his C compiler
> uses a lot of inline code... Even without inline code, Clean is only three
> times

And how long did it take Richard, and how much effort was it for him to get
the code that fast? I'm on the mailing list too. His goal was to do this in
a week, yes? It took him significantly longer, as I recall. This is a good
question to ask him:

Considering how long it takes to optimize the Clean version, are there any
productivity gains relative to C?

I would guess *no*, that in this particular case, Richard would be far more
productive in C.

Antonio Costa

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to

James Hague wrote:

> 1. The programming style and concepts are very different than what has
> been mainstream for the last thirty years. Pascal, C, C++, Modula-2, and
> Java are all fundamentally similar. Languages like ML can reduce C++
> experts to rank beginners for a good while.

> 2. There's a lack of good tutorials and source code for declarative


> programs other than theorem provers and compilers.

This is also my opinion, but you stated it better than I did. I said that
C is easier. You said why it is easier: There a models to follow, books,
tutorials, etc.

> 3. To write a usable application of moderate complexity that doesn't run
> from the command line, you almost always need to write some OS-specific
> interface code in an imperative language.

I cannot agree with this topic. Clean has a very good GUI, which is becoming
even better. It is portable (the same code for Windows, MacIntosh, and
MacIntosh;
I don't know about the Sun, but I guess that the code must be similar).
People developed a lot of things in this GUI, like the two IDEs, and a lot
of games. Among the games, you will find: Tetris (for some reason, Clean
team removed the Tetris game from the distribution), Worm, Scrabble (one of
the
most beautiful and impressive implementations of Scrabble I ever saw,
even when compared with the Scrabble Robot of the Scrabble Association),
Turing Machine, Ana's Java Animator (which generates byte code for the JVM
using a visual language), Mines, Tiles, that program to
draw figures for Tex (and whose name I cannot remember, but I want
to get it again), Alex's Own Expert System, Simple Database, Not So Simple
Database, Cedric's Java Dissassembler. Haskell has not som many GUI
applications as Clean, but Conal Eliot's RB applications show that Haskell
communtity wants to go even further than Clean team. No, I don't think
that GUI and Graphics is an issue. In fact, Clean Object IO library is even
better than anything that I have seen in C. If I write a GUI application in C
(hypothetically, because I don't program in C), I cannot compile it as is
in another machine. In Clean, GUI applications can run in many machines.

A. Costa

Robert Bernecky

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to gazzani
> Henrik Bäärnhielm wrote:
> > But then, there must be SOME negative sides of functional languages
> > versus imperative languages, musn't it? Or why doesn't everyone use them?

I think there is a more fundamental problem here. I've been a
designer and developer of APL systems since the dark ages, and
have watched industry (merchant banks, large manufacturing firms,
insurance companies, stock brokers, pharmaceutical companies...)
dither with APL and similar languages (J,K, NIAL). Here's
a few observations:

They use APL, because it gives them a substantial development
edge in terms of time-to-solution. I point to a large drug company
and, a Large European bank, and a large purveyor of numeric
financial data as examples of companies that adopted
APL to solve large, time-critical problems that Keep Changing
(due to gov't reporting requirements, market changes, etc).
All 3 of these firms decided that APL was Bad, because it:
- was Non-Strategic [you figure out what that means]
- was not Industry-Standard [in spite of the ISO APL
Standard ISO N8485.]
- was hard to find and keep qualified personnel [this one I believe]

However, they DO NOT like APL:
- it's hard to find qualified personnel, because universities
don't teach it.
- there are only a dozen or so vendors.
- interfacing APL to scalar-oriented languages is messy.
- performance has traditionally been a problem, in the sense
that writing scalar-oriented looping code can bring a
mighty mainframe to its knees. Or ankles.

So, at various times, management would change, and they would
embark on large [$20-40E6 USD] projects to convert
to other languages, such as C++. These efforts typically failed,
usually because specs would change faster than C++ coders
could react to them. Lots of money down
the tubes. Periodically, they try again, but they have so much
invested in existing code that they'll never complete a conversion,
particularly when management is also singing the "downsize"
tune, and they lose their best people.

Now, let's turn it around: It's not an issue of whether you
as a programmer want to use a functional language; it's
whether or not your client WANTS their mission-critical
system written in a language "that nobody knows".
So, assuming that functional languages (FL) are absolutely swell,
they still don't get used, because:

a. The client can't maintain FL with their existing programmers.

b. The client has a huge investment in non-FL code, and
their programmers know non-FL and are adequate or good
at maintaining it. Conversion is FAR too costly.

c. The client's management is paranoid about changing to FL,
even for new apps, because of FUD(fear, uncertainty, and
doubt) and the chance of the manager getting canned if FL
doesn't work for some reason. Would you play Bet-Your-Company
to get better apps? Remember, your stock options are
at stake.

d. Inter-connection of existing non-FL and FL apps may be
nasty.

I think these issues may be more relevant to the lack of adoption
of FL than anything having to
do with the possible virtues or vices of FL.

Bob


Simon Helsen

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to gazzani
>IMHO, functional languages are conceptually difficult to learn. In C,
>one learns a few ideas (iteration, if then else, function call) and s/he does

and no more in a simple functional one (recursion, condition, lambdas)
Take Scheme, there are not many languages which rival it in simplicity (as
far as "concepts" is concerned. And lot of concepts => difficult
language. This can be easily observed by looking at first years
struggling through Java, which conceptually *very* complex)

>If a novice writes poor code for handling matrices, Clean won't compile.

...
<snip: stuff about "unique type required but not offered at the indicated
position">
...

I personally don't know about this "unique type etc."-message, since I am
not familiar with Clean, but you're giving a counter-argument for using
languages like Delphi or C. Of course, if you don't know what the *static*
error message means, you can sit and stare and you won't achieve anything.
But you can also sit and stare at your program that is aborting for one or
other obscure reason. But claiming that people are better off by debugging
their program for a week instead of solving the static type problem is
absolutely ridiculous. If that student of yours would have looked up what
the message means and examined his code at the proper location, he might
have solved his problem in less than a week. Moreover, the next time, he
will find the cause of the error much faster and at least he knows that
these kind of errors won't occur anymore after compilation succeeded.

Actually, such an error-message is the main virtue of statically typed
systems (as opposed to many annoyances). Consider this, what if the
*runtime* error did not occur right away? What if it does occur when a
difficult customer is pushing his new expensive product to its limit and
knocks on your door because your program is no good?

>I know that I will offend a lot of people for daring to post this in a list
>dedicated to functional programming, but let's face it: Languages like
>Clean are fast, concise, increase the productivity of the expert (expert =
>person who knows how to offer unique type at the indicated position :),
>safe, all errors are detected at runtime, etc... C is easier to learn.

is it? Why then, for example, find humanities students (who typically
never saw a imperative program before) Prolog easy and straightforward
to learn and are Computer Science students complaining as soon as they
can't use their beloved C (or Java nowadays)? The problem is that many of
us started off one way or another with an imperative language (even if it
was just Basic) and the first love...

My impression (by observing students and the kind of comments from this
thread) is that people are reluctant to learn something new which is
perhaps better (doesn't even have to be, but whether it is or not, it is
prejudged since it takes an effort to do things differently)

>Therefore, there are a lot of people who knows C, and few people who
>knows Clean (substitute Haskel for Clean, and you won't change the
>equation...)

I think your conclusion is a bit simplistic considering the many other
reasons why it might be beneficial to use a mainstraim language (like C).

Simon


pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
Nick Kallen (nka...@uclink4.berkeley.edu) wrote:
: > This puzzles me. Why people don't use functional languages? I have been

I think this points out there there are a lot of people who have a lot
of knowledge about using C effectively. I think it will take some time
for the knowlegde fo using functional languages to get into the same
range. The incentives are there, and could increase. I would not
expect large numbers of people to start learning FP right now. But I
would also nto be too critical for those who are trailblazing, really,
what may become well worn tracks.

I think that is the message of FP right now: there is an opportunity
to blaze some interesting trails and those trails may lead the way in
the not too distant future to even more pioneeers and eventually large
populations.

Craig Dickson

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
gazzani <co...@ufu.br> wrote:

>IMHO, functional languages are conceptually difficult to learn. In C,
>one learns a few ideas (iteration, if then else, function call) and s/he

>does a lot of things...

You left out pointers, explicit memory management, typedefs, learning how
to implement variable-length lists since the language doesn't have them
built in, etc.

And of course this argument falls to the ground if we substitute C++ or
Java for C in your statement. Any decent functional language is much easier
to become expert in than C++! (Of course, one might make the same argument
for any decent object-oriented language, but I digress...)

>I had a student who was writing a simple file handling program. There
>was a share violation in his program. Guess what! Clean signaled the
>error, opened the (in)famous window, and signaled the share violation
>(as "unique type required but not offered", of course). The student couldn't
>see how to offer the asterisk to the cute compiler, and gave up after
>15 minutes of trials. The same student opened the Delphi, wrote the
>same program, made the same mistake (I was observing everything).
>Delphi compiled the program without a single warning, and generated
>the executable application. The results were wrong, of course.
>He noticed the error, entered the debug, and started looking for the
>problem. A person seldom gives up if s/he is active, looking for an
>error. One week later, he found the error, and fixed it. He still doesn't
>know how to offer the asterisk to Clean compiler :)

Sure, but that's quite different from arguing functional languages vs. C as
you did above. Tools like Delphi and Visual Basic are designed for
inexperienced or low-skill-level programmers. Their languages are ugly,
inexpressive, and slow, but they are good at holding your hand. What you
really saw is not that Delphi is an easier language to write in (after all,
the student wrote equally incorrect code in both languages), but that
Delphi's interactive development tools are geared towards helping
beginners, whereas Clean's aren't. This is irrelevant to the functional vs.
imperative debate; it has more to do with the fact that Delphi and VB are
aimed at the mass market.

It would be interesting to see what could be done with making a really
sophisticated hand-holding GUI environment for Clean or Haskell or Erlang,
but nobody's tried to make one as far as I know.

Craig

Ben Sano

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
You must remember that the code counting was done over delivered code only and
included EVERYONE who worked on the project, not just the programmmers.

--
--Ben

kin...@sp2n23-t.missouri.edu

unread,
Apr 16, 1999, 3:00:00 AM4/16/99
to
In article
<Pine.LNX.3.96.99041...@punaluu.informatik.uni-freiburg.de>,
Simon Helsen <she...@acm.org> wrote:
>
[somebody now unattributed wrote]

>
>>>But then, there must be SOME negative sides of functional languages
>>>versus imperative languages, musn't it? Or why doesn't everyone use
>>>them?
>
>This question is peculiar similar to the title of an article by Phil
>Wadler in Sigplan Notices a few months ago (and for those following
>comp.lang.functional regularly, this should be "deja vu") It is titled
>"Why no one uses functional programming languages". In it, you'll find a
>pool of reasons (and non-reasons) why no one uses them (or only
>marginally).

A nice, short, paper. But to make the point even shorter, I'll
recapitulate his list of qualities that widely used languages have:

1) "interlanguage working" (i.e., a foreign function interface)
2) extensive libraries

3) portability
4) stability, ease of installation
5) availability of debuggers and profilers
6) availability of training

7) "a good track record" (so management will let you use them)

8) efficient implementation (although Wadler notes this hasn't stopped
the Java bandwagon from rolling on)

As I try to suggest by my grouping of these reasons, I think this boils
down to 4 qualities:

a) Encourages software re-use (Works with code that's already available)
b) Easy to start and keep using
c) Buzz
d) Sizzle

Where sizzle stands in for either performance substantially better than
what you've got, or code that's easier to bang out than in another
language.

Except for the Buzz part, I think this basically looks like a "Worse is
Better" argument. Wadler also mentions the "Killer App" effect, but I
see this as just a version of "Worse is Better" in a niche where you have
no competitors.

>Whether Wadler is right or not, nobody can tell, but at
>least it would be worth to take his arguments into account (and as for
>Erlang, you may argue that they have proven many of them to be right...)

Well, to the extent that Wadler has re-phrased "Worse is Better", than
I think it's likely he's right. What's interesting is that the original
poster came up with what amount to the same list:

>>I can think of three primary reasons that functional languages haven't
>>become mainstream:
>>

>>1. The programming style and concepts are very different than what has
>>been mainstream for the last thirty years.

[snip]

In other words, my reason (b): easy to start using (in the current
environment).

>>2. There's a lack of good tutorials and source code for declarative
>>programs other than theorem provers and compilers.

Also (b): without tutorials and souce, it's harder to get started.

>>3. To write a usable application of moderate complexity that doesn't run
>>from the command line, you almost always need to write some OS-specific
>>interface code in an imperative language.

That's (a): if you don't have an FFI, you're screwed.

>>To write a vi clone in Caml,
>>you'll need to do some Curses interfacing, for example. This comes down
>>to "to write professional programs in Haskell/ML/Clean, you also need to
>>know C."

Now this is where I see *some* hope of improvement. The very latest stab
at a foreign function interface for Haskell (H/Direct) finally tries to
move beyond this, being based on IDL, and allowing your code to be or use
COM objects. The approach has Buzz (reason c), and would allow some
Haskell programs to finally get some Sizzle (reason d). The down-side is
that IDL presents something of a hurdle in itself.

[snip]

And here's the URL for the paper, kindly provided by Simon Helsen:

>http://cm.bell-labs.com/cm/cs/who/wadler/papers/sigplan-why/sigplan-why.ps.gz
>
> Simon

jking

Friedrich Dominicus

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
This is quite an interesting topic. But I missed s.th which I found
important.

Antonio Costa wrote:


>
> James Hague wrote:
>
> > 1. The programming style and concepts are very different than what has

> > been mainstream for the last thirty years. Pascal, C, C++, Modula-2, and
> > Java are all fundamentally similar. Languages like ML can reduce C++
> > experts to rank beginners for a good while.


This is very true for me. If I look at solutions I have difficulties to
understand what's going on sometimes in functions with a million
parameters. I have take a look at the pure functional data-structures
and some stuff is really heavy.

Another point is that is that altthough the solutions look quite elegant
they don't fit the learned step-by-step approach which you can found in
imp. languages. This is not just a thing in that languages but e.g in
cooking. Cooking is not described declarative but imperative.

1. first took that
2. than that
3 do that ...

So one large problem is the switch from step-by-step to the declarative
style. It looks a lot like Mathematics and as elegant solution might are
for the initiated so hated is the stuff by many of us. And even worse
even in introction texts you found s.th abotu squares and the like but
not of how to do I/O. And if s.o ones to learn that the Monads come into
the game. And how are they described? With mathematics. And a bit
criticism is the style of coding. This is an implementation of a lenght
in Haskell: as found in prelude.
length :: [a] -> Int
length = foldl' (\n _ -> n + 1) 0

Or in Scheme with the historical car and cdr (nobody really know why
that is changed) Or the tendency to write as short and hierogryphical as
possible so another lenght implementation may be (introductoin

lenght :: [a] -> Int
length [] = 0
length (x:xs) = 1 + length(xs)

not
length (front:rest) = 1 + length(rest)


or from the Examples/Stack
topOf :: Stack a -> a
topOf [] = error "topOf: empty stack"
topOf (x:_) = x

not
topOf (front:_) = front

or from purely functional data-structures (p 193) at the end

where
(SHALLOW d1) ++ (SHALLOW d2)
| size d1 < 4 = SHALLOW (dappendL d1 d2)
.
.
. | otherwise = DEEP d (cons (SIMPLE f) a) m b r


this is so unreadable that it hurts.


Another point is: The imperative stuff can be seen as a machine. I push
a button and s.th happens. And another point is that building models
(ships, planes) etc is not declarative too you have to follow an
imperative way.

So to make a long story short: I think we learn more step-by-step than
other things, so most? are used to work this way too.

I think this is a big handicap for FP-languages.


>
> > 2. There's a lack of good tutorials and source code for declarative
> > programs other than theorem provers and compilers.

Even worse the main stream believe in FP seems to be: "we don't need an
debugger" So maybe you didn't but a debugger does his execution
step-by-step which I can follow. There are nearly no debuggers for FP
languages. I learned Eiffel as there was no suitable debugger but how do
you help yourself then. you put in some print routines. That's not a
strong point for FP-languages.

And the anotheg intentin seems to be. FP is runnable specification. If
some here the word "specification" they began to shiver. And the advise
on how to develop larger application in a functional way slides very
early in the world of pure mathematics, foundations, conclusions etc.
The also done proof by induction, was one of the most hated things to
learn in studiyin. I think I see the advantages now but to that time ...


>
> > 3. To write a usable application of moderate complexity that doesn't run
> > from the command line, you almost always need to write some OS-specific
> > interface code in an imperative language.


Sorry I don't see that. But what I see is that GUI-stuff is not a major
stuff in FP languages. And than I can read in this news-group how
supirious FP is even in that regions.

It it's so superior why can't I find e.g a easy to use Haskell -Gui
library with some good examples?

So it's not all FP what shines.

Friedrich

Nick Kallen

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
> : Considering how long it takes to optimize the Clean version, are there
any
> : productivity gains relative to C?
>
> : I would guess *no*, that in this particular case, Richard would be far
more
> : productive in C.
>
> I think this points out there there are a lot of people who have a lot
> of knowledge about using C effectively. I think it will take some time
> for the knowlegde fo using functional languages to get into the same
> range. The incentives are there, and could increase. I would not
> expect large numbers of people to start learning FP right now. But I
> would also nto be too critical for those who are trailblazing, really,
> what may become well worn tracks.

I think this is a naive viewpoint. If I understood what Richard was talking
about correctly, then:

He had an algorithm, of known complexity implemented in time T1 in C, and
implemented (the first, unoptimized implementation) in time T2 in Clean. Let
us assume for the sake of argument that T2 < T1, but I don't think this is a
valid assumption.

The original implementation, used lists, sparsely used unique types, had
extensive strictness annotations, etc. Richard said that the Clean
implementation is mostly a straightforward translation of the C version, but
obviously he put extra effort into adding uniqueness information and
strictness information. But even given that,

From Richard's email:

>The original C version took 254 seconds on a medium size made-up test
>problems. My improved C took 102 seconds.

>The Clean version took 10590 seconds.

Where the "improved" version described by Richard is:

>I took a
>simple Neural Network program written by someone who is an expert in
>the field and speeded it up by a factor of 2.5, basically by writing
>the kind of clean C any APL fan would produce (:-).

Now, after further Clean optimization, which took 2 weeks of work, during
which time Richard was extremely productive experimenting with several
things:

- Macros for inlining
- Unrolled strict lists (Ursl)
- Strictness annotations
- Uniqueness Types
- Arrays
- Elimination of higher order functions
- Keeping data in the source vs. reading it from a file.
- Etc.

He finally got the following result:

>Recall that the previous version of the program, _with_ the data in the
>program, took
> 453 sec (user) + 13 sec (GC) = 466 sec (total).
>Well, just reading the data from a file takes
> 0.8 + 0.0 = 0.8 seconds,
>and reading the data and solving the problem takes
> 399 sec (user) + 12 sec (GC) = 411 sec (total)

>We're now down to 4 times slower than optimised C, which is darned good.

Within 5 days he had a working Haskell implementation. He didn't share the
Haskell performance for the Neural Network, but in order to make
comparisons:

>I decided to focus on a smaller task instead: multiplying two
>100x100 double-precision matrices.

>RESULTS
> Compiler List Ursl Array
> GHC 3.02 5 sec 3 sec 25 sec
> Clean 1.3.1 5 sec 4 sec 0.8 sec
> C 0.2 sec
>...

Richard reaches the following conclusions:

> - Clean and GHC produce similar results for lists. That's quite
> encouraging.
> - the effect of not inlining and not letting me use macros either
> really does show up.
> - Although this code makes NO use of uniqueness or array update,
> Clean's arrays really really shine. WELL DONE CLEAN TEAM!

and adds:

>Interestingly, the Clean/C ratio
>for this problem is the same as the Clean/C ratio for the original
>NN problem: 4.

Now, aside from the fact that all of this is an extremely fascinating and
enlightening exploration of performance comparison and optimization, we can
reach the following conclusion:

The overhead in optimizing Clean code to a reasonable constant factor (4) is
*huge*.

Now, consider the following two scenarios:

1) Richard straight translates the C implementation to Clean, modulus
familar functional/imperitive idioms. To optimize it, he has to translate
lists to arrays, add extensive uniqueness types, add extensive strictness
annotation, use macros rather than functions where appropriate, eliminate
higher order functions, and so on. Conclusion: in an application where
performance matters (as here it does, that's the whole point of this
excercise), while there may be productivity gains in straightforward
functional implementations, there are huge productivity losses due to extra
effort from optimization.

2) Richard knows from previous experience and (the nonexistent) extensive
literature on the subject of optimizing your pure lazy functional programs
exactly what idioms and things he'll have to think about when mapping the C
to Clean. He writes his first Clean version with all optimizations, meaning
he can't use higher order library functions or laziness (which makes what
John Hughes talks about inapplicable). I'm guessing it would be unreasonable
to assume that there were *any* net productivity gains, even when you know
what optimizations to make to the point where it's formulaic. Not to mention
the extra debugging overhead of starting with a more complicated program!
Conclusion: it's likely that Clean is not as productive as C when you're
writing highly optimized Clean code.

These are my conclusions, what are yours?

Nick Kallen

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
> A big part of the problem is that people seem to be getting trained in
> the popular language but they are not getting educated in how to think
> about computation. I was fortunate that early on I took a couple of
> "principles of programming languages" courses and that my university
> was big on Lisp. I learned not to just appreciate Lisp but to
> understand the semantics of all kinds of programming languages, what
> they have in common, and how they differ.

At my university, Berkeley, the first (real) course for CS programmers uses
Scheme with Structure And Interpretation of Computer Programs as the
textbook. The second course is in Java, and this is primarily
datastructures/algorithms/programming-in-the-large material. The third
course is on machine structures, which teaches C and ASM.

In beginning of the third course, the professor did a poll of ~400 students.

The results were not surprising: of those who know Java, 80% prefer it over
any other language. Of those who know Scheme 20% who know it prefer it over
any other language. Those who knew C, 23% prefer it over any other
languages. Because people skip classes, you can't be sure what languages
people know, but the data indicate that everyone knows Scheme. So the
conclusion to be drawn is: of those who know Scheme and Java (presumably
equally well), 80% prefer Java; of those who know Scheme and C (presumably
equally
well), 23% prefer C. Also, nobody who knows C and Java and Scheme prefers C.

It's important to note that for most students here, their college
programming carreer began in Scheme, although a strong percentage of them
had previous programming experience in (presumably) imperitive languages in
high school and such. However, it is still not a valid conclusion to say
that what you learn first is what you prefer: clearly a significant
percentage of people whose first language was Scheme prefer Java.

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
Nick Kallen (nka...@uclink4.berkeley.edu) wrote:

: These are my conclusions, what are yours?

That Richard learned a lot about how to make the current Clean
implementation "relatively fast" for certain kinds of algorithms. That
the Clean team learned some things about how a programmer of such fast
algorithms wanted to use Clean's features, but couldn't, and that
Clean is a language where a large number of programs can be written
using an "obvious" style, and the rest that need more efficiency can
be written as well using more effort.

As I said in my previous post, this seems like trailblazing to me. I
had not seen that kind of expereince written up anywhere before.

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
Nick Kallen (nka...@uclink4.berkeley.edu) wrote:

: At my university, Berkeley, the first (real) course for CS


: programmers uses Scheme with Structure And Interpretation of
: Computer Programs as the textbook. The second course is in Java, and
: this is primarily datastructures/algorithms/programming-in-the-large
: material. The third course is on machine structures, which teaches C
: and ASM.

: In beginning of the third course, the professor did a poll of ~400
: students.

: The results were not surprising: of those who know Java, 80% prefer
: it over any other language. Of those who know Scheme 20% who know it
: prefer it over any other language. Those who knew C, 23% prefer it

: over any other languages...

: ...However, it is still not a valid conclusion to say that what you


: learn first is what you prefer: clearly a significant percentage of
: people whose first language was Scheme prefer Java.

Maybe these results represent a failure on UCB's part since the goal
of a course like SICP is not to turn out students who "favor Scheme"
but to turn out students who understand the structure and
interpretation of any kind of computer program.

Brian Rogoff

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to

Sorry to quote so much, but that was a fascinating post, and I felt that
all of that was necessary.

I agree with your conclusions, but I got a few other things out of that
too.

(1) Richard should have translated the program to Fortran, and run
compiled it on a good Fortran compiler. That way if the C version is
slower we could conclude that C is not as productive as Fortran when
you're writing highly optimized C code :-).

(2) Current functional language implementations suck at compiling array
heavy code so numerical programmers with a need for speed should
shop elsewhere *for now*, or at least use an implementation which
offers a convenient way to call C or Fortran. More work surely needs
to be done here.

(3) Use the tool the right way. FFTW uses an OCaml program to generate C
code for fast FFTs. Functional languages are good for this kind of
work, since they've been optimized by their implementors for
implementing compilers, typically their own. There's some sort of
bizarre fixed point theorem in there about the design of research
languages, I'm sure. This probably accounts for (2) as well.

-- Brian

Eugene Dragoev

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
Well... since this message shows up only in the comp.lang.functional
newsgroup I don't think there are many people here that will want to do this.
If you want some heated exchange just crosspost this to the C/C++ and
assembly language groups :)

With attitude like this advocates of general purpose FP languages will have
difficulty attracting more users. Why not position FP languages as "Easy, Fun
and the smart next step for Intelligent Programmers that are currently using
C/C++, Java and you name it."

Let's face it - I make my living writing Java programs and used to write
C/C++ and assembly before. If all I know is Haskell what kind of job I could
get right now?

Eugene

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
Brian Rogoff (b...@shell5.ba.best.com) wrote:

: (3) Use the tool the right way. FFTW uses an OCaml program to generate C

: code for fast FFTs. Functional languages are good for this kind
: of work, since they've been optimized by their implementors for
: implementing compilers, typically their own. There's some sort
: of bizarre fixed point theorem in there about the design of
: research languages, I'm sure. This probably accounts for (2) as
: well.

This is a great point. The Squeak Smalltalk system runs on a virtual
machine that is written in... Squeak Smalltalk! It generates C or it
can be run as a virtual machine simulator within Smalltalk. People who
use it report that it is a great way to experiment with new features
of virtual machines, simulate them, and then generate them as C code.

Nick Kallen

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
> Maybe these results represent a failure on UCB's part since the goal
> of a course like SICP is not to turn out students who "favor Scheme"
> but to turn out students who understand the structure and
> interpretation of any kind of computer program.

The goal of Berkeley is not to turn out FP converts, it's to teach students
computer science. Students are free to make their own choices, and after
exposure to two languages they make these choices.

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
Nick Kallen (nka...@uclink4.berkeley.edu) wrote:
: > Maybe these results represent a failure on UCB's part since the goal

Nick, I seem to be failing to communicate clearly with you. The point
of an SICP-like introduction to programming is not about functional
programming only, or Scheme only, etc. SICP teaches how to understand
the mechanics that underly a wide range of programming languages. What
better way to be able to make a free choice than to have a solid
foundation in programming language semantics?

Nick Kallen

unread,
Apr 17, 1999, 3:00:00 AM4/17/99
to
> Nick, I seem to be failing to communicate clearly with you. The point
> of an SICP-like introduction to programming is not about functional
> programming only, or Scheme only, etc. SICP teaches how to understand
> the mechanics that underly a wide range of programming languages. What
> better way to be able to make a free choice than to have a solid
> foundation in programming language semantics?

OK, I see what you mean. Well, it doesn't represent a failure on Berkeley's
part, because having personally taken the classes, they're taught extremely
effectively. Students make their own decisions based on probably one of the
most ideal presentation of SICP possible.

Simon Helsen

unread,
Apr 18, 1999, 3:00:00 AM4/18/99
to Nick Kallen
>At my university, Berkeley, the first (real) course for CS programmers uses

<snip>

>It's important to note that for most students here, their college
>programming carreer began in Scheme, although a strong percentage of them
>had previous programming experience in (presumably) imperitive languages in

>high school and such. However, it is still not a valid conclusion to say


>that what you learn first is what you prefer: clearly a significant
>percentage of people whose first language was Scheme prefer Java.

No, that is not clear to me at all. Berkeley, as far as I know, is a very
good university for computer science. Students who start in Berkeley are
probably very interested in computer science and programming in
particular. That professor should have asked in his interview what their
"real" first programming language was as well. It won't be Scheme, I
would bet on that. So, forget about those results.

Another point is indeed that using Abelson's book, the students did not
learn a programming language, but learned about programming (which is what
makes Berkeley an excellent university!) If you're well on your way with
programming principles, learning Java is not very hard anymore. And I also
wonder how the questions were formulated, because Berkeley graduates are
about to make a lot of money when they come out and they won't be able to
that in Scheme. In other words, I wouldn't be so sure about the way people
judge their preference for a programming language - there are likely many
non-technical aspects (not to speak about hype)

Simon


pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 18, 1999, 3:00:00 AM4/18/99
to
Simon Helsen (hel...@informatik.uni-freiburg.de) wrote:

: In other words, I wouldn't be so sure about the way people judge


: their preference for a programming language - there are likely many
: non-technical aspects (not to speak about hype)

And with Java's rich libaries, etc. there is a lot of incentive to
choose it no matter what it's flaws in the language per se.

Robert Bernecky

unread,
Apr 18, 1999, 3:00:00 AM4/18/99
to Brian Rogoff

Brian Rogoff wrote:

> (2) Current functional language implementations suck at compiling array

Not quite a fair statement. I point you at 3 counter-examples:

a. SISAL: This produces very good vector code, that can
beat Fortran on UP and MP systems. It's also good on short,
squat arrays, but does indeed roll over and die on tall,
skinny arrays. This is because it's a vector-of-vectors
language, so a matrix requires (in the present compiler)
one descriptor per row. This is performance death.

b. SAC: Produces good UP and MP code, but the language
is heavily subsetted -- arrays are fixed size, for example.

c. APEX: This is my APL to SISAL compiler, which does fairly
good, but suffers from (a), of course.

I think that within a year, we'll have nailed the big remaining
performance problems in functional array languages.

Bob

Joe Armstrong

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Henrik Bäärnhielm <d98...@d.kth.se> writes:


> But then, there must be SOME negative sides of functional languages
> versus imperative languages, musn't it?

A number of factors:

1) Speed - FPs are usually slower
2) Libraries - Not so many good libraries
3) IDEs - none yet
4) Integration with Imperative langauges - usually inefficient
5) Packaging - can't make stand alone executables.

Comments:

1) Doesn't worry me. If it's "fast enough" - who cares - I stopped
worrying when I got 133 MHz pentium - now that is *fast* :-)

2) GUI libraries worries me. I've seen *nothing* like
it for Haskell,Erlang,scheme, ML, ... Other libraries OK.

3) I'd like somethink like Delphi - great - I've not seen anything
this good for FPs

3) see 1) - only a problem for "fine grain" interaction.

4) Sigh. I'm hopeful here. [I've made an Erlang that is smaller than
perl, starts faster than perl, and makes *tiny* compressed
executables - [cat in erlang is a few hundered bytes + a single
Shared library of about 0,5 Meg]

> Or why doesn't everyone use
> them?

Because they're not mainstream.

If the industry were to widly adopt languages like Erlang, Prolog, ..
there would be mass unemployment of programmers.

The usual way of doing things is

1) make something that is impossibly difficult to use
2) Hype it like mad - tell everybody how easy to use it is
3) Sell masses of tools and books that just about make it
usable
4) Sell bux fixes and support

But what we are doing is:

a) Make something that is incredably easy to use (Erlang :-)
b) Give it away free
c) Don't advertise it (We have no hype budget :-)
d) Hope it spreads by word of mouth

/Joe

--
Joe Armstrong Computer Science Laboratory +46 8 719 9452
AT2/ETX/DN/SU Ericsson Telecom SE-126 25 Stockholm Sweden
j...@cslab.ericsson.se http://www.ericsson.se/cslab/~joe


Ketil Z Malde

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> length :: [a] -> Int
> length = foldl' (\n _ -> n + 1) 0

Actually, I think this is pretty cool, since if you're reading the
Prelude, you probably know enough to write the trivial length function
already.

> Or in Scheme with the historical car and cdr (nobody really know why
> that is changed)

Uh? Personally, while I'd prefer head and tail or something like
that, I don't think having obscure names matter all that much, in
particular for commonly used concepts. Surely, using * to denote
pointers and & for addresses is hardly intuitive?

> lenght :: [a] -> Int
> length [] = 0
> length (x:xs) = 1 + length(xs)

> not
> length (front:rest) = 1 + length(rest)

> topOf (x:_) = x


> not
> topOf (front:_) = front

Are you suggesting that writing a list as (x:xs) is inferior to
(front:rest)? The (x:xs) construct is so common, I don't think that's
a problem, and it does make things more compact.

Using an 'x' for a parameter is also pretty common practice, IMHO. I
just don't see any real benefit from changing that.

> Another point is: The imperative stuff can be seen as a machine.

Yep, to many it's a more logical way of thinking. OTOH, I think if
one started out with functional programming, imperative style would be
experienced as rather cumbersome.

> Even worse the main stream believe in FP seems to be: "we don't need an
> debugger"

Not true, I think. But of course, you don't need to spend time in a
debugger hunting mismatched new/deletes, tracing stray pointers,
chasing type errors, etc.

On the other hand, error messages are often rather cryptic, in
particular to the beginner. (Well, if you use MSVC++, the error
messages are pretty braindead also, but at least you can look it up).

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

Joe Armstrong

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
jha...@dadgum.com (James Hague) writes:

>
> I didn't start this thread, but I wanted to give a quick thank you to
> everyone who contributed. Many good points were brought up, and the
> discussion was most interesting.
>
> One thing I'd like to add is that IMO the argument about functional
> languages having a steep learning curve for people not familiar with them
> doesn't apply nearly so much to Erlang. I haven't been too interested in
> Erlang in the past, because of its relatively poor performance on
> sequential code. Lately I've been taking a deeper look, and I'm
> impressed.

Thank you.

Simplicity was a design goal.

When you write a book you have a target audience in mind.

When you design and implement a programming language you have a
target programmer in mind.

Our goal was a language for Ericsson programmers - not for rocket
scientists with propellers on their heads :-)

So you won't find currying, monads, lazy evaluation, ... and you
will find "imperative features".

We have taught Erlang to a couple of thousand programmers in
Ericsson and very few have had problems learning it.

My experience after teaching Erlang a lot is:

"Programmers are good or bad - a good programmer can learn ANY
language - actually the best Erlang programmers were the C skeptics.
Really good C programmers who criticised Erlang at every point
often became Erlang evangalists"


> Many of the usual stumbling blocks, like curried functions and odd use of
> parentheses, aren't a part of Erlang. And neither are functors, module
> signatures, objects, references, and convoluted class systems. User
> defined types aren't necessary. Arrays are just tuples.
>
> I like Ocaml very much, both because of the language definition and
> because of the optimizing compiler. And I like Haskell because the
> notation is very clean and mathematical. But Erlang is the simplest of
> the three, and, at the same time, the one I'm seeing how to use for real
> applications in the most straightforward manner.

> Someone recently was ranting about functional languages without all the
> usual baggage. Erlang seems to be that.
>
> --
> James Hague

AJ Megacz

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to

> At my university, Berkeley, the first (real) course for CS
> programmers uses Scheme with Structure And Interpretation of
> Computer Programs as the textbook. The second course is in Java, and
> this is primarily datastructures/algorithms/programming-in-the-large
> material. The third course is on machine structures, which teaches C
> and ASM.

I'd like to add that I don't think one semester is long enough to
really "get" FP in the deepest sense of understanding why it's so
good. At Carnegie Mellon our first 3 CS courses go C++/C++/ML (I think
you can substitute Java for one of the C++es). I spent my entire
semester of ML thinking "but I can do all this in C -- why learn
another language?".

Towards the end of the semester, my TA finally explained to me that ML
(and FP) isn't about solving a new class of problems that is
unsolvable in C -- it's about solving the same problems with less
programmer effort.

But that's exactly the problem -- it takes a substantial amount of
time before somebody can code in an FP as "easily" as they can code in
an IP language (assuming that they already know IP, which is the case
for 95+% of all programmers). So they get all the suffering of
learning the new language with [almost] none of the benefits.

I went on to become a TA for that same class, and after my second
semester of constant exposure to ML, writing code in FP (ML or
Haskell) is now much easier for me than writing C code. I remain
convinced that C isn't ever going to get substantially easier for me
(after 8 years of coding in it).

It also helps that I've done a lot of reading into why FP is the way
it is. Most undergraduates don't understand the compiler optimizations
that can come from tail recursion, single assignment, referential
transparency, dependent types, and single-threading guarantees. For
them, these are cumbersome restrictions, not prerequisites for highly
optimizable code.

> No, that is not clear to me at all. Berkeley, as far as I know, is a very
> good university for computer science. Students who start in Berkeley are
> probably very interested in computer science and programming in
> particular.

Amen. I would be _very_ surprised to find a CS or CE major at my
school who hadn't coded in an imperative language before college (even
if it's just BASIC)

- aj

---
WARNING: I NO LONGER OWN <meg...@usa.net> -- DO NOT SEND EMAIL THERE
"Nobody has any 'Rights'. We are entitled only to Liberties"
Adam Megacz <meg...@cmu.edu>

Friedrich Dominicus

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Ketil Z Malde wrote:
>
> Friedrich Dominicus <Friedrich...@inka.de> writes:
>
> > length :: [a] -> Int
> > length = foldl' (\n _ -> n + 1) 0
>
> Actually, I think this is pretty cool, since if you're reading the
> Prelude, you probably know enough to write the trivial length function
> already.

Nevetheless it's not easy to read on my eyes. just the (\n _ need
pretty much knowledge.

>
> > Or in Scheme with the historical car and cdr (nobody really know why
> > that is changed)
>
> Uh? Personally, while I'd prefer head and tail or something like
> that, I don't think having obscure names matter all that much, in
> particular for commonly used concepts. Surely, using * to denote
> pointers and & for addresses is hardly intuitive?

No it isn't. But neither is ^.

>
> > lenght :: [a] -> Int
> > length [] = 0
> > length (x:xs) = 1 + length(xs)
>
> > not
> > length (front:rest) = 1 + length(rest)
>
> > topOf (x:_) = x
> > not
> > topOf (front:_) = front
>
> Are you suggesting that writing a list as (x:xs) is inferior to
> (front:rest)? The (x:xs) construct is so common, I don't think that's
> a problem, and it does make things more compact.

That's the point (it's more compact) not even a though on how this look
to not so used programmers. And against all advise to use name which
make a sense for users. It's compact so it's better. You don't mention
my other example form PFDS. Very intuitive

>
> Using an 'x' for a parameter is also pretty common practice, IMHO. I
> just don't see any real benefit from changing that.

so does a C-programmer with & && | || * ** and all the nice stuff.

>
> > Another point is: The imperative stuff can be seen as a machine.
>
> Yep, to many it's a more logical way of thinking. OTOH, I think if
> one started out with functional programming, imperative style would be
> experienced as rather cumbersome.

That might be true but there aren't a lot of universities where FP is
the first programming language and I'm quite sure that most which learn
programming for themselves start with an imperative language. So whyt
that than? There are a lot of free FP-languages too. But if you take a
look at the stuff which comes for UNICES you hardly finf FP-programming.
And worst Emacs-list look to terrible that nobody gives FP another
chance.

>
> > Even worse the main stream believe in FP seems to be: "we don't need an
> > debugger"
>
> Not true, I think. But of course, you don't need to spend time in a
> debugger hunting mismatched new/deletes, tracing stray pointers,
> chasing type errors, etc.

If that is not true, why couldn't I find one e.g for Haskell, OCAML? So
I think this is so long true till I can find one. which let's me see how
a functin is evaluated. I bet s.o will say that's pretty simple just
write it on your own. For me it isn't.


>
> On the other hand, error messages are often rather cryptic, in
> particular to the beginner. (Well, if you use MSVC++, the error

> messages are pretty braindead also, but at least you can look it up).

Error messages are cryptic in a lot of languages and the are not better
in FP too. So no point for both sides. Maybe a small minus for FP,
because FP is claimed to be better.

Regards
Friedrich

Nick Kallen

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
> Error messages are cryptic in a lot of languages and the are not better
> in FP too. So no point for both sides. Maybe a small minus for FP,
> because FP is claimed to be better.

Claimed by whom? Please don't let a few people encourage generalizations. As
a person who's been programming in Haskell/Clean/ML for a few years, I think
FP is great, but not better.
I hate to use the cliche "best tool for the job," but I subscribe to
that viewpoint. In the most general sense, I think that there are many ways
to think about computation. Two of which are the lambda calculus and an
imperative calculus (which I visualize as MIPS assembly). Each is quite
adept at handling specific computations, even though all are essentially
equivalent. Other models of execution that are quite adept is the pi
calculus and derivitives like the ambient calculus (of which I'm a huge
fan). For each paradigm there are applications that beg to be written in it.

Ketil Z Malde

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> Nevetheless it's not easy to read on my eyes. just the (\n _ need
> pretty much knowledge.

No, it's not trivial, but it should lead you to think, hey, why are
they doing that, you look it up, work it you, and end up wiser.

> > Uh? Personally, while I'd prefer head and tail or something like
> > that, I don't think having obscure names matter all that much, in
> > particular for commonly used concepts. Surely, using * to denote
> > pointers and & for addresses is hardly intuitive?

> No it isn't. But neither is ^.

So Pascal isn't very intuitive or straightforward either?

Apparently unlike most people, I remember learning C. The pointer
stuff was really, really hard. Even in Pascal, pointers were
difficult. IO was difficult. The printf format was obscene.

Okay, you work with it for a while, and you type **argv and %d in your
sleep. But it's not intuitive, easy on the beginner, or any of that.

> > > length (x:xs) = 1 + length(xs)

vs.

> > > length (front:rest) = 1 + length(rest)

>> Are you suggesting that writing a list as (x:xs) is inferior to


>> (front:rest)? The (x:xs) construct is so common, I don't think that's
>> a problem, and it does make things more compact.

> That's the point (it's more compact) not even a though on how this look
> to not so used programmers. And against all advise to use name which
> make a sense for users. It's compact so it's better. You don't mention
> my other example form PFDS. Very intuitive

>> Using an 'x' for a parameter is also pretty common practice, IMHO. I
>> just don't see any real benefit from changing that.

> so does a C-programmer with & && | || * ** and all the nice stuff.

No no no. Any third grade student knows that x is the unknown. OTOH,
most people would interpret & as a conjunction, | as a "pipe" or
"bar", * as footnote or multiplication, and ** probably as
exponentiation.

The only vaguely intuitive thing about C is using & for bitwise (and
&& for logical) and, and | for bitwise (|| logical) or. And still,
the difference between logical and bitwise operators, and complexities
like signed/unsigned is the source for no end of confusion.

>> Yep, to many it's a more logical way of thinking. OTOH, I think if
>> one started out with functional programming, imperative style would be
>> experienced as rather cumbersome.

> That might be true but there aren't a lot of universities where FP is
> the first programming language and I'm quite sure that most which learn
> programming for themselves start with an imperative language.

Unfortunately, yes. So we're back to inertia and mindshare as the
main reasons for low FP acceptance.

> So whyt that than?

Whyt indeed.

> There are a lot of free FP-languages too. But if
> you take a look at the stuff which comes for UNICES you hardly finf
> FP-programming. And worst Emacs-list look to terrible that nobody
> gives FP another chance.

Nonsense, any Debian or Red Hat archive is brim full of FP language
implementations. And other Unices traditionally only come with a C
compiler, usually in a castrated version, if at all these days.

>> Not true, I think. But of course, you don't need to spend time in a
>> debugger hunting mismatched new/deletes, tracing stray pointers,
>> chasing type errors, etc.

> If that is not true,

I meant that the general sentiment is *not* that there is no need for
a debugger. I didn't mean the FP niche was overflowing with debugging
tools, which it clearly isn't.

> why couldn't I find one e.g for Haskell, OCAML?

The NHC group have a debugger for Haskell, I think.

> Error messages are cryptic in a lot of languages and the are not better
> in FP too. So no point for both sides. Maybe a small minus for FP,
> because FP is claimed to be better.

FP doesn't claim to give better error messages, AFAIK. From the
implementations I have looked at, many error messages could be a bit
more verbose and beginner friendly, IMHO.

Ulf Wiger

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
>>>>> "Eugene" == Eugene Dragoev <eug...@istar.ca> writes:

Eugene> Let's face it - I make my living writing Java programs and
Eugene> used to write C/C++ and assembly before. If all I know is
Eugene> Haskell what kind of job I could get right now?

I can't speak for Haskell, but when it comes to Erlang, the
programmers we have don't *just* know Erlang. We want them to be
versatile and pick the right tool for the job.

Religion is all too common among programmers, and not something
found only among FP advocates - Java and C programmers can be just
as religious.

I see modern product development as a combination of pragmatic
decisions about components: how they're implemented and how they
interact. We use Erlang, C, C++, Perl, shell scripts, Expect, Java,
and Erlang (I may have forgotten something...) in the AXD 301
ATM switch.

/Uffe
--
Ulf Wiger, Chief Designer AXD 301
Ericsson Telecom AB tfn: +46 8 719 81 95
Varuvägen 9, Älvsjö mob: +46 70 519 81 95
S-126 25 Stockholm, Sweden fax: +46 8 719 43 44

Dr. Seth A. Greenblatt

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Friedrich Dominicus wrote:

> Ketil Z Malde wrote:
> >
> > Friedrich Dominicus <Friedrich...@inka.de> writes:
> >
>
> >
> > > Even worse the main stream believe in FP seems to be: "we don't need an
> > > debugger"
> >

> > Not true, I think. But of course, you don't need to spend time in a
> > debugger hunting mismatched new/deletes, tracing stray pointers,
> > chasing type errors, etc.
>

> If that is not true, why couldn't I find one e.g for Haskell, OCAML? So
> I think this is so long true till I can find one. which let's me see how
> a functin is evaluated. I bet s.o will say that's pretty simple just
> write it on your own. For me it isn't.
>

Ocaml has a debugger and a number of other useful programming tools.

-- Seth
=========================
Dr. Seth A. Greenblatt
President & CEO
Objective Science, Inc.
sgree...@erols.com


Friedrich Dominicus

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Nick Kallen wrote:
>
> > Error messages are cryptic in a lot of languages and the are not better
> > in FP too. So no point for both sides. Maybe a small minus for FP,
> > because FP is claimed to be better.
>
> Claimed by whom? Please don't let a few people encourage generalizations. As
> a person who's been programming in Haskell/Clean/ML for a few years, I think
> FP is great, but not better.


This group is called c.l.f and most of the time I read that FP is still
better.


> I hate to use the cliche "best tool for the job," but I subscribe to
> that viewpoint.

Agreed but what is the best tool for FP-languages?

Regards
Friedrich

Dana Harrington

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
In article <KETIL-86ya...@ketilboks.bgo.nera.no>,

Ketil Z Malde <ke...@ii.uib.no> wrote:
> Friedrich Dominicus <Friedrich...@inka.de> writes:
>
> Are you suggesting that writing a list as (x:xs) is inferior to
> (front:rest)? The (x:xs) construct is so common, I don't think that's
> a problem, and it does make things more compact.
>
> Using an 'x' for a parameter is also pretty common practice, IMHO. I
> just don't see any real benefit from changing that.

Furthermore when one has more than one list they are decomposing I find it
much easier to read (x:xs),(y:ys),... than (front1:rest1),(front2:rest2),...
In functional languages one usually writes short functions, in this respect I
find that descriptive variable names do not always make a program more
readable. I personally find that if the code is short using long variable
names makes the code harder to read.

> > Another point is: The imperative stuff can be seen as a machine.
>

> Yep, to many it's a more logical way of thinking. OTOH, I think if
> one started out with functional programming, imperative style would be
> experienced as rather cumbersome.

Quite true, I find it easier to think about evaluating an expression than
tracking through an evolving state. In the first case I already start off
with the answer, it is just a matter of simplifying it; in the second case I
am forced to think like a machine and think in terms of updating memory
locations. Two different ways of thinking, I'm not going to say one is
easier/better than the other, but I think they are both valuable ways of
approaching problems.

> > Even worse the main stream believe in FP seems to be: "we don't need an
> > debugger"
>
> Not true, I think. But of course, you don't need to spend time in a
> debugger hunting mismatched new/deletes, tracing stray pointers,
> chasing type errors, etc.

In a purely functional language like Haskell or Clean I do not find much need
for a debugger myself. Most of the debugs I hunt down with a debugger in C
involve array overruns, memory management errors and type errors (curse those
automatic casts.) I find that an interpretor is much more important in FP.
Since I don't have to deal with state I can just run the individual functions
from my program on input and see what they evaluate to, if there is an error
than at some point a function will produce the wrong output. Hugs is
indispensable when writing Haskell programs. I believe there are some
(non-referentially transparent) debugging `functions' in Hugs, I think trace
is the name. There are some places where some sort of traditional debugging
facility would be convenience, but this doesn't seem to be as crucial in FP
as in IP.

Dana

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/ Search, Read, Discuss, or Start Your Own

Friedrich Dominicus

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Ketil Z Malde wrote:
>
> Friedrich Dominicus <Friedrich...@inka.de> writes:
>
> > Nevetheless it's not easy to read on my eyes. just the (\n _ need
> > pretty much knowledge.
>
> No, it's not trivial, but it should lead you to think, hey, why are
> they doing that, you look it up, work it you, and end up wiser.

This is very weak and I hate such things it's the same as if I write
while(*string)

What have you all to know to understand this. So why should the same
faults be done in FP?


>
> > > Uh? Personally, while I'd prefer head and tail or something like
> > > that, I don't think having obscure names matter all that much, in
> > > particular for commonly used concepts. Surely, using * to denote
> > > pointers and & for addresses is hardly intuitive?
>
> > No it isn't. But neither is ^.
>
> So Pascal isn't very intuitive or straightforward either?

No. Easier is IMO Python and the like.


>
> Apparently unlike most people, I remember learning C. The pointer
> stuff was really, really hard. Even in Pascal, pointers were
> difficult. IO was difficult.


Monads are easier to undertand and use as the printf family? Quite
interesting.


>
> > That's the point (it's more compact) not even a though on how this look
> > to not so used programmers. And against all advise to use name which
> > make a sense for users. It's compact so it's better. You don't mention
> > my other example form PFDS. Very intuitive
>

> >> Using an 'x' for a parameter is also pretty common practice, IMHO. I
> >> just don't see any real benefit from changing that.


so then you think that this is fine fp-programming to cited from PFDS
(p 192 around mid)
instance Deque d => CatenableDeque (SimpleCatDeque d) where
(Shallow d1) ++ (Shallow d2)
| tooSmall d1 = Shallow (dappendL d1 d2)
| tooSmall d2 = Shallow (dappendR d1 d2)
| otherwise = Deep d1 empty d2


everything quite clear? Not for me. Here's some Eiffel code from QUEUE
which append one quue to another (I'm quite sure this is not what the
code above does but maybe s.th simular)
append (s: SEQUENCE [G]) is
-- Append a copy of `s'.
require
argument_not_void: s /= Void
local
l: like s
do
if s = Current then
l := deep_clone (s)
else
l := s
end
from
l.start
until
l.exhausted
loop
extend (l.item);
l.forth
end
ensure
new_count: count >= old count
end

much longer indeed but I think more readable with variable names which
make sense. You might come to another conclusion.

>
> > so does a C-programmer with & && | || * ** and all the nice stuff.
>
> No no no. Any third grade student knows that x is the unknown. OTOH,
> most people would interpret & as a conjunction, | as a "pipe" or
> "bar", * as footnote or multiplication, and ** probably as
> exponentiation.

what about and, or, xor? why ** for exponeentiation this is a pointer of
a pointer to .. (everyone knows ;-)

>
> The only vaguely intuitive thing about C is using & for bitwise (and
> && for logical) and, and | for bitwise (|| logical) or. And still,
> the difference between logical and bitwise operators, and complexities
> like signed/unsigned is the source for no end of confusion.

What do you mean? bitwise and and logical operators are difficult to
understand?
Can't believe that.


>
> > There are a lot of free FP-languages too. But if
> > you take a look at the stuff which comes for UNICES you hardly finf
> > FP-programming. And worst Emacs-list look to terrible that nobody
> > gives FP another chance.
>
> Nonsense, any Debian or Red Hat archive is brim full of FP language
> implementations. And other Unices traditionally only come with a C
> compiler, usually in a castrated version, if at all these days.

Oh my Debian system comes with FP packages but they are not installed by
default as is e.g C or python or perl or awk ... another point why I
think FP is not so accepted it the tool-box principle on Unix.

cat file | tr " \t\r" "\n\n\n" | sort | uniq -c | tail +2 which may be
easy to read for Unix lovers but terrible for others but if you get
into touch with computers (especially Unices) you start with cd ls and
the like and maybe you learn a grep bla *.c and it's likely that you
begin with a small shell-script
which is a step-by-step algorithm normally and you won't get in contact
e.g with SCSH at first.

>
> >> Not true, I think. But of course, you don't need to spend time in a
> >> debugger hunting mismatched new/deletes, tracing stray pointers,
> >> chasing type errors, etc.

Oh that's quite ok, but to follow what you have written gives you some
feeling of what is going on. I'm not sure what is going on in a
FP-script.

e.g length is pretty nice in FP languages but how can I follow it how
can I visualize it? I don't know but how to do that in C, Python, Eiffel
and the like is not a problem at all.


>
> The NHC group have a debugger for Haskell, I think.

hugs hasn't AFAIK but hugs has a main advantage over NHC, or GHC. it is
an interpreter. but you can't do what you can do in Python. In Python i
can define a functin very easily on the command line I can't do that in
Hugs,what a mess.

>
> > Error messages are cryptic in a lot of languages and the are not better
> > in FP too. So no point for both sides. Maybe a small minus for FP,
> > because FP is claimed to be better.
>

> FP doesn't claim to give better error messages, AFAIK. From the
> implementations I have looked at, many error messages could be a bit
> more verbose and beginner friendly, IMHO.

No FPlers don't claim that, but they don't provide me with a debugger
neither. So I just have to get it right, and that's not too easy if you
learn how to function can be handeled.

Regards
Friedrich

Lennart Augustsson

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> > > Nevetheless it's not easy to read on my eyes. just the (\n _ need
> > > pretty much knowledge.
> >
> > No, it's not trivial, but it should lead you to think, hey, why are
> > they doing that, you look it up, work it you, and end up wiser.
>
> This is very weak and I hate such things it's the same as if I write
> while(*string)

Both are idioms, and if you claim proficiency in a language
you should know the common idioms.

--

-- Lennart Augustsson
[This non-signature is unintentionally not left unblank.]

Lennart Augustsson

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

But the Haskell code does something rather different and much more
subtle. Comparing these is like saying that you don't like computing
prime numbers in Haskell, but prefer computing factorial in Eiffel.

kin...@sp2n21.missouri.edu

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
In article <371AFB04...@inka.de>,

Friedrich Dominicus <Friedrich...@inka.de> wrote:
>Ketil Z Malde wrote:
>>
>> Friedrich Dominicus <Friedrich...@inka.de> writes:

[snip stuff about length function]

>> > Or in Scheme with the historical car and cdr (nobody really know
>> > why that is changed)
>>

>> Uh? Personally, while I'd prefer head and tail or something like
>> that, I don't think having obscure names matter all that much, in
>> particular for commonly used concepts. Surely, using * to denote
>> pointers and & for addresses is hardly intuitive?
>
>No it isn't. But neither is ^.

Wow. That's a very revealing exhchange that doesn't reveal very much. :-)

Let's start with the C operators * and &. I'm sure that today's
contestants know what these really are, but the way they describe
them is really weird, which tells us something *else* about C other
than what they thing.

But to be hideously clear about it, you don't use * "to denote pointers".
There is no special convention for naming a variable containing a pointer
in C. "foo" could be an int, a float, a pointer to either, or almost
anything else. What * and & are is operators. So * in C is the
dereference operator, and if I see "*foo" in a C program, I expect that
the variable "foo" itself did contain a pointer that I am now
dereferencing. Similarly, "&" doesn't denote an address, it's an operator
that returns an address, and you can take try to take the address of
almost anything.

The problem in C is that the declaration syntax is at best an
acquired taste, so that you see things like

int *x;

which apparently give naive people almost every idea but the correct one,
even before you start talking about arrays, much less even more
complicated things. The fact that there are type declarations in C++ that
even *experts* get confused about is pretty stunning.

Which makes it all the more depressing when you see somebody suggest
something much, much better and get nowhere with it. Every sentient
programmer should read the "C++ re-syntaxed" and "SPECS" papers written by
B. M. Werther and D. M. Conway:

http://www.cs.monash.edu.au/~damian/papers/

I expect all the functional language programmers will go away nodding
their heads, saying, "Yes, that's a more reasonable way to do things".
But at least some of the C++ people will first be in denial, then in
despair...

But getting back to the top level point, people are surprisingly good at
learning pretty arbitrary associations between labels and objects, but
they are surprisingly bad at learning (and using) arbitrary syntactic
constructions. The difference between "*" and "^" as operators might not
be worth fighting over, but the difference between:

void (*set_new_handler(void (*) (void))) (void);

which is often "improved" to:

typedef void (*new_handler) (void);
new_handler set_new_handler(new_handler);

and the SPECS version:

func set_new_handler : (^(void -> void) -> ^(void -> void));

which might also be written as:

type new_handler : ^(void -> void);
func set_new_handler : (new_handler -> new_handler);

is worth having a religious war over. (This is a motivating example in
the SPECS paper, as you might have guessed.)

jking


>>
>> > lenght :: [a] -> Int
>> > length [] = 0

>> > length (x:xs) = 1 + length(xs)
>>

>> > not


>> > length (front:rest) = 1 + length(rest)
>>

>> > topOf (x:_) = x
>> > not
>> > topOf (front:_) = front
>>

>> Are you suggesting that writing a list as (x:xs) is inferior to
>> (front:rest)? The (x:xs) construct is so common, I don't think that's
>> a problem, and it does make things more compact.
>

>That's the point (it's more compact) not even a though on how this look
>to not so used programmers. And against all advise to use name which
>make a sense for users. It's compact so it's better. You don't mention
>my other example form PFDS. Very intuitive
>
>>
>> Using an 'x' for a parameter is also pretty common practice, IMHO. I
>> just don't see any real benefit from changing that.
>

>so does a C-programmer with & && | || * ** and all the nice stuff.
>>

>> > Another point is: The imperative stuff can be seen as a machine.
>>
>> Yep, to many it's a more logical way of thinking. OTOH, I think if
>> one started out with functional programming, imperative style would be
>> experienced as rather cumbersome.
>

>That might be true but there aren't a lot of universities where FP is
>the first programming language and I'm quite sure that most which learn

>programming for themselves start with an imperative language. So whyt
>that than? There are a lot of free FP-languages too. But if you take a


>look at the stuff which comes for UNICES you hardly finf FP-programming.
>And worst Emacs-list look to terrible that nobody gives FP another
>chance.
>
>>

>> > Even worse the main stream believe in FP seems to be: "we don't need an
>> > debugger"
>>

>> Not true, I think. But of course, you don't need to spend time in a
>> debugger hunting mismatched new/deletes, tracing stray pointers,
>> chasing type errors, etc.
>

>If that is not true, why couldn't I find one e.g for Haskell, OCAML? So
>I think this is so long true till I can find one. which let's me see how
>a functin is evaluated. I bet s.o will say that's pretty simple just
>write it on your own. For me it isn't.
>
>
>>

>> On the other hand, error messages are often rather cryptic, in
>> particular to the beginner. (Well, if you use MSVC++, the error
>> messages are pretty braindead also, but at least you can look it up).
>

>Error messages are cryptic in a lot of languages and the are not better
>in FP too. So no point for both sides. Maybe a small minus for FP,
>because FP is claimed to be better.
>

>Regards
>Friedrich

Dana Harrington

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
In article <371B690D...@inka.de>,

Woah, this seems like an excellent non-example.
Variables in Haskell example:
d1 : first deque
d2 : first deque
Variables in Eiffel example:
: first sequence
s : second sequence
l : s, or a copy of s
count : length of `'?
new_count : length of `' after appending s?
old_count : length of `' before appending s?

What am I appending to what? In the first example I think it is clear that
d2 is being appended to d1. It's not clear at all (to me) what is happening
in the second case, I assume ``extend (l.item)'' appends the value of the
current item in sequence l onto the object whoses method is being called, and
that ``l.forth'' moves the current index for l forward, but this is just a
guess. Worse yet `l' stands for one sequence, while `' stands for the other
(the object whose method we are in). You are not going to tell me that `'
(blank, also known as `this' or `self') is a descriptive variable name are
you? And this is not simply a poor choice of variable names, it is enforced
by the language syntax.

In addition to the fact that the two examples do different things I'd have to
conclude myself that the Haskell example is much easier to read. An
additional problem with variables in IP is that they are variable, the value
of the variable depends on at what point in the computation you observe it.
In pure FP a variable, once set, is not changed, hence I don't have to keep
track of what the variable means `right now', it is defined once and for all.
Not to mention the ghastly habit some imperative programmers have of reusing
the same variable name for different, unrelated values.

Perhaps you could search a little harder for a better example, to me `l' and
`s' are as incomprehensible as variable names as `d1' and `d2'. Perhaps you
were being ironic when you suggested this example?

Simon Raahauge DeSantis

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
In article <371B690D...@inka.de>, Friedrich Dominicus wrote:
>Ketil Z Malde wrote:
>> Apparently unlike most people, I remember learning C. The pointer
>> stuff was really, really hard. Even in Pascal, pointers were
>> difficult. IO was difficult.
>
>
>Monads are easier to undertand and use as the printf family? Quite
>interesting.
>
I for one find it pretty hard to memorize all the one-character codes printf
and its friends use.
The concept of monads is difficult I think (I've got a vague and fuzzy
handle on how to use them (sometimes) in Haskell), but actually doing IO
with them is really easy once you're familiar with them. You just chain them
together using >> and >>=. It's almost like C++'s IOStreams would like to be
(it's just so nice to automatically derive Show in Haskell...).


--
-Simon Raahauge DeSantis

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 19, 1999, 3:00:00 AM4/19/99
to
: >Monads are easier to undertand and use as the printf family? Quite
: >interesting.

Monads are a kind of straightjacket. You cannot safely place an I/O
statement in an arbitrary expression of a functional program. Monads
are used to enforce this goal.

I find it easy to use printf and other side effects in C. But after
some amount of modifying the code, a C application can become
unwieldy.

The use of monads helps to prevent this in a language like Haskell.
Yet it is not my currently preferred way of programming. I like the
simplicity of a mostly-functional language like Erlang.

Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Lennart Augustsson wrote:

> > much longer indeed but I think more readable with variable names which
> > make sense. You might come to another conclusion.

> But the Haskell code does something rather different and much more
> subtle. Comparing these is like saying that you don't like computing
> prime numbers in Haskell, but prefer computing factorial in Eiffel.

What does the Haskell code do. Isn't that a shallow copy form one Queue
to antother. If you understand what the Haskell code does, you can tell
me and I look for another solution. If I understand that code it's about
a shallow or deep copy. But of course I might be completely wrong. So
much about understanding FP.

Regards
Friedrich

Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
>
> In a purely functional language like Haskell or Clean I do not find much need
> for a debugger myself. Most of the debugs I hunt down with a debugger in C
> involve array overruns, memory management errors and type errors (curse those
> automatic casts.)

See my other comment about some function in Haskell which I don't
understand. And would like to look in to undertand. Even a simple lenght
can't be visualized.
Eiffel V 2.3 came with a quasi non-existent debugger. But now nearly all
Eiffel compilers come with a debugger. Why, because a debugger let you
look what's going on, in Eiffel you don't need an debugger for array
overruns, memory management and type errors. So if we just would have
such kind of bugs Eiffel didn't need one. so there must be a bunch of
other areas where a debugger is handy. And I bet the same holds for FP
languages.

There are some places where some sort of traditional debugging
> facility would be convenience, but this doesn't seem to be as crucial in FP
> as in IP.

That was said from OO too. And it's just not true. Of course yoiu
needn't a debugger but then you help yourself with s.th like
if condition then
put_string("I'm here in bla all ok");
or the like

So how do you do that in FP?
Regards
Friedrich

Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
>
> Wow. That's a very revealing exhchange that doesn't reveal very much. :-)

Indees but for a Pascal programmer this makes perfect sense ;-)


>
> But getting back to the top level point, people are surprisingly good at
> learning pretty arbitrary associations between labels and objects, but
> they are surprisingly bad at learning (and using) arbitrary syntactic
> constructions. The difference between "*" and "^" as operators might not
> be worth fighting over, but the difference between:
>
> void (*set_new_handler(void (*) (void))) (void);
>
> which is often "improved" to:
>
> typedef void (*new_handler) (void);
> new_handler set_new_handler(new_handler);

why not (an Eiffelish language)
set_new_handler({f}) : {f}

a function that takes a function as argument which don't have a return
value and don' have any parameter and returns a function whihc on't have
a retrun value and no parameter.


>
> and the SPECS version:
>
> func set_new_handler : (^(void -> void) -> ^(void -> void));
>
> which might also be written as:
>
> type new_handler : ^(void -> void);
> func set_new_handler : (new_handler -> new_handler);

I don't think that it's was agood idear to tell somehting which stands
for nothing (void) gets' an extra name. So I do not think that

void bla(void) (C) is as readable and understandable as
bla (Eiffel)

If I wouldn't know C I woiuld say bla is a function taking a Parameter
of type void and returning an Parameter of type void. That is
desparately wrong here, but how should one know if
int blu (int) means: blus is a function which take an int Paramter and
returns an int. So imo void is a really bad choice.


>
> is worth having a religious war over. (This is a motivating example in
> the SPECS paper, as you might have guessed.)


No it isn't because of using a special word go indicate nothing. That's
bad on both sides.

Till then
Friedrich

Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Simon Raahauge DeSantis wrote:
>
> In article <371B690D...@inka.de>, Friedrich Dominicus wrote:
> >Ketil Z Malde wrote:
> >> Apparently unlike most people, I remember learning C. The pointer
> >> stuff was really, really hard. Even in Pascal, pointers were
> >> difficult. IO was difficult.
> >
> >
> >Monads are easier to undertand and use as the printf family? Quite
> >interesting.
> >
> I for one find it pretty hard to memorize all the one-character codes printf
> and its friends use.

Oh I agree. But how do you print a left aligned string of 15 chars
length with Monads. The easy formatting is what makes printf so
flexible. Of course we can discuss about the approach. But I do think
formatted output is one of the most done tasks even today. So in that
sense printf is just fine. I would like to have such a printing facility
in Eiffel too.

Regards
Friedrich

Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Dana Harrington wrote:
>
> In article <371B690D...@inka.de>,
> Woah, this seems like an excellent non-example.
> Variables in Haskell example:
> d1 : first deque
> d2 : first deque
> Variables in Eiffel example:
> : first sequence
> s : second sequence
> l : s, or a copy of s
> count : length of `'?

Current


> new_count : length of `' after appending s?

replace `' with Current and you got it.

> old_count : length of `' before appending s?

Yes, so you can read it. Just you imagination is enought, my isn't large
enought for the haskell stuff.

>
> What am I appending to what? In the first example I think it is clear that
> d2 is being appended to d1.

On Eiffel everything works on objects so append is declared in class
List. And you have to call append this way.
d1: SEQUENCE[G];

d1.append(d2);

so where's the problem? I don't think this is more unreadable than what
Haskell does.


like is called an anchored declarations. That means if s is of class
LIST l is of type LIST too. If s is a QUEUE l is a QUEUE too.

> It's not clear at all (to me) what is happening
> in the second case, I assume ``extend (l.item)'' appends the value of the
> current item in sequence l onto the object whoses method is being called, and
> that ``l.forth'' moves the current index for l forward, but this is just a
> guess.

Very good guess. Indeed that's true. So you don't know Eiffel but you
can read it. I know a bit of Haskell and have problem doing that.


>Worse yet `l' stands for one sequence, while `' stands for the other
> (the object whose method we are in). You are not going to tell me that `'
> (blank, also known as `this' or `self') is a descriptive variable name are
> you? And this is not simply a poor choice of variable names, it is enforced
> by the language syntax.

This is one thing you have to know all Methods work on the current
object.
The first part is if s is the same as the Current.
|too_small d1 = Shallow ? (appendR= append to the right?

and that's not nearly all the whole stuff looks like:


instance Deque d => CatenableDeque (SimpleCatDeque d) where
(Shallow d1) ++ (Shallow d2)
| tooSmall d1 = Shallow (dappendL d1 d2)
| tooSmall d2 = Shallow (dappendR d1 d2)
| otherwise = Deep d1 empty d2

(Shallow d) ++ (Deep f m r)
| tooSmall d = Deep (dappendL d f) m r
| otherwise = Deep d (cons f m) r
(Deep f m r) ++ (Shallow d)
| tooSmall d = Deep f m (dappendR r d)
| otherwise = Deep f (snoc m r) d
(Deep f1 m1 r1) ++ (Deep f2 m2 r2) = Deep f1 (snoc m1 r1 ++ cons f2
m2) r2


One times it seems to be a shallow copy otherwise a deep copy of a
QUEUE, I migth be wrong. In Eiffel I wouild just write
d1: QUEUE[G] (G stands for any Type)
d2: QUEUE[G]

d1.copy(d2)
d1.deep_copy(d2) if that's what this does.

but what does tooSmall mean here?

Regards
Friedrich

>
> In addition to the fact that the two examples do different things I'd have to
> conclude myself that the Haskell example is much easier to read.

They don't. You hava tell me that on QUEe is appended to another so if
you have a QUEUE in EIFFEL the append would just be called.

q1: QUEUE;
q2: QUEUE;

q1.append(q2);

append is probably be redefined in an successor to SEQUENZE. But I think
this can be done in Haskell too.

> An
> additional problem with variables in IP is that they are variable, the value
> of the variable depends on at what point in the computation you observe it.
> In pure FP a variable, once set, is not changed, hence I don't have to keep
> track of what the variable means `right now', it is defined once and for all.
> Not to mention the ghastly habit some imperative programmers have of reusing
> the same variable name for different, unrelated values.

This is one weakness and one strength of side-effects. But nearly no
actual FP language did not provide a kind of variable in a IP sense.


>
> Perhaps you could search a little harder for a better example, to me `l' and
> `s' are as incomprehensible as variable names as `d1' and `d2'. Perhaps you
> were being ironic when you suggested this example?

The names are maybe not well choosen too. But you understand what was
going on (or you just guesss) I think you don't have any knowledge of
Eiffel but nearly all your guesses were quite right. The only thing you
didn't know was is that all Methods in Eiffel work on a Current objects.
But that's was the only thing I have to explain.

But I don't understand the


(Shallow d1) ++ (Shallow d2)

What does Shallow mean. ++ is known as concatenation.

Ketil Z Malde

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> No. Easier is IMO Python and the like.

I think Python is my preferred imperative language. :-)

>> Apparently unlike most people, I remember learning C. The pointer
>> stuff was really, really hard. Even in Pascal, pointers were
>> difficult. IO was difficult.

> Monads are easier to undertand and use as the printf family? Quite
> interesting.

I don't remember claiming that.

Monads are difficult to understand, and I think a lot of the blame is
due to the research community trying to explain them from a
mathematical vantage point. That may go down well with peer reviewed
journals, but not with us dilletantes and dabblers, I'm afraid.

>>>> Using an 'x' for a parameter is also pretty common practice, IMHO. I
>>>> just don't see any real benefit from changing that.


> so then you think that this is fine fp-programming to cited from PFDS
> (p 192 around mid)

> instance Deque d => CatenableDeque (SimpleCatDeque d) where
> (Shallow d1) ++ (Shallow d2)
> | tooSmall d1 = Shallow (dappendL d1 d2)
> | tooSmall d2 = Shallow (dappendR d1 d2)
> | otherwise = Deep d1 empty d2

Hmm...I fail to see any (x:xs) construction in there. What I see are
parameters named d1 and d2, which makes sense, since they are of (a)
type (derived from) Deque.

The function defines the ++ append operator on CatenableDeques, how it
works exactly depends on how the Shallow and Deep constructors work,
and the definition of dappendL/R and empty, I think. The names should
give us a few hints, though.

[Eiffel example snipped]

> much longer indeed but I think more readable with variable names which
> make sense.

Oh, like l and s? Really?

>> No no no. Any third grade student knows that x is the unknown. OTOH,
>> most people would interpret & as a conjunction, | as a "pipe" or
>> "bar", * as footnote or multiplication, and ** probably as
>> exponentiation.

> what about and, or, xor? why ** for exponeentiation this is a pointer of
> a pointer to .. (everyone knows ;-)

I was talking about what most non-computer literate persons would
think. At least in this country, the education system hasn't gotten
to teaching third grade students to interpret double asterisks as
pointer-to-pointer.

> > The only vaguely intuitive thing about C is using & for bitwise (and
> > && for logical) and, and | for bitwise (|| logical) or. And still,
> > the difference between logical and bitwise operators, and complexities
> > like signed/unsigned is the source for no end of confusion.

> What do you mean? bitwise and and logical operators are difficult to
> understand? Can't believe that.

I mean that C is hopless mess of obfuscated operators, and even those
that are somewhat intuitive have their problems.

> Oh my Debian system comes with FP packages but they are not installed by
> default as is e.g C or python or perl or awk ... another point why I
> think FP is not so accepted it the tool-box principle on Unix.

Yes, FP is the minority. So what, run dselect and install whatever
you desire. Debian is, what, five CDs chock full of software.

> cat file | tr " \t\r" "\n\n\n" | sort | uniq -c | tail +2

Actually, I thought Haskell would be just great for implementing this
kind of operators. Of course, the |s would have to be typed, and one
should preferably have a better method of manipulating multiple
streams than is supplied by the bourne shell.

Hashell anybody?

> Oh that's quite ok, but to follow what you have written gives you some
> feeling of what is going on. I'm not sure what is going on in a
> FP-script.

I can relate to that, yes.

>> The NHC group have a debugger for Haskell, I think.

> hugs hasn't AFAIK but hugs has a main advantage over NHC, or GHC. it is
> an interpreter.

You mean that it's "incremental", I think.

> but you can't do what you can do in Python. In Python i
> can define a functin very easily on the command line I can't do that in
> Hugs, what a mess.

See my previous complaint about this, and the retribution I got from,
I think, (one of) the author(s). Dejanews is your friend.

Ketil Z Malde

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> but what does tooSmall mean here?

> What does Shallow mean.

Good question, you'll have to look up the definitions, I think. Note
that identifiers starting with a capital are usually(?) type
constructors.

My guess is that the Deque implementation come in two flavors, Shallow
and Deep, and that there's some optimization wizardry going on to
determine which one is used.

tooSmall is apparently a function used to determine whether a Deque is
small enough to use the Shallow kind of Deque.

Lennart Augustsson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> Lennart Augustsson wrote:
>
> > > much longer indeed but I think more readable with variable names which
> > > make sense. You might come to another conclusion.

> > But the Haskell code does something rather different and much more
> > subtle. Comparing these is like saying that you don't like computing
> > prime numbers in Haskell, but prefer computing factorial in Eiffel.
>
> What does the Haskell code do. Isn't that a shallow copy form one Queue
> to antother. If you understand what the Haskell code does, you can tell
> me and I look for another solution. If I understand that code it's about
> a shallow or deep copy. But of course I might be completely wrong. So
> much about understanding FP.

I can't tell what the code does, because you have only given us
a snippet. You did not show us the definition of Deque, Shallow,
Deep, etc.
But this much I can tell you:
The code tells you how to make a deque with concatenation when
you only have one with no concatenation. And I bet the time
bound is constant or logarithmic.
So here are some differences with the code you gave:
This is deques, yours is sequences.
This is a persistent data structure, yours is updateable.
This is an operation with constant(?) time, yours is linear.

It doesn't have anything to do with shallow or deep copying.
These concepts are semantically identical in a language like
Haskell.

--

Lennart Augustsson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> But I don't understand the
> (Shallow d1) ++ (Shallow d2)
> What does Shallow mean. ++ is known as concatenation.

Your problem seems to be that you don't know the basics of Haskell.
Now I understand why you have problems understanding Haskell code.
You should look in some Haskell book again.
What you showed us defines (++) on a new data structure.
[At the time of the writing of that book (++) was an overloaded
operator.]
One of the constructors of this data structure is Shallow.
So Shallow doesn't mean anything, as such. But I bet the
name is carefully choosen.

Haskell is not a language you can understand by just looking
at some code, you actually have to know the syntax of the
language first. I guess that is true for most languages. :-)

Simon Helsen

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to Friedrich Dominicus
>Eiffel V 2.3 came with a quasi non-existent debugger. But now nearly all
>Eiffel compilers come with a debugger. Why, because a debugger let you
>look what's going on, in Eiffel you don't need an debugger for array
>overruns, memory management and type errors. So if we just would have
>such kind of bugs Eiffel didn't need one. so there must be a bunch of
>other areas where a debugger is handy. And I bet the same holds for FP
>languages.

no, it doesn't. Eiffel is still an imperative languages, which, by
definition, means that it relies on state and side-effect. For what do you
use a debugger? Well, I use it to check contents on certain variables and
trace their change. Now, if you don't have variables whose contents can be
corrupted by funy and unexpected behaviour of routines far away (or worse,
invisible to you, as is often the case in large software development), the
need for a debugger is not that high anymore. With pure functional
programming, you have this oh so famous property of referential
transparency, which means basicly that names and their bound expressions
are equivalent, well, than you debug by looking at the behaviour or
isolated expressions (hence, the importance of a read-eval system or
perhaps an interpreter). This is something you obviously can't do in an
imperative language since an isolated expression may behave different on
an infinite amount of different states. "Traditional debugging", i.e.
inspecting runtime state to see where and why it unexpectedly changed,
becomes "mostly" (I did not say, "always") superfluous.

Now, I have to admit that many functional languages have impure extensions
as well (e.g. ML or Scheme) and I use them too as they are sometimes just
easier or more elegant to use (e.g. I much prefer the imperative
implementation of the classical algorithm which calculate the strongly
connected components of graph) over the functional version. Also, although
monads are a cool idea and are sometimes easier to use than their
imperative solution, I still prefare to do I/O traditionally. When I use
imperative features in a call-by-value FL (like I sometimes do in ML), I
need a debugger. And it is true that it would be great if, say, SML/NJ
would come with a debugger again (like it used to do in the 0.93 release).
But you can still use Ocaml or Scheme, which both *have* a debugger.

As for a pure, call-by-need FL, having a debugger is not only "that"
necessary, it is non-trivial as well. Computation order is not easy
anymore (due to laziness) and my guess is that seeing something of its
computation trace will just more confuse than anything else. And this is
the whole point, in pure FL, the actual execution order of your program is
not relevant as long as the right values are produced for the right
consumers.

It would be helpful for this meaningless discussion if you'd first make
yourself familiar with FP before shouting around how great Pascal or Java
is. You're trying to be religious about it, but breaking open doors as
most people here are quite aware of both the merits and problems of FP.

Simon


Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Thanks for this polite answer. I'm really happy that you let me look
like an IP or OOP addicted ;-9

Ketil Z Malde wrote:
>
> Friedrich Dominicus <Friedrich...@inka.de> writes:
>
> > No. Easier is IMO Python and the like.
>

> I think Python is my preferred imperative language. :-)

So we have at least one thing in common;-))

>
> >> Apparently unlike most people, I remember learning C. The pointer
> >> stuff was really, really hard. Even in Pascal, pointers were
> >> difficult. IO was difficult.
>
> > Monads are easier to undertand and use as the printf family? Quite
> > interesting.
>

> I don't remember claiming that.

No you don't. But despite the not obious meaning of %s %d, %g and the
like it's a very powerful tool for formatted output. And IMO that's one
strength of IP or OOP the output facilities which work with
side-effects.

>
> Monads are difficult to understand, and I think a lot of the blame is
> due to the research community trying to explain them from a
> mathematical vantage point. That may go down well with peer reviewed
> journals, but not with us dilletantes and dabblers, I'm afraid.

I read some interesting report about this, don't remember the complete
title but is was talked about it some weeks ago.

>
> >>>> Using an 'x' for a parameter is also pretty common practice, IMHO. I
> >>>> just don't see any real benefit from changing that.
>
> > so then you think that this is fine fp-programming to cited from PFDS
> > (p 192 around mid)
>
> > instance Deque d => CatenableDeque (SimpleCatDeque d) where
> > (Shallow d1) ++ (Shallow d2)
> > | tooSmall d1 = Shallow (dappendL d1 d2)
> > | tooSmall d2 = Shallow (dappendR d1 d2)
> > | otherwise = Deep d1 empty d2
>

> Hmm...I fail to see any (x:xs) construction in there. What I see are
> parameters named d1 and d2, which makes sense, since they are of (a)
> type (derived from) Deque.
>
> The function defines the ++ append operator on CatenableDeques, how it
> works exactly depends on how the Shallow and Deep constructors work,
> and the definition of dappendL/R and empty, I think. The names should
> give us a few hints, though.
>
> [Eiffel example snipped]
>

> > much longer indeed but I think more readable with variable names which
> > make sense.
>

> Oh, like l and s? Really?

No that was silly from me. But some other has pointed out what this Code
mean and he was just guessing. So it seems not too hard to understand.
But of course l and s are not too verbose too but the come with an type
qualifier too
s: SEQUENZE[G]

and l is like s so it is an SEQUENZE too, I think for such a method
that' not too bad.


>
> >> No no no. Any third grade student knows that x is the unknown. OTOH,
> >> most people would interpret & as a conjunction, | as a "pipe" or
> >> "bar", * as footnote or multiplication, and ** probably as
> >> exponentiation.
>
> > what about and, or, xor? why ** for exponeentiation this is a pointer of
> > a pointer to .. (everyone knows ;-)
>

> I was talking about what most non-computer literate persons would
> think. At least in this country, the education system hasn't gotten
> to teaching third grade students to interpret double asterisks as
> pointer-to-pointer.

Read the ;-). I was kidding about what everyone knows. but nobody has an
idea that ** stand for exponentiation if you havn't learn, is it
FORTRAN?


>
> I mean that C is hopless mess of obfuscated operators, and even those
> that are somewhat intuitive have their problems.

I agree but didn't use Haskell && == and the like too?

>
> > Oh my Debian system comes with FP packages but they are not installed by
> > default as is e.g C or python or perl or awk ... another point why I
> > think FP is not so accepted it the tool-box principle on Unix.
>

> Yes, FP is the minority. So what, run dselect and install whatever
> you desire. Debian is, what, five CDs chock full of software.

No haskell AFAIK. So I download it from www.haskell.org and OCAML was
very much out ot date.


>
> > cat file | tr " \t\r" "\n\n\n" | sort | uniq -c | tail +2
>

> Actually, I thought Haskell would be just great for implementing this
> kind of operators. Of course, the |s would have to be typed, and one
> should preferably have a better method of manipulating multiple
> streams than is supplied by the bourne shell.

Show me that in Haskell and combine it with other elements which are
there just waiting to be used.

> > Oh that's quite ok, but to follow what you have written gives you some
> > feeling of what is going on. I'm not sure what is going on in a
> > FP-script.
>

> I can relate to that, yes.
>

> >> The NHC group have a debugger for Haskell, I think.
>
> > hugs hasn't AFAIK but hugs has a main advantage over NHC, or GHC. it is
> > an interpreter.
>

> You mean that it's "incremental", I think.

I thought more about interactivity you type s.th and you got an answer.
Which is what is not possible with an compiler.


>
> See my previous complaint about this, and the retribution I got from,
> I think, (one of) the author(s). Dejanews is your friend.

Oh, does the have changed that? Would be really nice.
Regards
Friedrich

Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
For the readers of this thread. I get a mail whith this message too and
I preferred to answer on that, because I have the feeling that Simon is
angry on me. So this might end up in flaming. Which is not what I want
it to be.

Regards
Friedrich

Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Lennart Augustsson wrote:
>
> Friedrich Dominicus <Friedrich...@inka.de> writes:
>
> > But I don't understand the
> > (Shallow d1) ++ (Shallow d2)
> > What does Shallow mean. ++ is known as concatenation.
> Your problem seems to be that you don't know the basics of Haskell.
> Now I understand why you have problems understanding Haskell code.

Such said, you mean Shallow is a type marker. Ok than I'm now able to
undertand a bit more. Fine, s.th learned again.

> You should look in some Haskell book again.

I'm on my way rereading "The Craft of Functional Programming" 2nd Ed. So
I'm sure I'll find this stuff. And I have had some more looks into the
Prelude to learn how Haskell should be programmed. And I have to say
while looking at Prelude I found some very nice stuff but other stuff is
just ugly.
eg. dispite the fact that they have used (x:xs) in everything which
handels lists all about list is really nice to read. Ok the fold-stuff
is somewhat heavy IMO, but I think it's perfectly ok if you know
Haskell.

>
> Haskell is not a language you can understand by just looking
> at some code, you actually have to know the syntax of the
> language first. I guess that is true for most languages. :-)

Dana harrington seems not to know the Eiffel stuff but she could read
the Eiffel and nearly got it rigth. That's is a point for Eiffel I
think.

I just have one more thing. I don't know if it was handeled here but we
wrote some different implementation of a function which counts all the
vowels in a String (not very exitcint), And I fouind the Haskell
solution pretty nice.

this was one:
#!/usr/local/bin/runhugs -h10k

f >.> g = g . f

main = interact main'

main' = lines >.> takeWhile (/= "exit")
>.> map (\str -> "The string " ++ str ++ " has " ++
show (countVowels str) ++ " vowels.\n")
>.> concat

-- putStr "Please give me a string (exit for end): "
countVowels = length . filter (`elem` "AEIOUaeiou")

I wasn't happy with that solution because the interactio was strange.
I'm quite sure that others have a better solution.

this another
#!/usr/local/bin/runhugs -h10k

module Main

where
import System

main :: IO ()
main = action

action = do putStr "Give me a string (exit for end): ";
str <- getLine;
if str == exit_string then
exitWith ExitSuccess
else do
putStrLn ("The given string " ++ str ++ " has "++ show (count_vowels
str) ++ " vowels"); action


exit_string :: String
exit_string = "exit"

vowels :: String
vowels = "AEIOUaeiou"

is_vowel :: Char -> Bool
is_vowel ch = elem ch vowels

count_vowels :: String -> Int
count_vowels = foldl' (\acc ch -> if is_vowel ch then 1+acc else acc) 0

this was Eiffel:
class VOWELS

creation make

feature
make is
local
counted_vowels: INTEGER;
str: STRING;
exc: EXCEPTIONS;
do
!!exc;
print ("Please give me a string (exit for end): ");
io.read_line;
str := io.last_string;
if str.is_equal(exit_string) then
exc.die(0);
else
counted_vowels := count_vowels(str)
print ("The given string "); print (str);
print (" has "); print(counted_vowels); print (" vowels%N")
make
end;
end; -- make


feature {NONE}

exit_string: STRING is "exit";

vowels : STRING is "AEIOUaeiou";

is_vowel(ch: CHARACTER): BOOLEAN is
do
if vowels.has(ch) then
Result := True;
end;
ensure
Result implies vowels.has(ch)
end;


count_vowels(str: STRING): INTEGER is
require
str_not_void: str /= Void;
local
i: INTEGER;
do
from i:=1;
invariant i >= 1 and then i <= str.count+1
variant str.count - i + 1
until i > str.count
loop
if is_vowel(str.item(i)) then
Result := Result + 1;
end -- if
i := i + 1;
end; -- from
end

end -- class VOWELS

IMO all solutions are nice done. But look how elegant and short the
functional sol can be. For the FPer here (are there some?) this is
surely more true as for me. But I bet you can read the Eiffel-solution
too.

One remark to the Haskell sol. The input/output takes me quite a while
to get it right and without some advice from this group it would be
worse. So what I would like to see more often is some code and
discussion about it. Is it good style what' can be improved etc. I hope
all have had so much fun with this simple and stupid program as I had.

Thanks to all which have pointed me out what to learn.


Till then
Friedrich

Ketil Z Malde

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> Read the ;-).

Oh. Humor. I see.

> I was kidding about what everyone knows. but nobody has an
> idea that ** stand for exponentiation if you havn't learn, is it
> FORTRAN?

What else would two multiplication symbols mean?

>> I mean that C is hopless mess of obfuscated operators, and even those
>> that are somewhat intuitive have their problems.

> I agree but didn't use Haskell && == and the like too?

Certainly not as pointer operators. Haskell has a tendency to use a
lot of quaint operators, but at least there's some indication of what
it does. E.g. -> and => indicate arrows, and should be somewhat
meaningful to anybody doing algebra, >>= and >> also indicate
direction, etc.

>> Actually, I thought Haskell would be just great for implementing

>> [Unix-like pipes]

> Show me that in Haskell and combine it with other elements which are
> there just waiting to be used.

Hmmm...take another look at the countWovels example you just posted,
and in particular the >.> operator.

>>> hugs hasn't AFAIK but hugs has a main advantage over NHC, or GHC. it is
>>> an interpreter.

>> You mean that it's "incremental", I think.

> I thought more about interactivity you type s.th and you got an answer.
> Which is what is not possible with an compiler.

Is too. There are compilers (Common Lisp ones, I think.) that let you
do exactly that. OTOH, the jvm is an interpreter, yet you can't have
it evaluate expression at the command line.

An incremental development system is one that lets you do this, the
issue is orthogonal to the compiler/interpreter issue - although in
practice, interpreters are often better at it.

Craig Dickson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Ketil Z Malde <ke...@ii.uib.no> wrote:

>Friedrich Dominicus <Friedrich...@inka.de> writes:
>
>> I was kidding about what everyone knows. but nobody has an
>> idea that ** stand for exponentiation if you havn't learn, is it
>> FORTRAN?
>

>What else would two multiplication symbols mean?

Double-dereferencing a second-order pointer? (Ha! Sorry. Couldn't resist.)

Craig

Dana Harrington

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
In article <371C80C8...@inka.de>,
Friedrich...@inka.de wrote:

> Dana harrington seems not to know the Eiffel stuff but she could read
> the Eiffel and nearly got it rigth. That's is a point for Eiffel I
> think.

Not entirely true, I know Sather, which is closely related to Eiffel, as well
as being familiar with many OO and imperative languages (which Eiffel is
fairly typical of). I was trying to play the part of someone unfamiliar with
either language. From this standpoint (admittedly quite difficult to put
myself in) the Haskell example seemed easier to decipher. To make any sort
of reasonable judgement about how intuitive these languages are one would
have to write equivalent code in both languages and give it to
non-programmers to decipher.

The OO and functional styles are quite different and coming from one the
other seems (at first) quite incomprehensible. Just as being a native
English speaker French seems quite awkward and incomprehensible to me. When
you've used Haskell-like languages as long as you've used Eiffel-like
languages then you might be able to make a more balanced judgement.

Dana Harrington

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
In article <371C0B29...@inka.de>,

Friedrich...@inka.de wrote:
> There are some places where some sort of traditional debugging
> > facility would be convenience, but this doesn't seem to be as crucial in FP
> > as in IP.
>
> That was said from OO too. And it's just not true. Of course yoiu
> needn't a debugger but then you help yourself with s.th like
> if condition then
> put_string("I'm here in bla all ok");
> or the like
>
> So how do you do that in FP?

This is a fundemental difference between declarative and imperative
languages. In imperative languages one goes through and executes a sequence
of commands, hence it is reasonable to ask what point I am in the list of
commands to execute and to note when I reach a particular point. On the
other hand in declarative programs one evaluates an expression, so one might
ask what a particular subexpression evaluates to. These two concepts are
roughly isomorphic. Hence in FP I would fire up an interpreter and feed it a
subexpression of the program, look at the output and see if it was what I
expected.

Friedrich Dominicus

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
> > Show me that in Haskell and combine it with other elements which are
> > there just waiting to be used.
>
> Hmmm...take another look at the countWovels example you just posted,
> and in particular the >.> operator.

As I said I didn't like that solution but maybe I have learn to like it
;-)

>
> >>> hugs hasn't AFAIK but hugs has a main advantage over NHC, or GHC. it is
> >>> an interpreter.
>
> >> You mean that it's "incremental", I think.
>
> > I thought more about interactivity you type s.th and you got an answer.
> > Which is what is not possible with an compiler.
>

> Is too. There are compilers (Common Lisp ones, I think.) that let you
> do exactly that.

Witout even typing s.th like CRTL+C for compile. Ups than I'm wrong.

> OTOH, the jvm is an interpreter, yet you can't have
> it evaluate expression at the command line.

The compile to java-byte-cod and this takes some time. So I agree it
should be possible in Java too as it is in with Haskell or OCAML.


>
> An incremental development system is one that lets you do this, the
> issue is orthogonal to the compiler/interpreter issue - although in
> practice, interpreters are often better at it.

I undertand, so a new point learned. This is quite good for one day ;-)

Regards
Friedrich

Craig Dickson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Friedrich Dominicus <Friedrich...@inka.de> wrote:

>> OTOH, the jvm is an interpreter, yet you can't have
>> it evaluate expression at the command line.
>The compile to java-byte-cod and this takes some time. So I agree it
>should be possible in Java too as it is in with Haskell or OCAML.

Erlang also compiles to byte-code, and allows interactive evaluation of
expressions.

Craig

Fergus Henderson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

>Simon Raahauge DeSantis wrote:


>>
>> Friedrich Dominicus wrote:
>> >Monads are easier to undertand and use as the printf family? Quite
>> >interesting.
>> >

>> I for one find it pretty hard to memorize all the one-character codes printf
>> and its friends use.

The fundamental problem with printf format codes is that they are not
extensible. They're OK for simple things but if you want to do anything
complex then you need to resort to some other technique.
For example, printf() doesn't provide any way of inserting thousands
separators or of formatting dates, times, currency, etc.

>Oh I agree. But how do you print a left aligned string of 15 chars
>length with Monads.

Easy:

foo string = print (left_align 15 string)

Here left_align is a function which takes a field width, a string,
and returns a new string which is the first string padded and/or
truncated to fit the field width. Defining left_align is very easy
(see below).

Now, that raises a question: if the string doesn't fit into 15 characters,
should it be truncated, or should the whole string be printed, even though
that will overflow the field width?

Depending on whether you want truncation, you can define left_align
as either

-- this version does not truncate
left_align n s = s ++ take (max 0 (n - length s)) (repeat ' ')

or

-- this version
left_align n s = take n s ++ take (max 0 (n - length s)) (repeat ' ')

With printf(), there is no such flexibility.

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

Fergus Henderson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Simon Helsen <hel...@informatik.uni-freiburg.de> writes:

>>Eiffel V 2.3 came with a quasi non-existent debugger. But now nearly all
>>Eiffel compilers come with a debugger. Why, because a debugger let you
>>look what's going on, in Eiffel you don't need an debugger for array
>>overruns, memory management and type errors. So if we just would have
>>such kind of bugs Eiffel didn't need one. so there must be a bunch of
>>other areas where a debugger is handy. And I bet the same holds for FP
>>languages.
>
>no, it doesn't.

I beg to differ. As I and others explained in quite some detail here on
this newsgroup quite recently, even in languages without side effects
a debugger is occaisionally very useful.

>With pure functional
>programming, you have this oh so famous property of referential
>transparency, which means basicly that names and their bound expressions
>are equivalent, well, than you debug by looking at the behaviour or
>isolated expressions (hence, the importance of a read-eval system or
>perhaps an interpreter).

That works OK for programs that don't manipulate complicated data
structures. But for programs that are manipulating complicated
data structures, typing in the function arguments by hand is not feasible,
and so using a debugger becomes much easier than using an interpreter.
Also, if you have a complicated function, it's often helpful to see
what arguments it is passing to the functions that it calls, so that
you can tell whether the bug is in the caller or the callee, thus
narrowing down your search.

>As for a pure, call-by-need FL, having a debugger is not only "that"
>necessary, it is non-trivial as well.

It's certainly non-trivial, but that doesn't mean that it's not worth
doing!

>Computation order is not easy
>anymore (due to laziness) and my guess is that seeing something of its
>computation trace will just more confuse than anything else. And this is
>the whole point, in pure FL, the actual execution order of your program is
>not relevant as long as the right values are produced for the right
>consumers.

Yes, in a lazy functional language what you normally want is a declarative
debugger -- one which shows you what values were computed, and lets you
traverse the computation tree, examining the arguments passed to subroutines
and the values returned from those subroutines -- rather than an
imperative-style trace-based debugger.

Lennart Augustsson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
f...@cs.mu.oz.au (Fergus Henderson) writes:

> Depending on whether you want truncation, you can define left_align
> as either

> ...
> or
> ...


> With printf(), there is no such flexibility.

Actually, in this case you are wrong. printf() does provide an
easy way to truncate or not. RTFM :-)

kin...@sp2n23-t.missouri.edu

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
[I've silently corrected all obvious typos for both sides here.]

In article <371C13D5...@inka.de>,


Friedrich Dominicus <Friedrich...@inka.de> wrote:
>>
>> Wow. That's a very revealing exhchange that doesn't reveal very
>> much. :-)
>

>Indeed but for a Pascal programmer this makes perfect sense ;-)

It make perfect sense for programmers to misunderstand basic facts about
the operators of a language? My memory of Pascal is faint, so I won't
claim to know what makes sense to Pascal programmers. But my point was
that compared to C's other warts, the (lack of) intuitiveness of the
symbols used for the dereference and address_of operators was pretty
small.

>> But getting back to the top level point, people are surprisingly good at
>> learning pretty arbitrary associations between labels and objects, but
>> they are surprisingly bad at learning (and using) arbitrary syntactic
>> constructions. The difference between "*" and "^" as operators might not
>> be worth fighting over, but the difference between:
>>
>> void (*set_new_handler(void (*) (void))) (void);
>>
>> which is often "improved" to:
>>
>> typedef void (*new_handler) (void);
>> new_handler set_new_handler(new_handler);
>
>why not (an Eiffelish language)
>set_new_handler({f}) : {f}

Then I'll assume that this is how you would declare this in Eiffel. Which
is fine, but SPECS was designed to be an alternative syntax for C++,
which, whether you like it or not, has a void type, and a weird
declaration syntax to boot.

>a function that takes a function as argument which doesn't have a
>return value and doesn't have any parameter and returns a function
>which doesn't have a return value and no parameter.

>> and the SPECS version:
>>
>> func set_new_handler : (^(void -> void) -> ^(void -> void));
>>
>> which might also be written as:
>>
>> type new_handler : ^(void -> void);
>> func set_new_handler : (new_handler -> new_handler);
>

>I don't think that it was a good idea to tell something which stands
>for nothing (void) get's an extra name.

OK, but that's presumably a problem you have with the C++ type system.
The point here was that the C++ declaration syntax was difficult at best,
AND that this was strictly a syntactic issue, since the SPECS paper
defines a syntax that is far more readable and that can be used to develop
real C++ programs. I'd be completely shocked if you thought the C++
version was better in any way.

>So I do not think that
>
>void bla(void) (C) is as readable and understandable as
>bla (Eiffel)

Not surprising on its face, although I'll point out that the re-design of
C (and C++) explicitly introduced "void" to overcome other difficulties.

>If I wouldn't know C I would say bla is a function taking a Parameter


>of type void and returning an Parameter of type void.

I guess we differ on this. If *I* didn't know C, I would wonder what the
heck "void bla(void)" was supposed to mean in the first place. And I
wouldn't assume the bareword "bla" in Eiffel was function declaration
syntax. Which is the nice thing about the SPECS version I'll insert again
here:

type new_handler : ^(void -> void);
func set_new_handler : (new_handler -> new_handler);

I've got two things; the first of these probably defines the type
of something called new_handler. The only things I need to
know are that -> is a type constructor for functions, "void"
is some type (albeit a mysterious one), and ^ is syntax for
"pointer to". Then I can read this out (in English) as:

"The type of new_handler is pointer to a function from void
to void."

Then the next thing says that there is a func(tion) set_new_handler whose
type is "function from new_handler to new_handler".

>That is desparately wrong here, but how should one know if
>int blu (int) means: blus is a function which take an int Paramter and
>returns an int. So imo void is a really bad choice.

I'm not sure I understand what you're trying to say. It sounds like you
have a problem with the whole "void" type concept (the type for things
that aren't really there?). And that should make you a functional
programming fan, since I think these languages are void of "void". :-)

>> is worth having a religious war over. (This is a motivating example in
>> the SPECS paper, as you might have guessed.)
>
>No it isn't because of using a special word go indicate nothing. That's
>bad on both sides.

I have no idea what you're talking about here, so I'll just restate my
opinion. If you're going to write C++ in the first place, the least you
can do is give it a comprehensible syntax. SPECS is one such syntax that
we know is adequate for the language, and almost certainly easier for
people to understand.

jking

Fergus Henderson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
c...@best.com (Craig Dickson) writes:

Mercury compiles to machine code, via C, and yet the latest development
version of the Mercury implementation allows interactive evaluation:
we compile the code on-the-fly and the dynamically link it into the
running executable. Yes, this does take some time. But it's still
quite usable.

Jeffrey Mark Siskind

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to Fergus Henderson
> Mercury compiles to machine code, via C, and yet the latest development
> version of the Mercury implementation allows interactive evaluation:
> we compile the code on-the-fly and the dynamically link it into the
> running executable. Yes, this does take some time. But it's still
> quite usable.

A lot of interactive compilers do this sort of thing: Mercury, KCL, Gambit-C,
and perhaps others as well. I've always wanted to do this also. But it appears
to require some black magic this isn't well documented. Can you give a quick
synopsis of how to do this (in as portable fashion as possible, at least among
flavours of Unix)?

Jeff (http://www.neci.nj.nec.com/homepages/qobi)

Fergus Henderson

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Lennart Augustsson <augu...@cs.chalmers.se> writes:

>f...@cs.mu.oz.au (Fergus Henderson) writes:
>
>> Depending on whether you want truncation, you can define left_align
>> as either
>> ...
>> or
>> ...
>> With printf(), there is no such flexibility.
>
>Actually, in this case you are wrong. printf() does provide an
>easy way to truncate or not. RTFM :-)

Sorry, you're absolutely right, you can do

printf("%15s", string)
or
printf("%15.15s", string)

I've even written code like that before, so I don't know why I forgot it.
But the general point about printf() not being extensible is still true.

James Jones

unread,
Apr 20, 1999, 3:00:00 AM4/20/99
to
Hmmm. Unix programs hooked together via pipes are very much in
the spirit of lazy evaluation, and work just like composed functions
of type [Char] -> [Char], don't they? I would think that would be a
point in favor of FP and lazy evaluation for people familiar with Unix.

James Jones

Opinions herein are those of the author, and not necessarily those of
any organization.

Friedrich Dominicus

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
Fergus Henderson wrote:
>
> Friedrich Dominicus <Friedrich...@inka.de> writes:
>
> >Simon Raahauge DeSantis wrote:
> >>
> >> Friedrich Dominicus wrote:
> >> >Monads are easier to undertand and use as the printf family? Quite
> >> >interesting.
> >> >
> >> I for one find it pretty hard to memorize all the one-character codes printf
> >> and its friends use.
>
> The fundamental problem with printf format codes is that they are not
> extensible. They're OK for simple things but if you want to do anything
> complex then you need to resort to some other technique.
> For example, printf() doesn't provide any way of inserting thousands
> separators or of formatting dates, times, currency, etc.
>
> >Oh I agree. But how do you print a left aligned string of 15 chars
> >length with Monads.


>
> Easy:
>
> foo string = print (left_align 15 string)

this is quite a nice solution and can be read easily, and hey even I can
understand it ;-)

>
> Here left_align is a function which takes a field width, a string,
> and returns a new string which is the first string padded and/or
> truncated to fit the field width. Defining left_align is very easy
> (see below).
>
> Now, that raises a question: if the string doesn't fit into 15 characters,
> should it be truncated, or should the whole string be printed, even though
> that will overflow the field width?
>

> Depending on whether you want truncation, you can define left_align
> as either
>

> -- this version does not truncate
> left_align n s = s ++ take (max 0 (n - length s)) (repeat ' ')
>
> or
>
> -- this version
> left_align n s = take n s ++ take (max 0 (n - length s)) (repeat ' ')
>

> With printf(), there is no such flexibility.

This examples are nice and the fit for a string very nicely. So I ask
has anybody written s.th simular to the Perl templates for printing.
with was formulars can be really nice formatted for an ascii output. But
how do you do formatted output from Records, do you make it an successor
from (I think it have to be)Show and redefine the output. How would you
do that in Haskell?
#!/usr/local/bin/python

import string, sys

stdin = sys.stdin
input=open("/etc/passwd", "r")

formatted_output="""
Login-Name: %-20s
UID : %4s, GID : %4s
Name : %20s
Home : %20s
Shell : %20s
"""


while 1:
line=input.readline()
if not line:
break
(login_name, password, uid, gid, real_name, home_dir, shell)=\
string.split(line, ":")
print formatted_output % (login_name,
uid,
gid, real_name,
home_dir, shell)
print "Bitte Enter drücken: ";
stdin.read(1)
input.close

I think it is very easy to write and I will do it on my own. It is just
thought as an example of how nice such stuff can be done in Python.

Regards
Friedrich

Friedrich Dominicus

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
>
> >> But getting back to the top level point, people are surprisingly good at
> >> learning pretty arbitrary associations between labels and objects, but
> >> they are surprisingly bad at learning (and using) arbitrary syntactic
> >> constructions. The difference between "*" and "^" as operators might not
> >> be worth fighting over, but the difference between:
> >>
> >> void (*set_new_handler(void (*) (void))) (void);
> >>
> >> which is often "improved" to:
> >>
> >> typedef void (*new_handler) (void);
> >> new_handler set_new_handler(new_handler);
> >
> >why not (an Eiffelish language)
> >set_new_handler({f}) : {f}
>
> Then I'll assume that this is how you would declare this in Eiffel.

No you can't declare it this way. In Eiffel everything have to be an
object so if you have a function you have to write a class which
encapsultes this. I say an Eiffel-lish language because the {F} stand
for: take it as a function if it is a class you would write
set_new_handler(f : F): like f



> Which
> is fine, but SPECS was designed to be an alternative syntax for C++,
> which, whether you like it or not, has a void type, and a weird
> declaration syntax to boot.

Sorry, I don't critizize SPECS.

>
> OK, but that's presumably a problem you have with the C++ type system.

No I havn't it was my opinion that have void standing for nothing is a
bad idea

> The point here was that the C++ declaration syntax was difficult at best,
> AND that this was strictly a syntactic issue, since the SPECS paper
> defines a syntax that is far more readable and that can be used to develop
> real C++ programs. I'd be completely shocked if you thought the C++
> version was better in any way.

I never have said I just mentioned that the keyword maked is even more
difficult to understand. So I don't recommend the C-style.

>
> >So I do not think that
> >
> >void bla(void) (C) is as readable and understandable as
> >bla (Eiffel)
>
> Not surprising on its face, although I'll point out that the re-design of
> C (and C++) explicitly introduced "void" to overcome other difficulties.
>
> >If I wouldn't know C I would say bla is a function taking a Parameter
> >of type void and returning an Parameter of type void.

Ok I try it the other way round. I now thinkg that one knows the
following.
int bla(int) stand for a function taking an int returning an int the
logigal implication on
void bla(void) is than bla is a function which take an void and returns
an void. Which is deadly wrong. So s.th which look very simular has two
completely different meanings. That's what I critizice.


>
> I guess we differ on this. If *I* didn't know C, I would wonder what the
> heck "void bla(void)" was supposed to mean in the first place. And I
> wouldn't assume the bareword "bla" in Eiffel was function declaration
> syntax. Which is the nice thing about the SPECS version I'll insert again
> here:
>
> type new_handler : ^(void -> void);
> func set_new_handler : (new_handler -> new_handler);
>
> I've got two things; the first of these probably defines the type
> of something called new_handler. The only things I need to
> know are that -> is a type constructor for functions, "void"
> is some type (albeit a mysterious one), and ^ is syntax for
> "pointer to". Then I can read this out (in English) as:
>
> "The type of new_handler is pointer to a function from void
> to void."

Yes indeed I would understand it this way. And I have to read the
article because I ask some other questions. like how can I declare that
a function take an argument
type new_handler ^((int) -> void -> void) ? or how can I declare that.
We can take the signal function as example which prototyp is written as:
void (*signal(int signum, void (*handler)(int)))(int);

ups we shouldn't we're in c.l.f this should be theme in c.l.c or c.l.c++

>
> I'm not sure I understand what you're trying to say. It sounds like you
> have a problem with the whole "void" type concept (the type for things
> that aren't really there?). And that should make you a functional
> programming fan, since I think these languages are void of "void". :-)


I'm a FP fan and I hope I state my criticism more clearly above. And I
think the idea the type declarations are much better in FP than they are
in C. I do not have a problem whic things wich are not there but to name
them as if there is something ;-)

>
> >> is worth having a religious war over. (This is a motivating example in
> >> the SPECS paper, as you might have guessed.)
> >
> >No it isn't because of using a special word go indicate nothing. That's
> >bad on both sides.

>
> I have no idea what you're talking about here, so I'll just restate my
> opinion. If you're going to write C++ in the first place, the least you
> can do is give it a comprehensible syntax.

for what does (void -> void) stands here. If I read it your way void is
a type of s.th simular but void stands for what here. I can read void
stands for nothing is stand for s.th which is of type void and what is
void (nothing) so
that woiuld be
^( -> )


>SPECS is one such syntax that
> we know is adequate for the language, and almost certainly easier for
> people to understand.

As I said above, I have to read the paper and I'll do. But this can't
be a discussuoin in c.l.f.

So either we switch to mail or c.l.c

Regards
Friedrich
>
> jking

Saba

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
I think an important issue ("out there" in the real world, so to speak)
is not just the productivity (how much a language supports rapid
development, etc...) but it is maintainability. This is where the so-called
software crisis still is. Declarative languages, because of their cleaner
semantics, have a clear advantage here, and that is their only promise,
in my view.

Maintaining a large system that is coded in any procedural language
(including hybrid procedural/OO langs.) is a nightmare. That is where
FP is superior.

No?


Paul Hudak wrote in message <3711F31A...@yale.edu>...
>> To me, it seems resonable that you need to think more
>> for every line of code, if you have to write a lesser amount
>> of code, so there would not be any difference in how fast
>> the programs are written. Am I right?
>
>There was at least one study done many years ago that showed that on
>large software projects the amount of code developed per day was
>independent of the language used, and that the number was surprisingly
>small, like around 7 LOC/day. In other words, whether you program in
>assembly language, Cobol, or C, a programmer will write on average 7
>lines of code per day over the long haul. (I did not include Haskell or
>ML in this list because the study predated them, but I'm pretty sure it
>included the Algol languages such as C and Pascal, so one might try to
>extrapolate from there. Of course, there is also the issue of defining
>what a LOC is...)
>
> -Paul
>
>--
>Professor Paul Hudak
>Dept of Computer Science Office: (203) 432-4715
>Yale University FAX: (203) 432-0593
>P.O. Box 208285 email: paul....@yale.edu
>New Haven, CT 06520-8285 WWW: http://www.cs.yale.edu/~hudak.html

pat...@c837917-a.potlnd1.or.home.com

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
Saba (sa...@wincom.net) wrote:

: Maintaining a large system that is coded in any procedural language


: (including hybrid procedural/OO langs.) is a nightmare. That is where
: FP is superior.

: No?

Maintenance of large imperative object oriented systems is a well
known (but apparently little practiced) problem. I would recommend
reading Robert C. Martin's book and Kent Beck's couple of books for
learning about this.

I have never developed any really large functional applications but
have developed some relatively complex GUI toys. The principles are
kind of the same and result in similar complexity: use higher order
functions (as you would use first class objects) that subscribe to
well documented, abstract contracts. And hide unnecessary state
descriptions (i.e. encapsulation).

Are there any good tricks of the trade for FP as there are for OO,
e.g. the _Design Patterns_ book? Some of the design patterns apply to
FP, but I have not done an exhaustive evaluation.

--
Patrick D. Logan mailto:patric...@home.com

kin...@sp2n23-t.missouri.edu

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
Guess I wasn't being very clear here...

My original point was that people were bashing C for having weird,
unintuitive operators like * and &, but that a far larger problem was that
type declarations in C(++) are far from transparent, although there is no
semantic reason they could not be much clearer. At least up to a point;
Friederich Dominicus does point out that there is something strange at
best about the void type, and expressing functions that "take" an argument
of this type.

But one more point:

In article <371D5AB9...@inka.de>,
Friedrich Dominicus <Friedrich...@inka.de> wrote:
>

[*big* snip]

>Ok I try it the other way round. I now think that one knows the


>following.
>
>int bla(int) stand for a function taking an int returning an int

Yup, although syntax like:

bla :: Int -> Int

would make this much clearer.

>the logigal implication on void bla(void) is that bla is a function which
>take a void and returns a void.

In other words, you could (and SPECS does) write:

bla :: Void -> Void

>Which is deadly wrong.

Well, certainly confusing as hell when you think of it from a functional
language perspective, since "bla" doesn't seem to be much of a function.
:-)

Obviously, "bla" can only be interesting if it has side effects, and
probably side effects of the kind that are most likely to annoy somebody
interested in functional programming at all.

>So something which looks very similar has two completely different
>meanings. That's what I criticize.

OK, and, a reasonalbe point to make even if functions like "blah"
themselves don't bother you.

>I'm a FP fan and I hope I state my criticism more clearly above. And I
>think the idea the type declarations are much better in FP than they are
>in C. I do not have a problem whic things wich are not there but to name
>them as if there is something ;-)

Oh, Lord, yes, type declarations are much better in FP than in current C.
And I do not doubt for a minute that this part of the attraction of FP.
But part of this attraction, it must be noted, is due to the fact that C
declarations are so, um, "interesting", even though you *could* (and SPECS
did) replace them with something far nicer looking.

jking


Carl R. Witty

unread,
Apr 21, 1999, 3:00:00 AM4/21/99
to
Friedrich Dominicus <Friedrich...@inka.de> writes:

> Ok I try it the other way round. I now thinkg that one knows the
> following.
> int bla(int) stand for a function taking an int returning an int the
> logigal implication on
> void bla(void) is than bla is a function which take an void and returns
> an void. Which is deadly wrong. So s.th which look very simular has two
> completely different meanings. That's what I critizice.

The syntax
void bla(void);
is not the recommended C++ declaration style. Better is:
void bla();
So you look at that and see "bla is a function which takes no
arguments and returns void". If you treat void as a type which
contains a single value, then this is fairly similar in meaning to the
Haskell syntax:
bla :: IO ()
which says that "bla is a function (with side-effects) which takes no
arguments and returns ()" (where "()" is the Haskell name for the type
with a single value).

Both C++ and Haskell compilers will optimize so that you don't
actually have to pass values of type void/() around (although this
optimization is so automatic as to be invisible in a C++ compiler, and
it's a fair bit of work in a Haskell compiler).

Carl Witty

Ketil Z Malde

unread,
Apr 22, 1999, 3:00:00 AM4/22/99
to
kin...@sp2n23-t.missouri.edu () writes:

> Guess I wasn't being very clear here...

> My original point was that people were bashing C for having weird,
> unintuitive operators like * and &,

Okay, that might have been me. This was in a response to the
criticism of the Haskell et al. (x:xs) syntax for lists, and as a
friendly reminder that learning C is far from easy.

It was about beginner-friendliness, I feel your criticism below is
aimed at the more experienced programmer.

> but that a far larger problem was that type declarations in C(++)
> are far from transparent, although there is no semantic reason they
> could not be much clearer.

> Friederich Dominicus does point out that there is something strange at


> best about the void type, and expressing functions that "take" an argument
> of this type.

Void can mean two things, used by itself, it fills the same function
as the () singleton type/value in Haskell. Functions like

void blah(void);

are simply C's way of expressing

blah :: () -> ()

I would be inclined to disagree that

blah()

(mostly for historical reasons) or in particular

blah :: ->

would be any improvement.

Of course, *pointers* to void are a precambrian form of inheritance in
C, much like, I think, the root of inheritance hierarchies in
languages like Smalltalk or Java. Obviously a lot less refined,
though.

>> So something which looks very similar has two completely different
>> meanings. That's what I criticize.

> OK, and, a reasonalbe point to make even if functions like "blah"
> themselves don't bother you.

>> I do not have a problem whic things wich are not there but to name


>> them as if there is something ;-)

I think a void type with a singleton value makes sense. *shrug*

Rainer Joswig

unread,
Apr 22, 1999, 3:00:00 AM4/22/99
to

> while 1:
> line=input.readline()
> if not line:
> break
> (login_name, password, uid, gid, real_name, home_dir, shell)=\
> string.split(line, ":")
> print formatted_output % (login_name,
> uid,
> gid, real_name,
> home_dir, shell)
> print "Bitte Enter drücken: ";
> stdin.read(1)
> input.close
>
> I think it is very easy to write and I will do it on my own. It is just
> thought as an example of how nice such stuff can be done in Python.
>
> Regards
> Friedrich

Given that you have defined a format string and a split
routine, the Common Lisp version looks like:


(with-open-file (stream "/etc/passwd")
(loop for (login-name nil uid gid real-name home-dir shell)
= (split-string (read-line stream nil nil) :item #\:)
while login-name
do (format t
*formatted-output*
login-name uid gid real-name home-dir shell)))

Rainer Joswig

unread,
Apr 22, 1999, 3:00:00 AM4/22/99
to

> > >>> hugs hasn't AFAIK but hugs has a main advantage over NHC, or GHC. it is
> > >>> an interpreter.
> >
> > >> You mean that it's "incremental", I think.
> >
> > > I thought more about interactivity you type s.th and you got an answer.
> > > Which is what is not possible with an compiler.
> >

> > Is too. There are compilers (Common Lisp ones, I think.) that let you
> > do exactly that.
> Witout even typing s.th like CRTL+C for compile. Ups than I'm wrong.

Some Common Lisp implementations are compiling everything on the
fly to native machine code:

Example: Typing to a prompt in Macintosh Common Lisp for PowerPC
(using a local function definition via FLET):

? (flet ((3adder (number)
(+ number 3)))
(disassemble #'3adder)
(3adder 4))

The output is:

(TWNEI NARGS 4)
(MFLR LOC-PC)
(BLA .SPSAVECONTEXTVSP)
(VPUSH ARG_Z)
(LWZ NARGS 331 RNIL)
(TWGTI NARGS 0)
(LI ARG_Y '3)
(LWZ ARG_Z 0 VSP)
(BLA .SPRESTORECONTEXT)
(MTLR LOC-PC)
(BA .SPBUILTIN-PLUS)
7

It is loading more messages.
0 new messages