RE: no continuations

2004-01-01 Thread oleg

Kevin S. Millikin wrote:
> It sure looks like the example contradicts the assertion, but I happen 
> to know that there is a set! (or some other assignment) in the macro 
> expansion of define.  I'm just using call/cc to get at that, rather 
> than getting at the one in the expansion of letrec.

In Scheme 'define' is normally a primitive because in most of the
systems a top-level 'define' must create a top-level variable binding,
and there is no other R5RS form that can do that. Still, you're right
about set!. R5RS says:

"5.2.1. Top level definitions
At the top level of a program, a definition
 (define variable  expression)
has essentially the same effect as the assignment expression
 (set! variable  expression)
if variable is bound. If variable is not bound, however, then the
definition will bind variable to a new location before performing the
assignment...  Some implementations of Scheme use an initial
environment in which all possible variables are bound to locations,
most of which contain undefined values. Top level definitions in such
an implementation are truly equivalent to assignments."

Similarly, R5RS obligates any Scheme implementation to resort to
assignments when processing a letrec form. An implementation may not
use a (polyvariadic) Y to implement letrec, unless the implementation
can prove that the difference is unobservable for the form in
question. Incidentally, one can easily observe how letrec is
implemented. For example, in Ocaml, the observation says that "let rec"
is implemented via an assignment.

So, in the examples mentioned earlier, call/cc simply pries open the
assignment that was already present in letrec or define. Alone,
call/cc cannot emulate assignments. There was a message exactly on the
same topic "call/cc is insufficient to emulate set!"  posted on
comp.lang.scheme two years ago:

http://google.com/groups?selm=200103010316.TAA30239%40adric.cs.nps.navy.mil

Threads 
http://google.com/groups?threadm=200102212311.PAA76922%40adric.cs.nps.navy.mil
http://google.com/groups?threadm=200102212321.PAA76933%40adric.cs.nps.navy.mil
http://google.com/groups?threadm=200102220358.TAA77339%40adric.cs.nps.navy.mil

might also be useful.

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: foldr

2004-01-01 Thread Garner, Robin
Title: RE: foldr





It's not too difficult to do: think 'fold map' and put it in the form that foldr needs.


cheers 


-Original Message-
From: James Ealing [mailto:[EMAIL PROTECTED]]
Sent: Friday, 02 January, 2004 1:54 PM
To: [EMAIL PROTECTED]
Subject: foldr



Hi all,


If I have a function:


it f [a0, a1, a2, ...] = [a0, f a1, f (f a2), ]


Is there any way of expressing


it f


as an instance of foldr?


Many thanks,


Jim



Yahoo! Messenger - Communicate instantly..."Ping" 
your friends today! Download Messenger Now 
http://uk.messenger.yahoo.com/download/index.html
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe



___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


foldr

2004-01-01 Thread James Ealing
Hi all,

If I have a function:

it f [a0, a1, a2, ...] = [a0, f a1, f (f a2), ...]

Is there any way of expressing

it f

as an instance of foldr?

Many thanks,

Jim


Yahoo! Messenger - Communicate instantly..."Ping" 
your friends today! Download Messenger Now 
http://uk.messenger.yahoo.com/download/index.html
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Module creation

2004-01-01 Thread Glynn Clements

J & M van Berchem wrote:

>   New to Haskell, I got a version, through Fink, for my Mac OS X.  I like
> the interpreter very much, but I do not see how I may get out of "Prelude"
> in order to write a program.

Use a text editor, then load the file with ":load Foo.hs".

You can't type definitions into the hugs/ghci interpreter, just
expressions; definitions have to be loaded from a file.

[Actually, ghci is slightly more liberal; it also allows let forms
(e.g. "let foo = ...") and IO actions (e.g. "foo <- getLine").]

-- 
Glynn Clements <[EMAIL PROTECTED]>
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Perspectives on learning and using Haskell

2004-01-01 Thread ajb
G'day all.

Quoting Graham Klyne <[EMAIL PROTECTED]>:

> (2) I find that I spend a far greater portion of my time *thinking* about
> what I'm trying to do than actually coding it.  There used to be an adage
> in the software industry that programmer productivity in lines-of-code per
> day was independent of programming language:  with Haskell, I suspect that
> old rule breaks down, because it seems that actually coding has become a
> relatively small part of the overall exercise.

In theory, that's true of other languages too.  Programmers are
*supposed* to spend more time doing non-coding than coding (where I
don't, for example, count writing unit tests as "coding").

I suspect that this is actually an artifact of your level of experience
with Haskell.  I know that I used to spend more time thinking than coding.
When you get familiar enough, you get to the stage where you can think on
your feet.

> (4) I have noticed that it's often very easy to write some inefficient code
> (sometimes *very* inefficient) to do some task in Haskell, and then to
> optimize it.

This, I believe, is one of the most unappreciated (by non-declarative
programmers, anyway) aspects of declarative programming.  It's easy to
write could-be-slow code that works first time, once you've fixed all
the bugs caught by the compiler.  Then, it's straightforward to swap out
implementations and replace them with more efficient ones as the need
arises.

This is possible to do in non-declarative languages.  It's even
encouraged in "agile" OO methodologies, like XP.  However, it's so much
less painful in a declarative language, because you're far less tempted
to introduce hidden dependencies to begin with.

In fact, I find that my "working but slow" code has almost no weird
dependencies.  I find myself having to _introduce_ them during the "get
it faster" phrase.  From an engineering point of view, this is almost
exactly the right thing, because that way you (in theory) end up with as
few dependencies as possible.

> (6) I have found that Haskell seems to a particularly effective platform
> for pursuing some ideas of extreme programming,

There you go. :-)

There is only one problem I've found with test-driven development in
Haskell.  In C++, it's possible to break the "module" abstraction
(yes, I know, C++ doesn't have modules; it has classes, which are really
instantiable modules) by using "friend".  In Haskell, I find myself
occasionally having to expose parts of a module which I would prefer not
to, in order for the unit tests suite to do their job effectively.

I wonder if there might be a way to fix this, say, by allowing modules
to selectively expose parts of their interface depending on who wants
to use it.

Cheers,
Andrew Bromage
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


RE: no continuations

2004-01-01 Thread Kevin S. Millikin
On Tuesday, December 30, 2003 5:04 PM, Kevin S. Millikin 
[SMTP:[EMAIL PROTECTED] wrote:
> Oh, sure.  I didn't mean to quibble with the idea that continuations
> are computational effects.  Just wanted to point out that (I think)
> you can't macro express mutation with call/cc, unless you've already
> got mutation anyway.

[snip]

> Yup.  If you do that, you can use d as your setter and c as your
> getter:
>
> > (define c (make-cell))
> > (define d c)
> > ((d 'set) 9)
> > (c 'get)
> 9
> > ((d 'set) 17)
> > (c 'get)
> 17

It sure looks like the example contradicts the assertion, but I happen 
to know that there is a set! (or some other assignment) in the macro 
expansion of define.  I'm just using call/cc to get at that, rather 
than getting at the one in the expansion of letrec.

Moved to Haskell Cafe.
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Module creation

2004-01-01 Thread J & M van Berchem
  New to Haskell, I got a version, through Fink, for my Mac OS X.  I like
the interpreter very much, but I do not see how I may get out of "Prelude"
in order to write a program.

  Could you advise me ?  Thanks in advanceJacques van Berchem

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Perspectives on learning and using Haskell

2004-01-01 Thread Graham Klyne
At 17:44 23/12/03 -0500, Derek Elkins wrote:
On Tue, 23 Dec 2003 17:26:20 +
Graham Klyne <[EMAIL PROTECTED]> wrote:
(moved to Haskell-Cafe as this reply might generate several more)

> I've spent part of the past few months learning Haskell and developing
> a moderately sized application.  I came to this from a long background
> (20 years or so) of "conventional" programming in a variety of
> languages (from Fortran and Algol W to Java and Python).  For me,
> learning Haskell has been one of the steepest learning curves of any
> new language that I have ever learned.  Before this project, I was
> aware of some aspects of functional programming, but had never
> previously done any "in anger" (i.e. for real).
Well, the obvious question is: after climbing partway up that curve,
what do you think of the view?  Was it worth learning?  Is it worth
continuing to use?  Does the code seem 'better' than what you might
produce in other languages you've used?
I think the view is good :-)

Others have written about the advantages of FP, and I won't try to repeat 
that.  My personal observations include:

(1) I notice that it's very easy to pick up and use third-party 
functions;  there doesn't seem to be the square peg/round hole effect that 
one gets with third-party libraries in conventional programming 
languages.  I don't know why this is, but two possibly contributing factors 
may be:

  (a) many Haskell expressions are just values, so in some respects 
they're closer to data than to code.  There isn't a procedural aspect to 
get in the way (e.g. no need to coordinate passage through the "von Neumann 
bottleneck"?)

  (b) the type system permits, even encourages, typing details that are 
not relevant to some function to be left unspecified.

(2) I find that I spend a far greater portion of my time *thinking* about 
what I'm trying to do than actually coding it.  There used to be an adage 
in the software industry that programmer productivity in lines-of-code per 
day was independent of programming language:  with Haskell, I suspect that 
old rule breaks down, because it seems that actually coding has become a 
relatively small part of the overall exercise.

(3) it has often been noted that despite the influx of "new" programming 
languages, little is truly new -- the act of programming is pretty much 
unchanged since, er, the 60's?  I know the basic ideas of FP have been 
around for several decades, but I do think there is some truly new thinking 
being applied in the area of FP, compared with conventional languages.  I 
think I do see some truly different approaches being explored in the FP 
community, and some of those do seem to have some real value.  (e.g. the 
way that Monads turn out to be such a flexible idea.  I haven't yet started 
to look at arrows.)

  Related to this, it seems to me that Haskell's lazy functional model is 
capable of subsuming many other programming models.  One that I discovered 
quite early was mimicking the test-and-backtrack style of Prolog.  More 
recently, looking at the like of "scrap your boilerplate" ideas, it seems 
that FP is capable of tackling the separation of "cross-cutting concerns" 
that seem to motivate the more recent Aspect Oriented Programming ideas, 
without really adding any new language features.

(4) I have noticed that it's often very easy to write some inefficient code 
(sometimes *very* inefficient) to do some task in Haskell, and then to 
optimize it.  My current project is currently riddled with horrendous 
inefficiencies, but I don't care because I am confident that I can optimize 
as and when I need to.  (The GHC profiling system is one reason for this 
confidence, and also the availability of off-the-shelf libraries to improve 
many of my very inefficient data structures.)

(5) working as I do in the area of Internet and Web protocols, I like the 
idea that I can (often) write code that is closely and "obviously" related 
to a specification that I'm trying to implement.  (This is an area that I'd 
like to explore further.)

(6) I have found that Haskell seems to a particularly effective platform 
for pursuing some ideas of extreme programming, and in particular test-led 
development.  (I do this very imperfectly, but I'm learning ;-)  For 
example, Dean Herington's unit testing framework seems to fit more 
comfortably into the  host language than, say, the JUnit framework from 
which it takes its inspiration.  Adding new styles of test-case has been a 
breeze compared with my experience of using JUnit or PyUnit (and I have 
found those frameworks to be very satisfactory).

(7) For the first time since learning Pascal, I'm impressed at how reliable 
my Haskell code (messy as much of it may be by Haskell standards) has 
turned out to be.

If I sit here longer, I will probably think of more.

But, in summary, I think a combination of:
- improved language implementations
- improved hardware
- new ideas about how to use/deploy FP
- the nature of some Int

Parsing library

2004-01-01 Thread James Ealing
I'm trying to make use of the combinatorial parsing
library to process strings. However, I can't figure
out the correct syntax for the (|||) (^^^) (>>>) (<^^)
and (^^>) functions. Can anyone see how to do it? If
so it'd be really useful if you could put down a
couple of examples of how each is used.
 
Thanks
 
Jim
 
The library:
 
Generic parsing functions
>module Parse (
>  Parse, succeed, token, spot, 
>  (|||), (^^^), (<^^), (^^>), (>>>), 
>  many, listOf, topLevel, 
>  white, ws, parseVar, word, parseNum)
>where

---
-- Combinatory parsing library using Maybe types --
-- suitable for non-ambiguous grammars.  --
-- [EMAIL PROTECTED] (21/10/96)  --
---

>infixr 5 `into`, ^^^, <^^, ^^>
>infixl 4 >>>
>infixr 3 |||
Maybe defined in prelude:
data Maybe a = Just a | Nothing
-
-- Type of parsers --
-
>type Parse a = String -> Maybe (a, String)
---
-- Basic parsers --
---
Succeed with the value given.
>succeed :: a -> Parse a
>succeed val inp = Just (val, inp)
Recognize a specified token at the head of the input.
>token :: Char -> Parse Char
>token t (u:x) = if t == u then Just (t,x) else
Nothing
>token t [] = Nothing
Recognize a token with a certain property.
>spot :: (Char -> Bool) -> Parse Char
>spot p (t:x) = if p t then Just (t,x) else Nothing
>spot p [] = Nothing

-
-- Parsing combinators --
-
A choice between two parsers. The function p1 ||| p2
returns the result of p1
whenever it succeeds and the result of p2 otherwise.

>(|||) :: Parse a -> Parse a -> Parse a
>(p1 ||| p2) inp = case p1 inp of
>Nothing -> p2 inp
>Just (v,x) -> Just (v,x)

Sequencing of parsers. The function p1 ^^^ p2 returns
the result, if any, of
applying p1 to the input and then p2 to the remainder.

>(^^^) :: Parse b -> Parse c -> Parse (b,c)
>(p1 ^^^ p2) inp = 
>  case p1 inp of
>Nothing -> Nothing
>Just (v,x) -> case p2 x of
>Nothing -> Nothing
>Just (u,y) -> Just ((v,u),y)

Semantic action. The results from a parser p are
transformed by applying a
function f.

>(>>>) :: Parse b -> (b -> c) -> Parse c
>(p >>> f) inp = case p inp of
>   Nothing -> Nothing
>   Just (v,x) -> Just (f v, x)

Sequencing of parsers, choosing one component or the
other
>(<^^) :: Parse b -> Parse c -> Parse b
>p <^^ q = (p ^^^ q) >>> fst
>(^^>) :: Parse b -> Parse c -> Parse c
>p ^^> q = (p ^^^ q) >>> snd




Repetition. The parser p is used as many times as
possible and the results are
returned as a list.
>many :: Parse b -> Parse [b]
>many p = ((p ^^^ many p) >>> cons) ||| (succeed [])
>cons (x,xs) = x:xs
ListOf p c applies parser p as many times as possible,
with the instances
separated by instances of c, and returns the result as
a list.
>listOf :: Parse b -> Char -> Parse [b]
>listOf p sep = p ^^^ many (token sep ^^> p) >>> cons
The top level parser is a function which maps a list
of tokens to a value. A
value p :: Parse a b can be converted to such a
function by applying topLevel:
>topLevel :: Parse b -> String -> b
>topLevel p inp
>  = case p inp of
>  Just (result,[]) -> result
>  Just (result,rest) -> 
>error ("parse unsuccessful; input
unconsumed:"++show rest)
>  other -> error "parse unsuccessful"
Note there is an error if the input is not fully
consumed.
It is sometimes useful to test whether a given parser
will accept the input
without actually returning a result.
>acceptedBy :: Parse b -> String -> Bool
>acceptedBy parser inp
>   = case parser inp of
>   Just (result,[]) -> True
>   other -> False
A more sophisticated form of sequencing. The into
combinator allows the second
parser to be chosen according the result of the first.
 
>into :: Parse b -> (b -> Parse c) -> Parse c
>into p f inp = case p inp of
>   Nothing -> Nothing
>   Just (v,x) -> f v x
==
Absorb white space
>white = many (token ' ' ||| token '\t')
>ws p = white ^^> p <^^ white
==
Consume and return variable: must start with small
letter, and continue with
alphanumberic characters
>parseVar :: Parse String
>parseVar = spot isLower ^^^ many (spot isAlphaNum)
>>> cons
Consume and return particular word
>word :: String -> Parse String
>word [c] = token c >>> (\ c -> [c])
>word (c:cs) = (token c ^^^ word cs) >>> cons
Consume and return number
>parseNum :: Parse Int
>parseNum = spot isDigit ^^^ many (spot isDigit) >>>
mknum
> where mknum (d, ds) = foldl f (digitToInt d) ds
>   f n d = 10*n + digitToInt d


Yahoo! Messenger - Communicate instantly..."Ping" 
your friends to

Re: Parsec question

2004-01-01 Thread Mark Carroll
Thanks to Tom for his interesting points. I am still developing an
inuition for how the error reporting goes. (-:

On Thu, 1 Jan 2004, Derek Elkins wrote:

(snip)
> > > testOr3 =   do{ try (string "(a"); char ')'; return "(a)" }
(snip)
> example both issues come up.  If we successfully parse the
> "(a" then the second alternative "(b)" can't possibly succeed and since
> it can't succeed there's no point in saving the input "(a" to be
> reparsed when backtracking since there's no point in backtracking.
(snip)

Ah, that makes sense - thanks! I think part of my problem might have been
the quoted and real brackets and braces - at least a couple of times, I
thought the char and the return were within the try. (-: I will try to
look more carefully next time.

-- Mark
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Parsec question

2004-01-01 Thread Tomasz Zielonka
On Wed, Dec 31, 2003 at 07:21:54PM -0500, Mark Carroll wrote:
> I tried posting this before but, from my point of view, it vanished. My
> apologies if it's a duplicate.
> 
> In http://www.cs.uu.nl/~daan/download/parsec/parsec.html we read,
> 
> > testOr2 =   try (string "(a)")
> > <|> string "(b)"
> >
> > or an even better version:
> >
> > testOr3 =   do{ try (string "(a"); char ')'; return "(a)" }
> > <|> string "(b)"
> 
> Why is the latter better?

testOr3 is a bit better at error reporting, for example:

  *> parseTest testOr2 "(a"
  parse error at (line 1, column 1):
  unexpected "a"
  expecting "(b)"

  *> parseTest testOr3 "(a"
  parse error at (line 1, column 3):
  unexpected end of input
  expecting ")"

But it still gives silly error messages in some cases:

  *> parseTest testOr3 "("
  parse error at (line 1, column 1):
  unexpected end of input
  expecting "(b)"

The original testOr1 is better here:

  *> parseTest testOr1 "(a"
  parse error at (line 1, column 3):
  unexpected end of input
  expecting ")"

  *> parseTest testOr1 "("
  parse error at (line 1, column 2):
  unexpected end of input
  expecting "a" or "b"

  *> parseTest testOr1 ""
  parse error at (line 1, column 1):
  unexpected end of input
  expecting "("

> (BTW, I like Parsec. Thanks, Daan. (-:)

I like Parsec too :)

Tom

-- 
.signature: Too many levels of symbolic links
___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: Parsec question

2004-01-01 Thread Derek Elkins
On Wed, 31 Dec 2003 19:21:54 -0500 (EST)
Mark Carroll <[EMAIL PROTECTED]> wrote:

> I tried posting this before but, from my point of view, it vanished.
> My apologies if it's a duplicate.
> 
> In http://www.cs.uu.nl/~daan/download/parsec/parsec.html we read,
> 
> > testOr2 =   try (string "(a)")
> > <|> string "(b)"
> >
> > or an even better version:
> >
> > testOr3 =   do{ try (string "(a"); char ')'; return "(a)" }
> > <|> string "(b)"
> 
> Why is the latter better?

As soon as you reach a point where a syntax error means no parse will
succeed you want to commit to that alternative for two reasons.  1) As
long as there appears to be a possibility for an alternative parse the
input needs to be saved and 2) there's no point backtracking if all
other alternatives will fail; it just wastes time.  In the above
example both issues come up.  If we successfully parse the
"(a" then the second alternative "(b)" can't possibly succeed and since
it can't succeed there's no point in saving the input "(a" to be
reparsed when backtracking since there's no point in backtracking. 
Obviously, this example is merely to illustrate the idea as there'd be
little to no inefficiency in this case.

___
Haskell-Cafe mailing list
[EMAIL PROTECTED]
http://www.haskell.org/mailman/listinfo/haskell-cafe