Question about error message

Paulo Sequeira otro_paulo@hotmail.com
Tue, 27 Aug 2002 00:05:53 -0500


Seth,

I'm really bad in optimization issues. To be honest, I have almost no
serious experience using Haskell, so I have never faced the task to build an
application for which it was crucial optimization either in space or time.

On the other hand, I have assimilated the idea that you can't put Haskell
programs compete with analogous versions in C++ in space/time usage. I think
that if you try to convince someone that programming in Haskell is better
than doing it in C++ based these metrics, you lost before starting.
Haskell's beauty is somewhere else.

Try to find mundane problems in which Haskell can do better than others
solving them. For example, I participated in some parts of the design and
implementation an n-tier system using, among other things, Visual Basic.
When we came to write the code for the data access components in the data
services tier, we discovered that much of the work was repetitive and
boring: just look at the stored procs' signatures and map them into VB
procedures.

It was clear that what we needed was an utility that could process some
database metadata and produced VB code. I you were considering implementing
it yourself, which language would you choose? (Certainly, I wouldn't pick VB
;) )

Good luck.

Paulo.

----- Original Message -----
From: Seth Kurtzberg <seth@cql.com>
To: Paulo Sequeira <otro_paulo@hotmail.com>
Sent: Monday, August 26, 2002 9:32 AM
Subject: Re: Question about error message


> Paulo,
>
> Yes you are correct.  I actually found another way to do it which is
similar
> but not quite as good; I'll paste it in below.  The program doesn't do
> anything useful; I was trying to use it to compare execution times for a
> compiled Haskell program to a compiled C program.  By the time I stopped
> optimizing it it runs in about 1.5 seconds, so it isn't of much use as a
> performance test, but I learned a lot coding it.  The C++ version is
running
> about 30 times faster, but I suspect that a lot of that difference is
startup
> time and I'll need longer running times to make a valid comparison.  Also,
> the actual printing of the results, which is really irrelevant (to the
> situation where I'm trying to convince one of my clients to use Haskell),
> probably takes a lot of the running time.  I'm going to change this to
just
> dump the binary results to a file and see what that does to the running
> times.
>
> If you happen to see any obvious way to get this to run faster, let me
know.
>
> Thanks again for your time and efforts.
>
> import System
> import IO
> import Data.List
>
> solutionString (a,b,c,d,e,f,g,h,i,j) =
>     concat["sum=", (show (a+d+e)),
>            ", values= ",
>            (show a), ", ",
>            (show d), ", ",
>            (show e), ", ",
>            (show b), ", ",
>            (show f), ", ",
>            (show g), ", ",
>            (show c), ", ",
>            (show h), ", ",
>            (show i), ", ",
>            (show j), "\n" ]
>
> validCorner x y z =
>     cornerSum >= 6 && cornerSum <= 48 && ((cornerSum `mod` 6) == 0)
>     where cornerSum = (x+y+z)*2
>
> solutionList =
>     [(a, b, c, d, e, f, g, h, i, j) |
>      a <- [0..9],
>      b <- [0..9], b /= a,
>      c <- [0..9], c /= b, c /= a,
>      (validCorner a b c),
>      d <- [0..9], d /= a, d /= b, d /= c,
>      e <- [0..9], e < d, e /= c, e /= b, e /= a,
>      f <- [0..9], f /= e, f /= d, f /= c, f /= b, f /= a,
>      g <- [0..9], f < g, g /= e, g /= d, g /= c, g /= b, g /= a,
>      h <- [0..9], h /= g, h /= f, h /= e, h /= d, h /= c, h /= b, h /= a,
>      i <- [0..9], h < i, i /= g, i /= f, i /= e, i /= d, i /= c, i /= b, i
/=
> a,
>      j <- [0..9], i < j, j /= h, j /= g, j /= f, j /= e, j /= d, j /= c, j
/=
> b, j /= a,
>      (a+d+e+b) == (a+f+g+c),
>      (a+d+e+b) == (b+c+h+i+j) ]
>
> main =
>     (putStr . concat . map solutionString) solutionList
>
>
> On Sunday 25 August 2002 22:38, you wrote:
> > Seth,
> >
> > At last, I can have some time to view your question with care. I'm
replying
> > to you, and not the list, because I'm not sure to be understanding
exactly
> > what is it that you need; this way, we will avoid introducing some noise
> > into the list by posting "Is this what you asked?" mails. Later, we can
> > post a message that summarizes the dialogue and the answer.
> >
> > ----- Original Message -----
> > From: Seth Kurtzberg <seth@cql.com>
> > Sent: Tuesday, August 20, 2002 1:45 AM
> >
> > > ...
> > >
> > > I was trying to follow the basic pattern for coding a recursive
function,
> > > where you give a pattern for, say, f (x:[]), and you then give a
pattern
> >
> > for
> >
> > > (x:xs) where xs is then used as the argument for a recursive call (as
in
> > > "f xs").
> >
> > I'm not sure if this is intentional, but there is a case missing here: f
[]
> > In case you want to, you can rewrite displaySolutions to cope whith it
this
> > way:
> >
> >     displaySolutions [] = return ()    -- the "do nothing"
> >     displaySolutions (x:xs) = displayOneSolution x >> displaySolutions
xs
> >
> > or
> >
> >     displaySolutions [] = return ()    -- the "do nothing"
> >     displaySolutions (x:xs) = do displayOneSolution x; displaySolutions
xs
> >
> > > The following is how I now understand it; let me know if this is
> >
> > fundamentally
> >
> > > incorrect (and thanks for taking the time to read it).
> > >
> > > ...
> > >
> > > The problem is that the examples I was looking at use something like
> > > (some calculation with x) * f xs, or + f xs, or some variation where
"f
> > > xs" is
> >
> > used
> >
> > > within a single expression.
> >
> > This pattern looks like the one foldr captures. Indeed, you can rewrite
> > displaySolutions in this way.
> >
> >     displaySolutions xs = foldr ((>>) . displayOneSolution) (return ())
xs
> >
> > > I see, now, that you need the combinator if
> > > there is more than one expression, and that this is not related to
> > > whether the expression uses monads.
> > >
> > > So, is there a way to code this without resorting to the combinator?
I
> >
> > could
> >
> > > have "displayOneSolution" return "displaySolutions", and then do this
(I
> > > think):
> > >
> > > (displayOneSolution x) xs
> > >
> > > but that would just move the combinator out of displaySolutions and
into
> > > displayOneSolution.  Or am I looking for something that doesn't exist;
> >
> > that
> >
> > > is, the combinator is the best way to code this pattern?
> >
> > What I understand is that you have a list of solutions you want to
display,
> > one after another. For this, you should traverse the list, one element
> > after another, applying the displayOneSolution function in order to
build
> > an action that do precisely what the name implies.
> >
> > This can be viewed as having a sequence of actions (display solutions)
to
> > be performed, one after another. Declaratively, you can understand this
as
> > having a list of actions that you combine using a sequencing operator.
The
> > end result is that you have a compound action that is the sequencing of
the
> > simpler actions of displaing a solution.
> >
> > If I'm correct in all this, then the answer is that you cannot avoid the
> > use of the combinator: it is the part that allows you to sequence the
> > actions. Anyway, it seems that displaySolutions has a pattern that is
> > captured by sequence_; so, if you ask me, I would code it this way:
> >
> >     displaySolutions xs = sequence_ (map displayOneSolution xs)
> >
> > which can be transformed also into
> >
> >     displaySolutions = sequence_ . (map displayOneSolution)
> >
> > Well, we didn't have to use the combinator after all (it is used in
> > sequence_).
> >
> > I tend to choose the second form, although I'm not sure if it is clear
and
> > easily understandable. What do you think?
> >
> > Paulo.
>
> --
> -----------------------------------
> Seth Kurtzberg
> M. I. S. Corp.
> 1-480-661-1849
>