[Haskell-cafe] consulting and contracting

2009-12-11 Thread Tim Newsham

I was wondering how many haskell consultants and contractors
(ie. freelance programmers) there are and how much demand there
is for their work.  Also what kind of work do most haskell
consultants and contractors get?  Is it primarily focused
around developing and maintaining haskell compilers and tools?
Mostly related to academia?  Spread out around several areas?

Tim Newsham | www.thenewsh.com/~newsham | thenewsh.blogspot.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Pike's Newsqueak talk

2009-06-05 Thread Tim Newsham

Tim Newsham  wrote in article 
 in gmane.comp.lang.haskell.cafe:

his language also
supports an interesting imperative primitive that lets you pick the first
available value from a set of channels which isn't available in pure
Haskell expressions.  Has anyone implemented a primitive like this for
Haskell?


Could it be the "amb" described at
   http://conal.net/blog/posts/functional-concurrency-with-unambiguous-choice/
   http://conal.net/blog/posts/smarter-termination-for-thread-racing/
?


It reminds me a little of unamb but is different.  Unamb is pure
and picks the first computed value of several consistent computations.
The select operator picks the first available value from a set of diff
channels, some of which may have diff types and so is definitely
not pure.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Pike's Newsqueak talk

2009-06-05 Thread Tim Newsham

I just watched http://video.google.com/videoplay?docid=810232012617965344

It's a great talk that is suprisingly relevant to Haskell programming 
(although at first blush it looks a bit unrelated). (It refs a lot of 
older work that actually led me to Haskell in the first place by way of 
McIlroy's haskell power-series paper).  Anyway, I thought it would be of 
general interest.


A lot of the progrms he discusses are a lot more elegant in pure Haskell 
code (ie. prime number sieve, power series), but his language also 
supports an interesting imperative primitive that lets you pick the first 
available value from a set of channels which isn't available in pure 
Haskell expressions.  Has anyone implemented a primitive like this for 
Haskell?


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] about Haskell code written to be "too smart"

2009-03-24 Thread Tim Newsham
When you think about it, what you are saying is that Haskell programmers 
shouldn't take advantage of the extra tools that Haskell provides. 


No, I'm not saying this.

But, as an example, when you read a function like:

buildPartitions xs ns = zipWith take ns . init $ scanl (flip drop) xs ns

that can be rewritten (argument reversed) as:

takeList :: [Int] -> [a] -> [[a]]
takeList [] _ =  []
takeList _ [] =  []
takeList (n : ns) xs  =  head : takeList ns tail
   where (head, tail) = splitAt n xs


I think this is a perfect example.  Haskell allows you to abstract out the 
concepts of recursion, zipping and iteration.  Your alternative reproduces 
these explicitely and intermixes them.  You are saying that programmers 
should avoid using these higher level abstractions and instead fall back 
to more explicit constructs that are, for you, easier to read.


The problem is that I have still problems at reading and understanding code 
that is too much terse...
Because I have to assemble in my mind each block, and if there are too many 
blocks I have problems.


It takes practice to read and to write.  The benefit is more 
expressiveness and more code reuse.



Manlio


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] about Haskell code written to be "too smart"

2009-03-24 Thread Tim Newsham
These friends are very interested in Haskell, but it seems that the main 
reason why they don't start to seriously learning it, is that when they start 
reading some code, they feel the "Perl syndrome".


That is, code written to be "too smart", and that end up being totally 
illegible by Haskell novice.


I too have this feeling, from time to time.

Since someone is starting to write the Haskell coding style, I really suggest 
him to take this "problem" into strong consideration.


When you think about it, what you are saying is that Haskell programmers 
shouldn't take advantage of the extra tools that Haskell provides. Haskell 
provides the ability to abstract code beyond what many other programming 
systems allow.  This abstraction gives you the ability to express things 
much more tersely.  This makes the code a lot harder to read for people 
who are not familiar with the abstractions being used.  This can be 
overcome with practice and experience.


I'm not trying to say that code can never get too complex.  Humans have 
some complexity budget and its not too hard to push the limits and blow 
your complexity budget.  But that is true in any language. The ability to 
abstract lets you factor out common patterns that are easy to reuse and 
remember (with practice) and lets you spend your complexity budget 
elsewhere.  As a programmer you still need to use your judgement to 
balance complexity against understandability.


[Obviously if you are writing code that you want to be readable by
people who arent well versed in common Haskell idioms, you'd limit
your use of abstractions.]


Manlio


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] symbolic evaluator for Haskell?

2009-03-18 Thread Tim Newsham
Lambdabot (on #haskell) has something similar using a type, Expr, to overload 
certain names, e.g.


   koninkje   > foldr f z [1..5]
   lambdabot  f 1 (f 2 (f 3 (f 4 (f 5 z

It's a complete hack and isn't as sophisticated as what you're after, but it 
could serve as a basis for implementation ideas.


I'm aware of the Expr stuff in lambdabot and elsewhere.  This is not
quite what I need, perhaps I should have picked an example that
doesn't almost-work with Expr.  I need something that will symbolically
evaluate a complex non-numeric expression that makes use of GADTs.

I'm thinking it might not be too hard to implement using TH, but haven't
tried yet...  (though not sure if TH supports GADTs).


Live well,
~wren


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] symbolic evaluator for Haskell?

2009-03-17 Thread Tim Newsham

Is there a symbolic evaluator for Haskell that will perform all
applications except on specified functions?  Ie. I would love
something that would take

foldr (+) (6 `div` 5) [1,2,3*4]

and "(+) (*)" and return

   1 + (2 + (3*4 + 1))

by performing all the applications except for (+) and (*).
(Something that supports ghc extensions is preferred :)

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] binary serialization

2009-03-04 Thread Tim Newsham

fft1976:

Is there a way to do binary serialization of Haskell values (in GHC,
at least)? If you propose a method, what are its type safety and
portability properties?


There are many ways. See Data.Binary (fast, portable). Most are type
safe, or additional safety can be added.


I would add to that: Data.Derive can be used to automatically
generate Data.Binary.Binary instances for your custom data types.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] monadic MapReduce

2009-03-03 Thread Tim Newsham

How about this. Is there a reason why I can't
replace the variables b and c in the type signature of mapReduce with with (IO 
b')
and (IO c'). b and c  can be any types.

mapReduce :: Strategy (IO b')-- evaluation strategy for mapping
  -> (a -> IO b')  -- map function
  -> Strategy (IO c')-- evaluation strategy for reduction
  -> ([IO b'] -> (IO c'))-- reduce function
  -> [a]   -- list to map over
  -> (IO c')

Just remember to wrap all values back in the IO monad.


Remember, the idea of map-reduce is to provide a very restrictive
programming interface so that you have a lot of flexibility in
your execution strategy.  If you start loosening the interface
you will still be able to execute the program, but you may
not be able to perform all the great optimizations you want to
perform.  For example, if you are using IO actions that are
stateful, what are the semantics?  Can one map action affect
other map actions?  Does this imply an ordering of the map functions?
Does this imply they all run on the same machine or at least have
state communicated between the machines on which they run?

The austere interface precludes any of these issues, and therein
lies the beauty.


Anish


Btw. I prefer the sawzall formulation over the map-reduce formulation.
A sawzall program just specifies how to map some data to a monoid
and the system is free to mappend the monoid values in whatever order
it wants (by applying associativity).

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] nubBy changed?

2009-03-01 Thread Tim Newsham

Did nubBy change recently?  In 6.8.2 I could generate primes as:

   nubBy (\a b -> b `mod` a == 0) [2..]

but in 6.10.1 I have to use

   nubBy (\a b -> a `mod` b == 0) [2..]

Is this change intentional?  If so, what is the reason?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Formal semantics for Haskell?

2009-02-09 Thread Tim Newsham

ML has a formal definition[1]; why not Haskell?  Would this be a Good Thing,
or a Waste Of Time?


Not exactly what you are asking for, but a start:
http://www.cs.kent.ac.uk/pubs/1992/123/index.html


gregg


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monad explanation

2009-02-06 Thread Tim Newsham

So if IO represents a program that when executed interacts with the world's
state, is it safe to say that when I return (State Int Int), that I'm
returning a "State program"?  That'd make sense as it really does look like
we force the State to be evaluated with runState, evalState or execState.


Yes, exactly.


The only difference with IO then is that to get IO programs to run, you have
to do it inside another IO program.


Almost.  Add to your mental model a "runIO" that is invoked when your 
program runs as:  "runIO main".  Your haskell compiler or interpretter 
arranges this for you as part of its contract with you.



I hope I'm not making this worse! :-)


I dont think so.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Monad explanation

2009-02-05 Thread Tim Newsham

You are absolutely right.  The statement
 "The values of the IO monad are programs that do IO. "
is somewhat nonsensical. Values don't do anything, they just are.
But values of the IO monad *describe* how to do IO; they can be seen
as a recipe for doing IO.
A recipe doesn't cook a dish, but when the recipe is executed by a
cook they creates a dish.
An IO values doesn't do IO, but when it is executed by the runtime
system IO happens.


Just as a recipe describes how to cook something, a program describes
how to accomplish something.  The program doesnt "do" anything
until it is executed.  However, we often use the word "do" to
describe what a program will do when executed (even though
its really the cpu that is actually "doing").


This is one way of interpreting what the IO type means.
(Another one is to say that Haskell is just an imperative programming
language, but any imperative actions show up in the type.)


I don't see the difference between these two interpretations.
Wether the program is made up of instructions for a cpu or for
an interpreter seems irrelevant.


 -- Lennart


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Monad explanation

2009-02-04 Thread Tim Newsham

I put up a small Monad explanation (I wouldn't quite call it
a tutorial):
  http://www.thenewsh.com/~newsham/haskell/monad.html

The intent here is to is to have a short description of what
a Monad is that is approachable by Haskell beginners or non-
Haskell programmers who are looking for an intuitive definition
but may not yet have the background or the inclination to
jump into full tutorial to tackle the subject.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Verifying Haskell Programs

2009-02-03 Thread Tim Newsham

State of the art is translating subsets of Haskell to Isabelle, and
verifying them. Using model checkers to verify subsets, or extracting
Haskell from Agda or Coq.


Don, can you give some pointers to literature on this, if any?  That
is, any documentation of a verification effort of Haskell code with
Isabelle, model checkers, or Coq?


Graham Hutton's _Programming in Haskell_ has a chapter on reasoning
about Haskell code:
  http://www.cs.nott.ac.uk/~gmh/book.html

I put together some exercises of some short proofs for small
Haskell functions:
  http://www.thenewsh.com/~newsham/formal/problems/

I have a short article that covers proofs in Haskell and Isabelle:
  http://users.lava.net/~newsham/formal/reverse/

The seL4 project is specifying an OS in Haskell, proving it in Isabelle
and translating it to C with proofs that connect the translations:
  http://ertos.nicta.com.au/research/sel4/

I have an article on the curry-howard correspondence
  http://www.thenewsh.com/~newsham/formal/curryhoward/

In systems like Coq you can write code and proofs of the code in
the same language and even at the same time.  The Coq'Art book is
a good reference, as are Adam Chlipala's draft book and Harvard
class materials and the _Type Theory & Functional Programming_ book.
Full text for all but Coq'Art are online:
  http://www.labri.fr/perso/casteran/CoqArt/index.html
  http://www.cs.harvard.edu/~adamc/cpdt/
  http://www.cs.harvard.edu/~adamc/cpdt/book/
  http://www.cs.kent.ac.uk/people/staff/sjt/TTFP/


         Denis


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell Web Framework

2009-01-26 Thread Tim Newsham

those that want it. From my Django experience, I must say that very few
things are cooler than calling a script which automatically generates all
the boilerplate code inherent in every web app.


Cooler:  abstracting away the boilerplate.


Michael


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Why monoids will abide...

2009-01-22 Thread Tim Newsham

On Thu, 22 Jan 2009, Eugene Kirpichov wrote:

To my mind, in the map-reduce case you generally need a commutative
monoid. Or, you need an extra infrastructure that mappend's only
results from adjacent machines, or something like that.


The paper
   http://www.cs.vu.nl/~ralf/MapReduce/

analyzes the model of Google's MapReduce and Sawzall.  quick haskell 
summaries at:

   http://www.thenewsh.com/~newsham/x/machine/MapReduce.hs
   http://www.thenewsh.com/~newsham/x/machine/Sawzall.hs

The MapReduce model isn't based directly on a monoid, but the Sawzall 
model is.


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] ANN: HTTPbis / HTTP-4000.x package available

2009-01-17 Thread Tim Newsham

There's however still no framework which supports both HTTP client and
server functions using the same Request and Response data type, right? I
don't know whether I am the only one who needs this (e.g. for the Real
Monad Transformer). E.g. a proxy would need this, too.


I've wanted this for a while now.  "Me Too."

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] software correctness ... can we in FPL step up to the plate??

2009-01-15 Thread Tim Newsham

http://www.businessweek.com/the_thread/techbeat/archives/2009/01/nsa_dhs_industr.html?link_position=link3
...

I think that http://www.galois.com is already doing as stated in the
article/ .. I sincerely think there is a segway for Haskell here with
strong and static type checking..


Strong static type checking is a very useful tool, but there's a lot more 
to securing against the 25 most common errors.  For example, you can use 
the type system to ensure that output encoding is always applied to

user-provided data, but you must first be aware of this issue and
write libraries that enforce this and make use of these libraries a
requirement in applications or application frameworks.  Some problems
such as cross-site request forgery are best addressed by the application
framework, so framework authors must be aware of these issues and
implement protections for the issue.  This usually involves the use
of some cryptographic primitives, and the type system doesn't do
anything to make sure you get that right.

Security issues are (mostly) a subset of correctness issues.  Haskell 
provides some tools to help you make sure your program is correct, but 
there are a lot of ways to write incorrect software despite the help

these tools provide.  These tools are very valuable and should be
sold to the wider developer community, but they are no silver bullet.


Vasili


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Monads aren't evil? I think they are.

2009-01-13 Thread Tim Newsham

I have seen several libraries where all functions of a monad have the
monadic result (), e.g. Binary.Put and other writing functions. This is
a clear indicator, that the Monad instance is artificial and was only
chosen because of the 'do' notation.


Maybe that was the initial reason, but I've actually found the
Binary.Put.PutM (where Put = PutM ()) to be useful.  Sometimes
your putter does need to propogate a result...

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Haskell not ready for Foo [was: Re: Hypothetical Haskell job in New York]

2009-01-09 Thread Tim Newsham
Don't get me wrong -- the socket support is pretty decent, but there are also 
some weird idiosyncrasies, for example requiring that the PortNum is 
specified in network byte order and lacking a function to convert 
host->network byte order (hton).


PortNum is indeed strange, but it does allow yo to specify the
value in your local endian without swapping:

   > print (toEnum 0x0102 :: PortNumber)
   258

what is misleading you is that the obvious construction doesn't:

   > print (PortNum 0x0102)
   513

I'm suprised htonl comes up so often.  You can unmarshall data directly 
from a byte stream to an Int type without caring about the underlying 
representation of your Int.  Why do people want the htonl function?



Bardur Arantsson


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell not ready for Foo [was: Re: Hypothetical Haskell job in New York]

2009-01-08 Thread Tim Newsham

On Jan 8, 2009, at 12:56 PM, Tim Newsham wrote:

You replied to someone discussing using Haskell at a CDN to implement
things like web servers by saying that Haskell wasn't suitable for
the task.


That is incorrect. I replied to Achim's message asking for elaboration on 
Haskell's unsuitability. It was a convenient point to discuss Haskell's 
networking deficiencies.


Oops.  My apologies.


Regards,
John


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell not ready for Foo [was: Re: Hypothetical Haskell job in New York]

2009-01-08 Thread Tim Newsham
The number of applications requiring the implementation of a custom web 
server is an insignificant fraction of the number of applications requiring a 
messaging system. I don't think anyone would dispute Haskell's ability to do 
low-level, raw networking, of the type that few people actually need to do. 
It's the higher level stuff where there's a huge amount of room for 
improvement.


You replied to someone discussing using Haskell at a CDN to implement
things like web servers by saying that Haskell wasn't suitable for
the task.


John


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell not ready for Foo [was: Re: Hypothetical Haskell job in New York]

2009-01-08 Thread Tim Newsham
Take, for example, RabbitMQ. There's nothing even remotely close in 
Haskell-land.


That would be useful for systems that require an "enterprise
messaging system," I agree, but I don't see how that would
be terribly important for a web server or most other networking
services I might want to implement.


John


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] data declarations should provide fold functions

2009-01-07 Thread Tim Newsham

I've had to use some fold functions recently and I've come to
the conclusion that Haskell should automatically generate
fold functions for data definitions.  To clarify what I mean,
for the data definition:

data MyData = This Int Char | That String Int Int

there should be a matching function definition:

foldMyData f g (This a b) = f a b
foldMyData f g (That a b c) = g a b c

This definition is as natural as the constructors "This" and
"That".  Consider the tuple definition and its fold:

data (,) a b = (a, b)
foldTuple f (x, y) = f x y

and the definition of Either and its fold:

data Either a b = Left a | Right b
foldEither f g (Left x) = f a
foldEither f g (Right x) = g x

In logic these constructors define the introduction rules
((,), Left and Right) and the folds define the elimination
rules (exactly for Either, indirectly for tuples) for conjunction
and disjunction.

Further, while pattern-matching is very convenient for accessing
the constituents of the data type, patterns are not first-class
objects in Haskell.  Fold functions, on the othe hand, are.
They can be passed around and used in higher-order functions
to extract constituents in a points-free manner.

I know the short-term answer is "use TH" to derive folds if
I want them, but I think such an important concept should probably
be part of the language.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Coroutines

2008-12-18 Thread Tim Newsham

Andrew was recently asking about co-routines.  A couple of years ago,
I was in much the same position as him; although I am pretty sure I
had heard the term before, it seemed like a mysterious idea with no
practical use.


Besides the point that people have already made that lazy evaluation
gives you similar control as coroutines, I wanted to point out how
simple it is to implement coroutines.  Here's a simple implementation
that ddarius made on IRC a few months back off-the-cuff.  I kept
it around on codepad because its cool:

  http://codepad.org/GwtS6wMj


 -- ryan


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Crash!

2008-10-24 Thread Tim Newsham

Haskell programs with particular constraints (i.e. pure, total Haskell, doesn't
primarily call gtk...)


Yup, and that's a great thing that we should be evangelizing to
all potential users.  No need to go overboard and tell them that
there will never be a crash, though..  The robustness claim is
strong enough without embellishment.


-- Don


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Crash!

2008-10-24 Thread Tim Newsham
The point is... I'm not doing that. Gtk2hs is, but that's a well-tested 
library, so I very much doubt it's the source of the bug.


I don't understand why Haskell users believe (perhaps are too often led to 
believe) that haskell programs can't crash.  Gtk2hs does a lot of native 
stuff.  Gtk's been around for a long time, but so has a lot of other 
software that has lots of bugs still present in it. Often these bugs lead 
to memory corruption and crashes.  Haskell does nothing to prevent this 
from happening (how could it?).


I entirely expect that this crash is due to Gtk2hs (well-tested though it 
may be) or one of its underlying dependencies (such as libpng).


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] synchronous channels in STM

2008-10-09 Thread Tim Newsham

I was wondering if it was possible to implement synchronous channels
within STM. In particular, I'd like to have CSP-like send and recv primitives
on a channel that each block until the other side arrives to complete
the transaction.

I think I've convinced myself that it's not possible, but
anyone care to differ?


Not quite the same thing, but you can implement synchronous message
passing fairly easily with MVars.  Here's a small example that
builds coroutines, courtesy of ddarius:

   http://codepad.org/GwtS6wMj

you could modify this slightly to have the receiver release the
sender as soon as the message is received, if that's what you wanted.
Is this close enough for you, or does it have to be in STM?


 cheers,
   rog.


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] TH code for deriving Binary and NFData instances

2008-09-27 Thread Tim Newsham

Here's some TH code for automatically deriving Data.Binary
and Control.Parallel.Strategies.NFData instances:

   http://www.thenewsh.com/~newsham/store/DeriveBinary.hs


Saizan pointed me to:
http://www-users.cs.york.ac.uk/~ndm/derive/

which does most of what DeriveBinary.hs does (and lots more).

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] TH code for deriving Binary and NFData instances

2008-09-27 Thread Tim Newsham

Here's some TH code for automatically deriving Data.Binary
and Control.Parallel.Strategies.NFData instances:

http://www.thenewsh.com/~newsham/store/DeriveBinary.hs

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] TH error

2008-09-26 Thread Tim Newsham

I'm goofing with TH and I have my program mostly done:

http://hpaste.org/10713

If I have the "$(deriveBinary ''MyData)" line commented out it
prints out what looks to me like correct code.  I can even paste
it into a program and it compiles.  However, when the line isn't
commented out I get an error I don't understand:

test.hs:1:0:
Illegal data constructor name: `x'
When splicing generated code into the program

There are two places in my code I use "x" in splices that could
be causing the problem:

g <- [| getWord8 >>= \x -> $(caseE [| x |] gcases') |]
and
  put x = $(caseE [| x |] (map return ps)) |]

but I don't understand why these might be causing errors (if they
are indeed the cause).  Using -ddump-splices doesn't help since
it seems to hit the error before dumping splices.

What's going on here?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell shootout -- mandelbrot

2008-09-21 Thread Tim Newsham

Here's a whack at regex-dna:
  http://haskell.org/haskellwiki/Shootout/Parallel/RegexDNA

only modest speedup (memory bw bound?).  A regex engine that could
run several machines concurrently in one pass would prob be a big win.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell shootout -- mandelbrot

2008-09-20 Thread Tim Newsham

a) have you submitted it to the shootout.


no


b) is it faster


yes


c) can you put it on the parallel shootout wiki,
   http://haskell.org/haskellwiki/Shootout/Parallel


http://haskell.org/haskellwiki/Shootout/Parallel/Mandelbrot

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] haskell shootout -- mandelbrot

2008-09-20 Thread Tim Newsham

Since this one's trivially parallizable, I took a crack at the
mandelbrot test case.  It was fairly easy to thread it on a
per-line basis in Haskell without changing the original too much.
It might be more efficient to break the work into larger chunks,
but that would require some slightly more complicated changes so
I didn't try that yet.

Anyway, the code and the results are here.  See README for details:
   http://www.thenewsh.com/~newsham/shootout/

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Functional references

2008-09-06 Thread Tim Newsham

Tim Newsham's approach with invertible functions is interesting, though it
feels like it's another layer wrapped on top of the primitive idea of
functional references.


Not all of the refs are using invertible functions..  however, the
ones that are invertible are more flexible.. you can use them
to make functional references that are mapped over lists, for example.

I've reformulated my code a few times since initially posting it..
In the latest incarnation, FRefGen (generic FRefs with arbitrary
get/modify) and Inv (invertible functions) are both instances of an
FRef class.  In earlier versions I had a function for converting
an invertible into an FRef.


~wren


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Functional references

2008-09-05 Thread Tim Newsham

It's especially bad when modules are extremely likely to be used
together, like Control.Monad.State & FRef, or Data.Map & the Prelude.
You end up being required to import one or the other qualified.


I think in the case of State vs. FRef a simple solution is to make
two modules: FRef, which uses "get" and "set" and "modify"
naturally, and FRef.State which defines State equivalents without
polluting the namespace.  Then if you're working with pure functions
you can import FRef and use the natural names, and when you're using the 
State monad you can import FRef.State and get the State definitions

that dont interfere with the standard "get" and "modify" names.
In the rare case (I think, am I wrong?) where you use both State
and FRef "modify" and "get" definitions in the same file, you can
import the one you use less off qualified...


 -- ryan


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Functional references

2008-09-04 Thread Tim Newsham
I'm playing with functional references and looking for some feedback on a 
small FRec library I put together:


  http://www.thenewsh.com/~newsham/FRef.hs

Novel (I think) is that the library is applied to some data accesses that 
are not normally covered by functional references -- ie. extracting words 
or replacing words in a string or values in an association list.  I'm 
hoping it will provides a useful framework for editing complex values such 
as data embedded in Base64 cookies in an HTTP header.


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell Propeganda

2008-08-28 Thread Tim Newsham
GNU ld supports "pragmas" which cause the use of certain functions to output 
warnings at link time (try compiling a C program that uses gets()).  It 
occurs to me that this, either in compiler or linker, would be a nice thing 
for ghc to do when using fromJust or other partial functions.


would you include all partial functions in this, such as head?


brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] contributing to standard library

2008-08-26 Thread Tim Newsham

Like everyone else who has used Haskell for a while, I'm accumulating
functions which I feel should have already been in the standard
libraries.  What's the normal path to contributing functions for
consideration in future standard libraries?  Is there some
experimental standard lib that we can contribute to to "try
out" for the big league?

Here are some functions:
  http://www.thenewsh.com/%7Enewsham/x/machine/Missing.hs

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell Propeganda

2008-08-23 Thread Tim Newsham
As a day-time java programmer, I can say from experience that sometimes (100% 
pure) Java programs DO segfault.


I've had it happen to me, and while you can justifiably say it's an error in 
the JVM somehow triggered by your program behaviour/timing, that doesn't help 
you very much at the time.


Sure, and just as java has its runtime, so does Haskell.  Runtimes
are software and prone to being buggy.  Runtimes are often written
in languages like C where bugs can lead to memory corruption, crashes
and arbitrary malicious code execution.

Here's a small example that I unfortunately ran across today:

ghc -c wxdirect/src/CompileClassTypes.hs -o
  dist/wxdirect/CompileClassTypes.o -idist/wxdirect -odir dist/wxdirect
  -hidir dist/wxdirect  -package parsec -cpp  -package time
Segmentation fault (core dumped)

:(


Maarten Hazewinkel


The point being that Haskell, while having a theorem checker that helps
programmers find and avoid bugs and while being based on semi-formal
concepts that can be used to avoid some pitfalls, is still no silver
bullet against any and all crashes.  Promising would-be converts that
it is will only lead to disappointment.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Haskell Propeganda

2008-08-23 Thread Tim Newsham
I guess I didn't express my point very clearly... That C programmers 
apparently don't realise that a type system that's sound will give them 
something -- i.e. their programmer won't ever segfault.  I wonder when we try 
to advertise Haskell if we should be saying "we can give you programs that 
never segfault", instead of "we have a strong type system".


That would be overpromissing.  You can definitely get segfaults in
Haskell.  The obvious example being

  http://codepad.org/Q8cgS6x8

but many less contrived and more unexpected examples arise naturally
(unfortunately).

By the way, the Java camp has (correctly) been touting this argument for 
quite a while.



Bob


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] FRP question

2008-08-17 Thread Tim Newsham

I'm interested in FRP, have read several of the papers and am wondering
if it could be applied to writing multi-client server programs.
What would be the input type events for such a system?  What would
be the output type events?  How would the system handle the fact
that it has to multiplex several IO streams (sockets)?

I'm trying to answer these questions myself and having a hard time.
Should input events include new connection requests and shutdowns?
Individual bytes?  Streams of bytes?  or higher level PDUs?
What kind of output should be generated?  Full PDUs?  streams of
bytes?  Pairs of (connection identifier,data)?
How would such a system effectively hide the multiplexed IO going on?
Is this sort of problem poorly suited for FRP?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-14 Thread Tim Newsham

Maybe it makes sense to have the streamble list instance in Binary as
well, with some examples?



Chunk = {
   length :: Word8
   elems :: [Elem]  --  0..255 repetitions
 }
Chunks = [Chunk] -- terminated with the first 0 length Chunk


I tried my hand at the encoding above:

http://www.thenewsh.com/%7Enewsham/store/test10.hs

it seems to work, although it doesn't seem to be very efficient.
I'm getting very large memory growth when I was hoping it
would be lazy and memory efficient...  What's leaking?


-- Don


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-14 Thread Tim Newsham

I think he might be saying that decodeFile is not the place for
application code, because the lower level cannot possibly know whether
it makes sense for there to be residual data in the ByteString. There
are plenty of file formats that consist of back-to-back concatenated
chunks of data, in which reading just one chunk does not by any means
require that a file can only contain one.


Right, but because of the way decodeFile works, whenever you do
not have a data type that explicitely checks for EOF in it's
Get definition, decodeFile will leak a file handle.  There is no
way to check that there is residual data, to access it, or to
close the file handle.  Since this is the normal state of affairs
(are there any Get definitions in the current library which check
for EOF when done?) I would suggest that this is an API bug.

I would suggest that "decodeFile" should check for EOF when done.
A second wrapper function "decodePartialFile" could return the
unconsumed data, perhaps, for situations when the EOF behavior is
not desired, or return some other way for the file to be closed.

Additionally, I would suggest that the Data.Binary library provide
a combinator for consuming data fully (ie. checking for EOF).  ie:

   fully :: Get a -> Get a
   fully a = do
  x <- a
  e <- isEmpty
  return $ case e of
  False -> error "expected EOF"
  True  -> x

   decodeFully = runGet $ fully get
   decodeFile fn = decodeFully <$> B.readFile fn

to make it easy for developers who do not use the decodeFile
primitive to add EOF checking to their marshalling functions.

As it currently stands, the most obvious application of the Data.Binary
API leads to subtly confusing errors that may go unnoticed for a
while.  (This would be a fine point for the documentation to address
to prevent others from falling in the same hole).

I'm currently using definitions like these and (`using` rnf) and
have a server that is able to repeatedly read and write the state
file.  Many thanks to Dons, Brian, Duncan and everyone else who
helped me out...

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-13 Thread Tim Newsham

So am I understanding you correctly that you believe this is not
a bug?  That the use Data.Binary.decodeFile function leaks a file
descriptor and this is proper behavior?

I still don't understand your explanation of how isEmpty can
return True without having read to EOF.  The ByteString continues
to contain more data until an EOF is reached.  Doesn't one of

 return (B.null s && L.null ss)

force getContents to read until EOF?

On Wed, 13 Aug 2008, Don Stewart wrote:

newsham:

Ok, surely at least everyone must agree that this is a bug:

  force :: Word8 -> IO Word8
  force x = print x >> return x
  -- force = return . (`using` rnf)

  main = do
  d <- force =<< decodeFile stateFile
  encodeFile stateFile d
  where stateFile = "1word32.bin"

test8.hs: 1word32.bin: openBinaryFile: resource busy (file is locked)



Remember that

   decodeFile f = liftM decode (L.readFile f)

and

   readFile :: FilePath -> IO ByteString
   readFile f = openBinaryFile f ReadMode >>= hGetContents

where hGetContents sits in a loop, reading chunks,

   loop = do
   c <- S.hGetNonBlocking h k
   if S.null c
 then do eof <- hIsEOF h
 if eof then hClose h >> return Empty
else hWaitForInput h (-1)
  >> loop
 else do cs <- lazyRead
 return (Chunk c cs)

while isEmpty is just,

   isEmpty :: Get Bool
   isEmpty = do
   S s ss _ <- get
   return (B.null s && L.null ss)

That is, it checks the parsed chunk, it doesn't demand any more reading be done.

So the only way you're going to get that Handle closed by readFile is to ensure
you read till EOF is hit. After you decode, just ask keep asking for bytes till 
EOF,
or close it yourself,

   decodeFile f = do
   h  <- openFile f ReadMode
   ss <- L.hGetContents h
   let e = decode ss
   rnf e `seq` hClose h

or some such, where you can confirm the decoding as taken place.



Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-13 Thread Tim Newsham

Ok, surely at least everyone must agree that this is a bug:

  force :: Word8 -> IO Word8
  force x = print x >> return x
  -- force = return . (`using` rnf)

  main = do
  d <- force =<< decodeFile stateFile
  encodeFile stateFile d
  where stateFile = "1word32.bin"

test8.hs: 1word32.bin: openBinaryFile: resource busy (file is locked)

the built-in Data.Binary.decodeFile function doesn't close
its handle when it is done (same reason as my earlier examples).


However, I think probably the real blame here should probably go
to Data.Binary which doesn't attempt to check that it has consumed
all of its input after doing a "decode".  If "decode" completes
and there is unconsumed data, it should probably raise an error
(it already raises errors for premature EOF).  There's no reason
for it not to, since it does not provide the unconsumed data to
the caller when its done, anyway...


I would have expected this to fix my problems:

  binEof :: Get ()
  binEof = do
  more <- not <$> isEmpty
  when more $ error "expected EOF"

  decodeFully :: Binary b => B.ByteString -> b
  decodeFully = runGet (get << binEof)
where a << b = a >>= (\x -> b >> return x)

but even when using decodeFully, it still doesn't close the handle.
Shouldn't Data.Binary.Get.isEmpty force a file handle close in
the case that it returns True?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-13 Thread Tim Newsham

Should the file be closed when the last byte is read (in this
case its definitely reading all four bytes) or when the first
byte after that is read (in this case it probably doesn't
attempt to read more than 4 bytes)?


I'll answer my own question.  Both Prelude.readFile and
Data.ByteString.Lazy.Char8.readFile will keep the file open
after reading the last byte and close it when trying to
read further.  Proof:

  module Main where
  import Control.Applicative
  -- import qualified Data.ByteString.Lazy.Char8 as B
  import Prelude as B

  stateFile = "1word32.bin"
  main = do
  x <- B.take 4 <$> B.readFile stateFile
  -- x <- B.take 5 <$> B.readFile stateFile
  print x
  B.writeFile stateFile x

This works for Prelude and ByteString when taking 5 (there are
exactly 4 bytes in "1word32.bin") and fail when taking 4.

I'm not sure that this behavior is so bad..  there might be some
advantages...  but it might be nice to have it close after the last
byte is read...

However, I think probably the real blame here should probably go
to Data.Binary which doesn't attempt to check that it has consumed
all of its input after doing a "decode".  If "decode" completes
and there is unconsumed data, it should probably raise an error
(it already raises errors for premature EOF).  There's no reason
for it not to, since it does not provide the unconsumed data to
the caller when its done, anyway...

Thoughts?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-13 Thread Tim Newsham

Ah, that would be a bug in older ByteString implementations, that were a
bit incautious about closing handles. This example works for me with

   bytestring-0.9.1.0


Yup, thank you Don and Duncan for pointing this out.  I updated
my bytestring library and the test case no longer fails.  However,
I'm still having problems and not sure why.  I was able to
distill the problem down to this:

  $ od -x 1word32.bin
  000  05002ca4

  $ runhaskell test6.hs
  loading...
  saving...
  test6.hs: 1word32.bin: openFile: resource busy (file is locked)

  $ cat test6.hs
  module Main where
  import Control.Applicative
  import Control.Parallel.Strategies (rnf, NFData, using)
  import Data.Binary
  import qualified Data.ByteString.Lazy.Char8 as B
  import Data.Word

  stateFile = "1word32.bin"

  loadState :: IO Word32
  loadState = decode <$> B.readFile stateFile

  saveState :: Word32 -> IO ()
  saveState db = B.writeFile stateFile $ encode db

  {-
  -- Works!
  loadState = B.readFile stateFile
  saveState = B.writeFile stateFile
  -}

  -- force x = print x >> return x
  force = return . (`using` rnf)

  main = do
  putStrLn "loading..."
  d <- force =<< loadState
  putStrLn "saving..."
  saveState d


I tried this both with "print" and "rnf" to the same effect.
It looks like there still might be some situations where the
file isn't being closed?

Should the file be closed when the last byte is read (in this
case its definitely reading all four bytes) or when the first
byte after that is read (in this case it probably doesn't
attempt to read more than 4 bytes)?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-12 Thread Tim Newsham

I'm starting to wonder if this isn't an issue with
Data.ByteString.Lazy.Char8.{read,write}File.


This simple test case fails:

  module Main where
  import qualified Data.ByteString.Lazy.Char8 as B
  main = do
  print =<< B.readFile "xxx"
  B.writeFile "xxx" =<< B.readFile "test.hs"

If you replace B.readFile with readFile and B.writeFile with writeFile
it works properly.  ByteString bug?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-12 Thread Tim Newsham

You might have to force the last value of the alist that the map gets
flattened into, since otherwise there's no guarantee that it will be
read.

You really, really want to be using rnf for this job, instead of
turning your brain into a pretzel shape.


*nod* that's my eventual goal but I'd like to make sure I understand
what is going on here first and rule out any bugs before I go using
some class I'm not that familiar with.

I'm starting to wonder if this isn't an issue with
Data.ByteString.Lazy.Char8.{read,write}File.  I am now printing
out the data entirely:

d <- decode <$> B.readFile stateFile
print d

and I still get the same error when I go to writeFile later.
There should be no data items in any of my structures that
the print statement does not force.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-12 Thread Tim Newsham

Doesn't Data.Map.size run in O(1) time? Maybe something like using
different encodings for big maps in the default implementation would
help?


ugh, of course.  Ok, so I fixed it to:

loadState db = do
d <- decode <$> B.readFile stateFile
let force = sum $ map (sum . map fromEnum . M.keys) $ M.elems d
print force
force `seq` atomically $ writeTVar db d

(my keys are dates, which are Enum).  This should look at
every key in every inner map.  Shouldn't that be sufficient to
force the entire data set (or do I have to touch the fields in the
data elements too?).  I still get the same error condition.


Felipe.


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-12 Thread Tim Newsham

Maybe it makes sense to have the streamble list instance in Binary as
well, with some examples?


A flexible format that doesn't sacrifice too much space efficiency
would be to encode in chunks of up to 255 elements:

 Chunk = {
length :: Word8
elems :: [Elem]  --  0..255 repetitions
  }
 Chunks = [Chunk] -- terminated with the first 0 length Chunk

streamable, amortized cost is about 1/256th of the length, and
the encoding is much more efficient than the current scheme
for short lists (like most strings).  Currently a string "foobar"
is 8 bytes for length and 7 for the actual string.


-- Don


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-12 Thread Tim Newsham

On Tue, 12 Aug 2008, Bryan O'Sullivan wrote:


On Tue, Aug 12, 2008 at 5:34 PM, Tim Newsham <[EMAIL PROTECTED]> wrote:


I tried to force the data with:

   loadState db = do
   d <- decode <$> B.readFile stateFile
   let force = sum $ M.elems $ M.size `fmap` d
   force `seq` atomically $ writeTVar db d

and I get the same error when trying to writeFile after doing
a loadState.


What happens if you simply print the number of elements in the map?
Forcing its spine is all you should need.


This is what the sum above does.  Its a Map of Maps, so this maps
M.size over the outter Map and sums the resulting elements.
That should touch every map element, at least.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-12 Thread Tim Newsham

  Log: savedState.bin: openFile: resource busy (file is locked)

this does not occur if the program wasnt loaded.  My best guess here
is that B.readFile isnt completing and closing the file for some
reason.  Is there a good way to force this?


Lazy IO. So force the result to be evaluated, and then close the handle,
or use strict bytestring reading.


There is no visible handle.  It's all hidden in readFile.
I will try forcing the data.


I tried to force the data with:

loadState db = do
d <- decode <$> B.readFile stateFile
let force = sum $ M.elems $ M.size `fmap` d
force `seq` atomically $ writeTVar db d

and I get the same error when trying to writeFile after doing
a loadState.


-- Don


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-12 Thread Tim Newsham

so that fromAscList's the result of parsing the map as a list, via,

   instance Binary a => Binary [a] where
   put l  = put (length l) >> mapM_ put l
   get= do n <- get :: Get Int
   replicateM n get

so that's a length-prefixed list, strictly. Which is possibly where the
stack's being consumed. Does just bumping the stack size a bit help?


ugh.. length prefix..
I could bump the stack size to fix my immediate situation, but my goal
is to have a server with a huge in-memory data set, and my test data
so far is quite small.


Alternatively, you could consider serialising the Map in some other
format (i.e. newtype the list, and serialise that say, in a lazy/chunked
encoding).


hackery :(
but that sounds like the obvious fix.


  Log: savedState.bin: openFile: resource busy (file is locked)

this does not occur if the program wasnt loaded.  My best guess here
is that B.readFile isnt completing and closing the file for some
reason.  Is there a good way to force this?


Lazy IO. So force the result to be evaluated, and then close the handle,
or use strict bytestring reading.


There is no visible handle.  It's all hidden in readFile.
I will try forcing the data.


-- Don


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] two problems with Data.Binary and Data.ByteString

2008-08-12 Thread Tim Newsham

I have a program that read in and populated a large data structure and
then saved it out with Data.Binary and Data.ByteString.Lazy.Char8:

   saveState db = B.writeFile stateFile =<<
   encode <$> atomically (readTVar db)

when I go to read this in later I get a stack overflow:

loadState db = do
d <- decode <$> B.readFile stateFile
atomically $ writeTVar db d

  Stack space overflow: current size 8388608 bytes.
  Use `+RTS -Ksize' to increase it.

or from ghci:

d <- liftM decode
  (Data.ByteString.Lazy.Char8.readFile
 "savedState.bin") :: IO InstrsDb

fromList *** Exception: stack overflow

The data type I'm storing is a Map (of maps):

   type DailyDb = M.Map Date Daily
   type InstrsDb = M.Map String DailyDb

What's going on here?  Why is the system capable of building and saving
the data but not in reading and umarhsalling it?  What is the proper way
to track down where the exception is happening?  Any debugging tips?

I also noticed another issue while testing.  If my program loads
the data at startup by calling loadState then all later calls to
saveState give an error:

  Log: savedState.bin: openFile: resource busy (file is locked)

this does not occur if the program wasnt loaded.  My best guess here
is that B.readFile isnt completing and closing the file for some
reason.  Is there a good way to force this?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] code review? store server, 220loc.

2008-08-05 Thread Tim Newsham

On Sat, Aug 2, 2008 at 10:13 PM, Tim Newsham <[EMAIL PROTECTED]> wrote:

  http://www.thenewsh.com/%7Enewsham/store/Server5.hs


You should try profiling this. I can see a few possible problems (such
as reading String from a socket, instead of a ByteString), but it's
difficult to predict what might be causing your code to be so slow.
Haskell code ought to be much more competitive with C for an
application like this.


Profiling didn't turn up anything obvious:
  http://www.thenewsh.com/~newsham/store/Server9.prof

one thing I dont quite understand is that it seems to be crediting
more time to "put8" and "get8" than is warranted, perhaps all of
the "get" and "put" functions...

One suprising result from testing:
  http://www.thenewsh.com/~newsham/store/TestBin.hs

shows that the Data.Binary marshalling is actually very fast, but
when I want to add a length field at the start of the buffer it
has a huge impact on performance.  I've tried several variations without
much luck...  (also the third test case is very odd in that skipping
a conversion to strict bytestring actually makes it slower(!)).

soo... I think thats probably one of the things limiting my performance.
Another one is probably my need to do two reads (one for length one
for the data) for each received record... I think with some trickiness
I could get around that (since recv will return only as many bytes as
are immediately available) but I don't know that its worth the effort
right now

Anyway, any thoughts, especially on how to make the bytestring operations
faster, would be appreciated.

Tim Newsham
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] code review? store server, 220loc.

2008-08-04 Thread Tim Newsham

You should try profiling this. I can see a few possible problems (such
as reading String from a socket, instead of a ByteString), but it's
difficult to predict what might be causing your code to be so slow.
Haskell code ought to be much more competitive with C for an
application like this.


I haven't tried profiling yet, I should do that (ugh, will prob
have to rebuild some libraries I'm using to support that).

Anyway, I haven't yet used any ByteString IO functions.  I ran
some tests when I was starting and it seems that using Handle IO
functions was a bit slower than using the Socket IO functions directly.
It looks like there are a bunch of Handle IO functions that can
return ByteStrings but I don't see any for sockets...  Are there any?
If not, I suspect it will be a wash switching to Handles and ByteStrings
(especially since most of my requests and responses are quite small).

I'll write up some tests to see how well those perform..

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] code review? store server, 220loc.

2008-08-03 Thread Tim Newsham

What kind of performance do you actually need? Can your network
connection actually sustain the bandwidth of your synthetic benchmarks?


This is just an exercise at the moment, so no particular performance
goal beyond "how fast can it go".


(tested using apache-bench, loopback interface, amd64 @ 2.2GHz)
With cached content 450k:
with 1 concurrent client:
   760 requests per second
   ~1ms latency
   34Mb/s

[...]

Obviously this is testing with a loopback network. My point is, it's
serving at a rather higher rate than most real network connections I
could buy (except local ethernet networks).


My requests and responses are fairly small, a typical request is 29bytes
and a typical response is 58bytes.  If you just count these payloads
its about 390kB/sec for 4.5kreq/sec and 1.2MB/sec for 13.5kreq/sec
(of course its more like double these as the TCP overhead will be
about the same size).  Anyway, with such small sizes, the performance
shouldn't be limited by the bandwidth (I dont think).  If this was
a back-end storage server, the network probably wouldn't be the
limiting factor.


Duncan


Tim Newsham
http://www.thenewsh.com/~newsham/___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] code review? store server, 220loc.

2008-08-03 Thread Tim Newsham

newsham:

Anyone interested in critiquing some code?  I'm looking for ideas
for making it faster and/or simpler:


What optimisation and runtime flags did you use (-threaded or not?)


currently "ghc -O --make $< -o $@".  For some measurements I tried
-threaded which seemed to have a slight slowdown and +RTS -N2 at
runtime which didnt seem to help.  I also ran some tests with
multiple clients running concurrently, and it seemed to handle them
at approximately the same rate with and without the threaded and
RTS flags (on an amd64x2).  Those flags should have allowed it to
handle two client connections (via forkIO) concurrently, right?

[ps: the same web directory has test clients and other versions of
the server.]

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] code review? store server, 220loc.

2008-08-02 Thread Tim Newsham

Anyone interested in critiquing some code?  I'm looking for ideas
for making it faster and/or simpler:

   http://www.thenewsh.com/%7Enewsham/store/Server5.hs

This is an exercise to see how well a server in Haskell would perform.
My goals are roughly:
- retargetability to other server types (ie. easy to
  replace request and response structures and business logic).
- readability.
- performance.

My measurements show that a simple dummy server (accept, forkio,
recv byte) handles roughly 7500 requests/connects per second,
the server/client that do real messages do about 4500 req and
connections per second.  If all requests are on the same connection
one after another it does about 13500 requests/second.  For
comparisons, a C ping-pong server does about 3600/second if
it has to fork for each new connection/request, and about 35000/sec
if its all on the same connection.  So it seems at least competitive
with a forking C server.  I havent tested threaded C servers.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] ghc socket weirdness

2008-07-24 Thread Tim Newsham

FreeBSD/7.0 amd64:

GHCi, version 6.8.2: http://www.haskell.org/ghc/  :? for help
Loading package base ... linking ... done.
Prelude> :module +Network
Prelude Network> listenOn $ PortNumber 8765
Loading package parsec-2.1.0.0 ... linking ... done.
Loading package network-2.1.0.0 ... linking ... done.
*** Exception: getAddrInfo: does not exist (servname not supported for 
ai_socktype)


(same error when compiled).

Anyone seen this before?  I have multiple NICs, could that be
confusing listenOn (does it not just bind on 0.0.0.0?)

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Gtk2Hs and GCs

2008-06-18 Thread Tim Newsham

I don't see a way to fetch an existing standard GC from a widget.
In other Gtk bindings I usually do this by fetching the widget's
style and then grabbing one of the gc's (such as fg_gc[STATE_NORMAL]).
In Gtk2Hs docs:
http://www.haskell.org/gtk2hs/docs/gtk2hs-docs-0.9.12/Graphics-UI-Gtk-General-Style.html
it looks like you can only get Colors, not the whole GC.
I can't seem to find any other way short of making a whole new GC
(as is done in Gtk2Hs/demos/graphic/Drawing.hs).  Am I missing
something?  Is there a reason the GC's arent retrievable?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] re: very hard to build darcs with win32 ghc-6.8.2!

2008-06-05 Thread Tim Newsham

Here's the wrapup, thanks to those who replied:

  - the haskell zlib package on hackage no longer requires that zlib
(the C library) be prebuilt.  It includes sources itself and
builds and installs them using Cabal.
  - the haskell zlib package is not used by darcs.  It links against
libz.a directly.  You do need to have libz.a somehow to build
darcs.
  - the darcs link error with "SleepEx" is caused because it uses
"foreign import ccall" when it should use "foreign import stdcall".
Fixing the decl in src/win32/System/Posix.hs to stdcall fixes
this issue.

I still think its odd that ghc's "gcc" is not very useable outside
of Cabal, but in this case it has no bearing on the zlib package.
If you choose to build "libz.a" (the C library) from sources using
this gcc it will be hard, but you could also get it from an external
source (such as the prebuilt libcurl library package).

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] very hard to build darcs with win32 ghc-6.8.2!

2008-06-04 Thread Tim Newsham

I built darcs for win32 recently and it was much more difficult than
it should be.  Probably most of the blame goes to ghc-6.8.2 binary
release for win32.  Half of the effort is getting the zlib prereq
working.

Previously to build zlib for win32 ghc I did the following:
http://www.haskell.org/pipermail/haskell-cafe/2007-March/023059.html

However, now, the gcc binary for ghc-6.8.2 does not work as well as
I would like which requires a bit more effort:

- It did not automatically add mingw headers during compilation, and
  to fix this I had to force some extra flags.  I built a shell script
  "xcc":

  #!/bin/sh
  GHC=/ghc/ghc-6.8.2
  PATH=/c$GHC/gcc-lib:$PATH
  export PATH
  /c$GHC/gcc -I $GHC/include -I $GHC/include/mingw \
 -I $GHC/gcc-lib/include -L $GHC/gcc-lib "$@"

- During linking it did not find crt2.o and adding it to PATH and
  -L did not help, so I just copied wholesale all of
  /c/ghc/ghc-6.8.2/gcc-lib into my zlib source directory.

- At this point I was able to build with:
  CC=./xcc ./configure --prefix=/c/ghc/ghc-6.8.2 \
   --libdir=/c/ghc/ghc-6.8.2
  make
  make install

Why is the gcc in ghc's directory so non-functional?

Ok, so with zlib (the C library) installed, the zlib haskell package
installs properly.  Dependency resolved.

Next, to build darcs I had to configure it without libcurl support
(or alternately spend time chasing down that dep, pass for now). 
Using cygwin I ran "./configure" which falsely uses the cygwin gcc

for configuration checks, but since gcc is never used directly during
the compilation process, that doesn't matter that much.  I could have
tried the "xcc" trick here again, but didn't bother.  I ran into
two problems during the build:

- -Werror is specified in the GNUMakefile and there are many warnings.
  I just removed -Werror for now.

- During linking it was not able to resolve "SleepEx" from
  src/win32/System/Posix.hs.  I could not figure out what is going
  on here.  I tried adding "-lkernel32" and "-L /ghc/ghc-6.8.2/gcc-lib
  -Lkernel32" to the Makefile and it still did not work even though
  /ghc/ghc-6.8.2/gcc-lib/libkernel32.a has [EMAIL PROTECTED] defined(!)
  Finally I bit the bullet and hacked around this by noticing that
  mingw headers have _sleep() defined.  I replaced the code in Posix.hs
  with:

  foreign import ccall "_sleep" c_sleep :: CULong -> IO ()

  sleep :: Integer -> IO CInt
  sleep n = c_sleep (fromIntegral n) >> return (toEnum $ fromIntegral n)

At this point darcs builds and the binary seems to work (so far).
I don't know the implication of my sleep hack (which doesn't return
the actual time slept).

Here's a small test program which uses FFI to SleepEx which I was
not able to get working with win32 ghc-6.8.2.

--
{-# OPTIONS -fglasgow-exts -fffi #-}
module Main where
import Foreign.C.Types

foreign import ccall "SleepEx" c_SleepEx :: CUInt -> CInt -> IO CInt

main = do
putStrLn "start"
n <- c_SleepEx (2*1000) 1
print n
---

So, what is going on with ghc-6.8.2?  Why is the gcc so hard to use
now?  Why can't I get FFI working with standard win32 functions?
Why aren't there prebuilt win32 darcs binaries anymore?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] reordering pure bindings in monads

2008-05-29 Thread Tim Newsham

Intuitively it seems like the applicative expression:

  (++) <$> getLine <*> getLine

should represent the same thing as the more traditional liftM2 
expressions:


  do { x <- getLine; y <- getLine; return ((++) x y) }

but it seems to me that you cant directly manipulate the first into
the second.  I get:

  do x2' <- getLine
 x1 <- return ((++) x2')
 x2 <- getLine
 return (x1 x2)

the only way I can get from here to the liftM2 definition is if I
treat "x1 <- return ((++) x2')" as "let x1 = (++) x2", and then
allow it to be reordered after the second getLine.  Then it is
straightforward to reduce to the liftM2 expression above.

It seems to me that this is a valid transformation if:
   - no side effects, including pattern match errors, can occur
 in the let (or x1 <- return ...).
   - movement doesnt change the dependencies
 - x1 isnt used between the original line and its new position
 - there are no new bindings for x2' introduced between the original
   line and the new line.

Did I overlook anything?  Do any haskell implementations allow rewrites
like these to occur?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] A mini haskell (in 244 lines of python)

2008-03-02 Thread Tim Newsham

For education and fun I wrote a small untyped non-strict lambda
calculus evaluator in python.  One of the goals was to keep it
fairly small and simple, and to do most of the work in the implemented
scripting language itself.  For that reason, I added macros to allow
things like "let" and "letrec" to be defined as syntactic sugar
easily outside of the evaluation engine itself.

The result is 244 lines of python, a small prelude that implements
tuples, lists and the state monad, and some small example scripts.
The prelude and scripts are heavily influenced by Haskell, the main
differences being a much simpler syntax, lack of pattern matching
and lack of a type system.  Data structures aren't supported but
are implemented fairly easily using lambda expressions as described
in

http://www.cs.nott.ac.uk/~nhn/TFP2006/Papers/03-JansenKoopmanPlasmeijer-EfficientInterpretation.pdf

This is all available at

   http://www.thenewsh.com/%7Enewsham/lambda/

as extracted package and .tgz.  The README file has documentation
including small examples.  Accompanying scripts provide more
complete examples, such as:

  [WITHLIST
[LET from2 (iter (add 1) 2)
[LET primes (nubBy (\x \y (eq (mod y x) 0)) from2)
  (traceList Val (take 10 primes))
]]]

which calculates the first 10 primes.

Exercise to the reader: I bet the evaluator could all be written much more 
compactly in Haskell.


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] strange GHC assembler failure

2008-02-02 Thread Tim Newsham

I'm getting a weird build error:
[ 9 of 95] Compiling Plugin.Pl.Common ( Plugin/Pl/Common.hs, 
dist/build/lambdabot/lambdabot-tmp/Plugin/Pl/Common.o )

/tmp/ghc52608_0/ghc52608_0.s: Assembler messages:

/tmp/ghc52608_0/ghc52608_0.s:36:0:  Error: unassigned file number 1
[... more of these ...]

I narrowed this down -- this happens when I add my new library
"silc-client" to the "Build-depends:" line in the cabal file even
if none of its code is referenced.  Removing the dependency makes
the error go away.  The module I'm referencing is a new one I'm
still working on and it makes use of FFI and references external
headers and libraries.
(I put a copy at http://www.thenewsh.com/~newsham/silc-client.tgz
if it helps anyone debug..  this is not release-quality code
though).

Any idea what is going on here?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] weird behavior with FFI

2008-02-02 Thread Tim Newsham

Am Samstag, 2. Februar 2008 schrieb Tim Newsham:

I am working on haskell bindings to C functions using FFI.  I have
a callback function that returns "IO ()".  When I pass in the callback
function:



I suspect this has to do with printf returning 'undefined' if you use it
with an IO type. Something in the code looks at the result and crashes.
Your second version is equivalent to printf "foo" >>= \_ -> return (),
i.e. it never evaluates printf's result but returns () instead.
Fixing the first version would require some changes to Text.Printf,
restricting the 'a' in PrintfType (IO a).


But the callback function is already of type "IO ()" as mentioned above.


HTH, Lukas


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] weird behavior with FFI

2008-02-02 Thread Tim Newsham

I am working on haskell bindings to C functions using FFI.  I have
a callback function that returns "IO ()".  When I pass in the callback
function:
foo = printf "foo"

it crashes (is there an easy way to debug this exception using ghc6.8.2?)
bot: SilcClient_d1al: uncaught exception

however, if I pass in the callback function:
foo = do
printf "foo"
return ()

it does not crash.  Is this a bug in my bindings?  In ghc/ffi?
Full code is at:
   http://www.thenewsh.com/%7Enewsham/silcbot.tgz

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO is a bad example for Monads

2007-12-11 Thread Tim Newsham
I haven't been following this thread closely, but would it be rude to suggest 
that someone who doesn't want to put the effort into learning the (admittedly 
difficult) concepts that Haskell embodies shouldn't be using the language? 
Haskell was never intended to be The Next Big Popular Language.  It was 
intended to be a purely functional language for people who want to use purely 
functional languages and who are willing to learn new concepts if it enables 
them to program in that  style.


This is at odds with the notion, popular on this list and other
haskell forums, that pure functional programming is the future.

Why is it that every time the topic of teaching basic concepts in
an easier way comes up there are always two or three replies that
say "should we bother?  lets filter out the idiots?"  These are
pointless and counterproductive.  Whether or not you like the idea
of lesser entities sullying your private, pure, functional programming
language, there are going to be a lot more people learning this
language, and there will be people trying to make it easier for them
to learn it.

whatever.  That said, of course we should strive to have better teaching 
materials, but there are a number of good IO/monad tutorials on the web.

[...]
because it enables us to write programs more effectively (in many cases, at 
least) than we can in other languages, but the learning curve is steep -- 
there ain't no such thing as a free lunch.


Many of the best resources for learning Haskell are still academic
papers published by language researchers.   We've still got a long
long way to go...  Sure there's no shortcut to learning difficult
concepts, but right now its more of a nature hike than a freeway...


Mike


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] do

2007-12-03 Thread Tim Newsham

Probably one should understand how to use monads before worrying about
the do-notation.  Here are some references:


I don't totally agree.  You can teach monads to beginners just fine
using the do-notation.  Unsuprisingly its very much like teaching
monads using bind.  You describe a two line do-block as the basic
building block for combining two actions into a single action:

do {
result1 <- act1
expr involving result1 building an act
}

show that you can nest them (expr can be another do block)

do {
result1 <- act1
do {
result2 <- act2
expr involving result1 and result2 building an act
}
}

and how the do-notation doesn't require you to start a new do-block
for nesting of do's and let's

   do {
   result1 <- act1
   let val1 <- expr resulting in a pure value
   result2 <- act2
   expr involving result1 and result2 building an act
   }

Then you can describe pattern matching and fail...

I've had debates about what should be taught, and obviously not
everyone agrees, but at the least, its possible and reasonable
and understandable to teach do-notation first.


 Denis


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] binary operator modifiers

2007-11-19 Thread Tim Newsham

liftM2 (/) sum length.  Anyway, the closest you can get in Haskell is
something like this, using the infix expressions of Ken Shan and Dylan
Thurston<http://www.haskell.org/pipermail/haskell-cafe/2002-July/003215.html>


Hmm.. that might be decent if you added rules to pretty-print them in 
lhs2tex.  The src code would be slightly messy but the formatted code would 
be very clean.  And it opens the doors for other binop decorators. 
Interesting idea.


I finally get my lhs2tex set up and put together a better example
of what I was talking about:

  http://www.thenewsh.com/%7Enewsham/Hats.pdf

Though I don't know if you can coax lhs2tex into accepting something like

  %format -:liftM2 (+):-   =  "\widehat{+}"

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Why are OCaml and Haskell being used at these companies?

2007-11-13 Thread Tim Newsham

Functional programming languages are now much more widely used in industry,
primarily because they offer substantial productivity improvements (roughly
10x) over C++ and Java and, consequently, are much more cost effective.


Do you have any references for this?


Dr Jon D Harrop, Flying Frog Consultancy Ltd.
http://www.ffconsultancy.com/products/?e


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] generating Maybe

2007-11-07 Thread Tim Newsham

Data.Maybe has functions for processing Maybe's but nothing useful
for creating maybe.  I think the following would be a very useful
addition, a guarded function:

guarded :: (a -> Bool) -> (a -> b) -> a -> Maybe b
guarded p f x | p x   = Just (f x)
  | otherwise = Nothing

such a function in the std libs would make functions like "unfoldr"
more attractive -- uses of foldr nearly always encapsulate this
notion.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Standalone PNG module?

2007-11-07 Thread Tim Newsham

Peter Verswyvelen wrote:


I would like to load 32-bit images (RGB+alpha) for use with GLUT/OpenGL.


I know GTK2HS has support for loading images, but does a standalone Haskell 
(wrapper) module exists for loading images?


See the message "PNG files" by Tim Newsham, sent to haskell-cafe on the 30th 
of october.


The code I wrote is onthe wiki at:
http://www.haskell.org/haskellwiki/Library/PNG

However, it does not load files, it generates files, and monochrome ones
at that.  Loading files would be slightly harder since you'd have
to support (or at least test for) more options, but the format isn't
that complicated.


Reinier


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: Why can't Haskell be faster?

2007-11-01 Thread Tim Newsham

Unfortunately, they replaced line counts with bytes of gzip'ed code --
while the former certainly has its problems, I simply cannot imagine
what relevance the latter has (beyond hiding extreme amounts of
repetitive boilerplate in certain languages).


Sounds pretty fair to me.  Programming is a job of compressing a solution 
set.  Excessive boilerplate might mean that you have to type a lot, but 
doesn't necessarily mean that you have to think a lot.  I think the 
previous line count was skewed in favor of very terse languages like 
haskell, especially languages that let you put many ideas onto a single 
line.  At the very least there should be a constant factor applied when 
comparing haskell line counts to python line counts, for example. 
(python has very strict rules about putting multiple things on the same 
line).


Obviously no simple measure is going to satisfy everyone, but I think the 
gzip measure is more even handed across a range of languages.  It probably 
more closely aproximates the amount of mental effort and hence time it 
requires to construct a program (ie. I can whip out a lot of lines of code 
in python very quickly, but it takes a lot more of them to do the same 
work as a single, dense, line of haskell code).



When we compete against Python and its ilk, we do so for programmer
productivity first, and performance second.  LOC was a nice measure,
and encouraged terser and more idiomatic programs than the current
crop of performance-tweaked low-level stuff.


The haskell entries to the shootout are very obviously written for speed 
and not elegance.  If you want to do better on the LoC measure, you can 
definitely do so (at the expense of speed).



-k


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] binary operator modifiers

2007-10-31 Thread Tim Newsham

liftM2 (/) sum length.  Anyway, the closest you can get in Haskell is
something like this, using the infix expressions of Ken Shan and Dylan
Thurston<http://www.haskell.org/pipermail/haskell-cafe/2002-July/003215.html>
:

[]


It works (?), but it's pretty ugly and hardly seems worth it, unfortunately.


Hmm.. that might be decent if you added rules to pretty-print them in 
lhs2tex.  The src code would be slightly messy but the formatted code 
would be very clean.  And it opens the doors for other binop decorators. 
Interesting idea.



-Brent


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] PNG files

2007-10-29 Thread Tim Newsham
I needed something small for writing out png files and didn't see 
anything, so I wrote my own.  It's not really large or general enough yet 
to warrant a full package.  It wouldn't require much work to support other 
variant formats, such as color.


 Png.hs 
{-
A small library for creating monochrome PNG files.
This file is placed into the public domain.
Dependencies: Zlib.
-}
module Png (png) where
import Data.Array
import Data.Bits
import Data.List
import Data.Word
import qualified Codec.Compression.Zlib as Z
import qualified Data.ByteString.Lazy as B

be8 :: Word8 -> B.ByteString
be8 x = B.singleton x

be32 :: Word32 -> B.ByteString
be32 x = B.pack [fromIntegral (x `shiftR` sh) | sh <- [24,16,8,0]]

pack :: String -> B.ByteString
pack xs = B.pack $ map (fromIntegral.fromEnum) xs

unpack :: B.ByteString -> String
unpack xs = map (toEnum.fromIntegral) (B.unpack xs)

hdr, iHDR, iDAT, iEND :: B.ByteString
hdr = pack "\137\80\78\71\13\10\26\10"
iHDR = pack "IHDR"
iDAT = pack "IDAT"
iEND = pack "IEND"

chunk :: B.ByteString -> B.ByteString -> [B.ByteString]
chunk tag xs = [be32 (fromIntegral $ B.length xs), dat, be32 (crc dat)]
where dat = B.append tag xs

-- | Return a monochrome PNG file from a two dimensional bitmap
-- stored in a list of lines represented as a list of booleans.
png :: [[Bool]] -> String
png dat = unpack $ B.concat $ hdr : concat [ihdr, imgdat, iend]
where height = fromIntegral $ length dat
  width = fromIntegral $ length (head dat)
  ihdr = chunk iHDR (B.concat [
be32 width, be32 height, be8 1, be8 0, be8 0, be8 0, be8 
0])

  imgdat = chunk iDAT (Z.compress imgbits)
  imgbits = B.concat $ map scanline dat
  iend = chunk iEND B.empty

scanline :: [Bool] -> B.ByteString
scanline dat = 0 `B.cons` bitpack dat

bitpack' :: [Bool] -> Word8 -> Word8 -> B.ByteString
bitpack' [] n b = if b /= 0x80 then B.singleton n else B.empty
bitpack' (x:xs) n b =
if b == 1
then v `B.cons` bitpack' xs 0 0x80
else bitpack' xs v (b `shiftR` 1)
where v = if x then n else n .|. b

bitpack :: [Bool] -> B.ByteString
bitpack xs = bitpack' xs 0 0x80

crc :: B.ByteString -> Word32
crc xs = updateCrc 0x xs `xor` 0x

updateCrc :: Word32 -> B.ByteString -> Word32
updateCrc = B.foldl' crcStep

crcStep :: Word32 -> Word8 -> Word32
crcStep crc ch = (crcTab ! n) `xor` (crc `shiftR` 8)
where n = fromIntegral (crc `xor` fromIntegral ch)

crcTab :: Array Word8 Word32
crcTab = array (0,255) $ zip [0..255] $ flip map [0..255] (\n ->
foldl' (\c k -> if c .&. 1 == 1
  then 0xedb88320 `xor` (c `shiftR` 1)
  else c `shiftR` 1) n [0..7])

___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] binary operator modifiers

2007-10-28 Thread Tim Newsham

I would love to have the ability to define binary operator modifiers.
For example:

  f \overline{op} g   = liftM2 op f g
  f \overleftarrow{op} n  = liftM2 op f (return n)
  n \overrightarrow{op} g = liftM2 op (return n) f
  \widehat{f} x   = liftM f x

so that for example you could define functions like:

   (*3) \overline{+} (/2)

and

   3 \overrightarrow{+} \widehat{read} getContents

Obviously you could write this out the long way:

   liftM2 (3+) $ liftM read getContents

or go through the trouble of defining a bunch of binops

   f <+> g = liftM2 (+) f g
   n +>  g = return n <+> g
   f <+  n = f <+> return n
   read' = liftM read

   (*3) <+> (/2)
   3 +> read' getContents

but doing this for more than one or two operators gets tedious
quickly...

Is there any way in Haskell to modify binops in this way and still
be able to use them infix?  If not, has anyone considered supporting
strange syntaxes like this?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] viewing HS files in Firefox

2007-10-28 Thread Tim Newsham
When I try to go to one of the Module.hs files, e.g. on darcs.haskell.org, it 
now has type HS and Firefox refuses to display it (and only lets me download 
it).  Does anyone know how to make Firefox treat certain file types as others 
(HS as plain text, in particular)? so that I can browse them with any 
convenience


In Windows what I do is save the file on the desktop when it asks you to 
save it.  Then right-click the file and select "open with" and choose 
"wordpad" to open it with.  Check the box "open with this application 
every time".  Now close it and go back to your browser and click on the 
file.  It should now open up in wordpad each time.  At least that is

the behavior in IE.


Thanks,
Isaac


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Tutorial: Curry-Howard Correspondence

2007-10-18 Thread Tim Newsham

I'm fairly new to this and struggling to follow along so I might
be a little off base here...

I assume you mean then that it is a valid proof because it halts for *some* 
argument? Suppose I have:


thm1 :: (a -> a) -> a
thm1 f = let x = f x in x

There is no f for which (thm1 f) halts (for the simple reason that _|_ is the 
only value in every type), so thm1 is not a valid theorem.


Now we reify our propositions (as the tutorial does) in a constructor:

data Prop a = Prop a

thm2 :: (Prop a -> Prop a) -> Prop a
thm2 f = Prop undefined

fix :: (p -> p) -> p
fix f = let x = f x in x

instance Show (Prop a) where
 show f = "(Prop )"

*Prop> :t thm2
thm2 :: (Prop a -> Prop a) -> Prop a

*Prop> thm2 (fix id)
(Prop )

Wow! thm2 halts. Valid proof. We have a "proof" (thm2 (fix id)) of a 
"theorem" (((Prop a) -> (Prop a)) -> (Prop a)), assuming that can somehow be 
mapped isomorphically to ((a -> a) -> a), thence to intuitionist logic as ((a 
=> a) => a).


The function needs to be total.  You seem to be using Haskell to execute a 
function to see if it terminates as a proof of totality.  Is that fair? 
This approach might work for some simple examples, but if the function 
doesn't terminate immediately then what?  I would assume that proof of

totality would be an obligation of the person who constructed the
function.  Using Haskell to prove termination for some simple cases might
be fair (in which case I see your point about avoiding a non-lazy
constructor), but it doesn't seem to be very general anyway.  If you're
relying on the programmer to provide proof of totality, then I don't
see the harm in using "Prop a" instead of "a".

That "somehow" in the tutorial seems to be an implied isomorphism from Prop a 
to a, so that proofs about (Prop a) can be interpreted as proofs about a. I 
hope to have shown that unless without constructors strict in their arguments 
that this  is not valid.


My hypothesis was that

 data Prop a = Prop !a

justified this isomorphism. Or am I still just not getting it?


That would allow you to use the dynamic property (I observed termination)
to verify the static property (the function is total) in some situations,
right?  But the static property of totality shouldn't rely on evaluation
strategy, right?


Dan


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Tutorial: Curry-Howard Correspondence

2007-10-17 Thread Tim Newsham

Very clear tutorial indeed. But why isn't propCC shown as Pierce's
Law? And Excluded middle is proven on such basis.


Simply because I don't know that much about pierce's law.  I've
seen it mentioned a few times, but I'm not that familiar with it
yet and I haven't read a good treatment of it yet.  Do you have
any pointers to something I could read?


Vitaliy.


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Tutorial: Curry-Howard Correspondence

2007-10-17 Thread Tim Newsham

Slightly offtopic - I am curious about the use of forall in some type
signatures:


If you specify the "forall p q" at the top level then the types
used internally will use the same "p" and "q".  Otherwise the
internal types will be new "p"s and "q"s and wont line up with
the outer type declaration.


subsume :: forall p q r. Prop (p :=> q) -> Prop ((p :/\ q) :== p)
subsume pIMPq = equivInj (impInj pq2p) (impInj p2pq)
  where pq2p :: Prop (p :/\ q) -> Prop p
pq2p assumePQ = andElimL assumePQ
p2pq :: Prop p -> Prop (p :/\ q)
p2pq assumeP = andInj assumeP q
  where q = impElim assumeP pIMPq


There "r" type variable is mentioned, but it does not occur anywhere
else in the signature - what's the purpose of this construct?


Ahh!  "r" is a remnant of earlier iterations where I had carried
around the "r" in every CProp from the classical propositions.
Then I realized I could just pick any "r" (I picked "()") and avoid
having to type "r" everywhere.  So its no longer used, and I'll remove
it from the code and the paper.  Thank you!


Krzysztof Kościuszkiewicz
Skype: dr.vee,  Gadu: 111851,  Jabber: [EMAIL PROTECTED]
Mobile IRL: +353851383329,  Mobile PL: +48783303040
"Simplicity is the ultimate sophistication" -- Leonardo da Vinci



Tim Newsham
http://www.thenewsh.com/~newsham/___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Tutorial: Curry-Howard Correspondence

2007-10-16 Thread Tim Newsham

A tutorial on the Curry-Howard Correspondence in Haskell:
  http://www.thenewsh.com/%7Enewsham/formal/curryhoward/

Feedback appreciated.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell-curry, classical logic, excluded middle

2007-10-14 Thread Tim Newsham
Now that that works, one more question.  Is it possible to hide the "r" that 
is attached to every single type?  For example to do something like this 
(which doesn't compile):


No answer needed.  Duh.. I can just pick "r" to be any type (like "()").

I've got intuitionistic logic and classic logic in haskell types
now, using an identical interface/notation (ie. they're swappable
for proofs that don't need excluded-middle).  The interfaces use
infix type names that "read" similarly to their meanings:

logic:
  http://www.thenewsh.com/%7Enewsham/formal/curryhoward/IntLogic.hs
  http://www.thenewsh.com/%7Enewsham/formal/curryhoward/ClassLogic.hs
and example theorems:
  http://www.thenewsh.com/%7Enewsham/formal/curryhoward/IntTheorems.hs
  http://www.thenewsh.com/%7Enewsham/formal/curryhoward/ClassTheorems.hs

Should this go up on the wiki somewhere?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] haskell-curry, classical logic, excluded middle

2007-10-14 Thread Tim Newsham

On Sun, 14 Oct 2007, Roberto Zunino wrote:

(Warning: wild guess follows, I can not completely follow CPS ;-))
Adding a couple of forall's makes it compile:
propCC :: ((forall q . p -> Prop r q) -> Prop r p) -> Prop r p
func1 :: (forall q . Or r p (Not r p) -> Prop r q)
 -> Prop r (Or r p (Not r p))


Yup!  That did it, thanks!

Now that that works, one more question.  Is it possible to hide the "r" 
that is attached to every single type?  For example to do something like 
this (which doesn't compile):


  data Prop p = Prop (forall r. (p -> r) -> r)
  run :: Prop p -> (p -> r) -> r
  run (Prop f) k = f k
  propCC :: ((forall q. p -> Prop q) -> Prop p) -> Prop p
  propCC f = Prop (\k -> run (f (\a -> Prop (\k' -> k a))) k)


Zun.


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] haskell-curry, classical logic, excluded middle

2007-10-14 Thread Tim Newsham

I've been struggling with this for the last day and a half.  I'm
trying to get some exercise with the type system and with logic by
playing with the curry-howard correspondence.  I got stuck on
the excluded-middle, and I think now I got it almost all the way
there, but its still not quite right.  Is this error I'm getting
(inline at the end) easily fixed, and what exactly is going on?

 code ---
{-# OPTIONS_GHC -fglasgow-exts #-}
module Classic where
{-
Classic logic.  (See Intuit.hs first).
In this system propositions all take a continuation.  This allows
us to define the law of the excluded middle.
-}
import Control.Monad


-- propositions are functions taking a continuation.
data Prop r p = Prop ((p -> r) -> r)
run :: Prop r p -> (p -> r) -> r
run (Prop f) k = f k
propCC :: ((p -> Prop r q) -> Prop r p) -> Prop r p
propCC f = Prop (\k -> run (f (\a -> Prop (\k' -> k a))) k)
instance Monad (Prop r) where
return p = Prop (\c -> c p)
p >>= mkq = Prop (\c -> run p (\r -> run (mkq r) c))


data TRUTH = TRUTH
type FALSE r = Not r TRUTH
data And r p q = And (Prop r p) (Prop r q)
data Or r p q = OrL (Prop r p) | OrR (Prop r q)
data Imp r p q = Imp (Prop r p -> Prop r q)
data Equiv r p q = Equiv (Prop r p -> Prop r q) (Prop r q -> Prop r p)
data Not r p = Not (forall q. (Prop r p -> Prop r q))


-- Truth
truth :: Prop r TRUTH
truth = return TRUTH

-- And-Injection
-- P, Q |- P /\ Q
andInj :: Prop r p -> Prop r q -> Prop r (And r p q)
andInj p q = return (And p q)

-- And-Elimination, left and Right
-- P /\ Q |- P
andElimL :: Prop r (And r p q) -> Prop r p
andElimL pq = pq >>= \(And p q) -> p
-- P /\ Q |- Q
andElimR :: Prop r (And r p q) -> Prop r q
andElimR pq = pq >>= \(And p q) -> q

-- Or-Injection, left and right
-- P |- P \/ Q
orInjL :: Prop r p -> Prop r (Or r p q)
orInjL p = return (OrL p)
-- Q |- P \/ Q
orInjR :: Prop r q -> Prop r (Or r p q)
orInjR q = return (OrR q)

-- Or-Elimination.
-- P \/ Q, P -> R, Q -> R |- R
orElim :: Prop r (Or r p q) -> (Prop r p -> Prop r s) -> (Prop r q -> Prop r s) 
-> Prop r s
orElim pORq p2r q2r = pORq >>= byCases
  where byCases (OrL p) = p2r p
byCases (OrR q) = q2r q

-- Implication-Injection
-- (P |- Q) |- P -> Q
impInj :: (Prop r p -> Prop r q) -> Prop r (Imp r p q)
impInj p2q = return (Imp p2q)

-- Implication-elimination (modus ponen)
-- P, P -> Q |- Q
impElim :: Prop r p -> Prop r (Imp r p q) -> Prop r q
impElim p pIMPq = pIMPq >>= \(Imp p2q) -> p2q p

-- Equivalence-Injection
-- P -> Q, Q -> P |- P = Q
equivInj :: Prop r (Imp r p q) -> Prop r (Imp r q p) -> Prop r (Equiv r p q)
equivInj pIMPq qIMPp = do
(Imp p2q) <- pIMPq
(Imp q2p) <- qIMPp
return (Equiv p2q q2p)

-- Equivalence-Elimination, Left and Right
-- P = Q |- P -> Q
equivElimL :: Prop r (Equiv r p q) -> Prop r (Imp r p q)
equivElimL pEQq = pEQq >>= \(Equiv p2q q2p) -> return (Imp p2q)
equivElimR :: Prop r (Equiv r p q) -> Prop r (Imp r q p)
equivElimR pEQq = pEQq >>= \(Equiv p2q q2p) -> return (Imp q2p)

-- Absurdity
-- False |- P
absurd :: Prop r (FALSE r) -> Prop r p
absurd false = false >>= \(Not true2p) -> true2p truth

-- Not-Inj
-- (P |- False) |- ~P
notInj :: forall r p. (Prop r p -> Prop r (FALSE r)) -> Prop r (Not r p)
notInj p2false = return (Not p2any)
  where p2any :: forall q. Prop r p -> Prop r q
p2any assumep = absurd (p2false assumep)

-- Not-Elimination
-- P, ~P |- Q
notElim :: Prop r p -> Prop r (Not r p) -> Prop r q
notElim p np = np >>= \(Not p2any) -> p2any p


-- Excluded-Middle
-- P \/ ~P
exclMiddle :: forall r p. Prop r (Or r p (Not r p))
exclMiddle = propCC func1
  where func1 :: (Or r p (Not r p) -> Prop r q) -> Prop r (Or r p (Not r p))
-- k  :: Or r p (Not r p) -> Prop r q
func1 k = return (OrR (return (Not func2)))
  where func2 :: Prop r p -> Prop r q
func2 k' = k (OrL k')

{-
http://www.cse.ogi.edu/~magnus/mdo-callcc-slides.pdf
-- A \/ ~A
excmid :: Either a (a -> b)
excmid = callcc (\k. Right (\a.k (Left a)))
-}

{-
Classic2.hs:114:27:
Couldn't match expected type `q' (a rigid variable)
   against inferred type `q1' (a rigid variable)
  `q' is bound by the type signature for `func2'
at Classic2.hs:113:44
  `q1' is bound by the type signature for `func1'
at Classic2.hs:110:45
  Expected type: Prop r q
  Inferred type: Prop r q1
In the expression: k (OrL k')
In the definition of `func2': func2 k' = k (OrL k')
-}


-- False-Elimination
-- (~P |- False) |- P

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] New slogan for haskell.org

2007-10-11 Thread Tim Newsham

"Haskell -- You're probably not smart enough to understand it."


You are not expected to understand this.
   http://swtch.com/unix/

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Fusing foldr's

2007-10-11 Thread Tim Newsham

Just goofing around with arrows and foldr while reading Hutton's
excellent paper on folds (http://www.cs.nott.ac.uk/~gmh/fold.pdf).

Wondering if this can be done automatically and more generally?

module Main where
import Control.Arrow
import Data.List

-- sum and length expressed as foldr.
fsum = foldr (\n -> (+n)) 0
flen = foldr (\n -> (+1)) 0

-- compute average using arrows..
-- compute the sum of a list, compute the length, and do a divide.
-- this traverses the list twice using two foldrs.
avg1 = uncurry (/) . (fsum &&& flen)
avg2 = uncurry (/) . (foldr (\n -> (+n)) 0 &&& foldr (\n -> (+1)) 0)

-- But the two foldr's can be fused together
-- here we're mixing the two foldr constants 0 and 0 to (0,0)
-- and we're mixing the two functions (\n -> (+n)) and
-- (\n -> (+1)) to (\n -> (+n) *** (+1)).
avg3 = uncurry (/) . foldr (\n -> (+n) *** (+1)) (0, 0)

main = do
print $ avg1 [1,2,3,4]
print $ avg2 [1,2,3,4]
print $ avg3 [1,2,3,4]

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Extract source code from literate Haskell (LHS) files

2007-09-30 Thread Tim Newsham
This is of course very easy to do manually, but does a command line tool 
exist for extracting source code from literate Haskell files?


something like:
   sed -e '/^[^>]/d' -e 's/^>//g' < foo.lhs > foo.hs

the first expression deletes lines not starting with ">".  The
second expression removes the ">" at the beginning of each line.

or if you prefer to keep the comments:

   sed -e 's/^[^>]/-- /g' -e 's/^>//g' < foo.lhs > foo.hs

the first expression puts "-- " at the start of each line without
a ">".


Thanks,
Peter


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Rewriting filter with foldr

2007-09-30 Thread Tim Newsham

filter f = foldr (\x -> if (f x) then (x:) else id) []



That's one neat solution but it also raises a few questions for me:
foldr :: (a -> b -> b) -> b -> [a] -> b
yet you've managed to squeeze in a function that takes only one argument. How 
is this possible without GHCI blowing its top?


Someone already explained this so I'll skip it.

2. Could you please explain the role of the identity function (id) in your 
code? Where's its argument, or is it sort of implicitly noted? For example, 
is it the case that the second argument is held in reserve and passed to the 
first function which would take it, hence (x:) and id?


How about working through an example?
[I'm using notes on the left hand side.  a number starting
with a colon is a reference to a definition, and a word
followed by a close paren ")" is a justification for the step.]

1:  filter f = foldr (\x -> if (f x) then (x:) else id) []

2:  foldr k z xs = go xs
3: where go [] = z
4:   go (y:ys) = y `k` go ys

filter (> 3) [5,2,6]
1)   = foldr (\x -> if (> 3) x then (x:) else id) [] [5,2,6]
2)   = go [5,2,6]
   where
5:   go [] = []
6:   go (y:ys) = (\x -> if (> 3) x then (x:) else id) y (go ys)
6)   = (\x -> if (> 3) x then (x:) else id) 5 (go [2,6])
lambda)  = (if (> 3) 5 then (5:) else id) (go [2,6])
if)  = (5:) (go [2,6])
6)   = (5:) ((\x -> if (> 3) x then (x:) else id) 2 (go [6]))
lambda)  = (5:) (if (> 3) 2 then (2:) else id) (go [6]))
if)  = (5:) (id (go [6]))
id)  = (5:) (go [6])
6)   = (5:) ((\x -> if (> 3) x then (x:) else id) 6 (go []))
lambda)  = (5:) (if (> 3) 6 then (6:) else id) (go []))
if)  = (5:) ((6:) (go []))
5)   = (5:) ((6:) [])
(6:))= (5:) [6]
(5:))= [5, 6]

So you can see that its building up a chain of one-argument
functions such as:

(5:) (id ((6:) []))

before collapsing it down to a list like

[5,6]

(note to save space, I collapsed the "id" term early.  If I left
it till longer we would have arrived at the expression above).


Many thanks, Paul


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] some simple proof exercises

2007-09-28 Thread Tim Newsham

Here are two small problem sets of proofs of Haskell functions.
They are aimed at people who do not have experience writing proofs
and are not necessarily well versed in Haskell.  Feedback is appreciated.

http://www.thenewsh.com/%7Enewsham/formal/problems/set1.html
http://www.thenewsh.com/%7Enewsham/formal/problems/set2.html

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] simple parsing (parsec) intro

2007-09-09 Thread Tim Newsham
I wrote a small intro about how to write a parser in haskell. Its 
basically about parsec and how it works, but its written without directly 
referencing parsec and aimed towards beginners (basically wrote it for 
some friends).


Any feedback is appreciated.

   http://www.thenewsh.com/%7Enewsham/formal/parse/parser.lhs

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] IO in HApps handler ?

2007-08-19 Thread Tim Newsham

Subject: IO in HApps handler ?
I am trying to add a handler that would run an external command in
HApps 0.8.8, and I got a type issue I do not know how to get around..

can we have IO in a handler ?


http://www.haskell.org/haskellwiki/HAppS_tutorial#Application

  "The MACID monad lets you update your state and *schedule*
   side-effects.  To be clear, MACID is not in the IO monad
   so you cannot execute side effects, you can only schedule
   them. The framework takes care of making sure they are
   executed at-least-once (if they can be completed by a
   deadline you specify)."

I don't know the specifics.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Small proof intro

2007-08-13 Thread Tim Newsham
I put together a small intro lesson on proving haskell code using 
quickcheck, equational reasoning and Isabelle/HOL. Its very elementary, 
but might be of interest to some people here.


  http://www.thenewsh.com/%7Enewsham/formal/reverse/

Feedback is appreciated.

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] FreeBSD/amd64 support?

2007-08-04 Thread Tim Newsham

I noticed that there is no official FreeBSD/amd64 port yet, although
there's a binary with a working "ghc" but non-working "ghci."  Has
there been any progress on the amd64 port?  Any estimate on when it
will be available?  Any known workarounds (is it possible to install
and run an x86 ghc in FreeBSD/amd64)?
Is hardware access holding anyone up?

Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] problem with IO, strictness, and "let"

2007-07-16 Thread Tim Newsham

The problem is that you're closing the file twice.  When you call any
function of the getContents family, you assign to that function the
responsibility to close the file, no sooner than it is no longer needed.
Don't call hClose yourself, Bad Things will happen.


If you close the file, the stream will suddenly end.  I believe silent
data corruption is worse than a crash :)  (currently, hGetContents also
truncates on I/O error, but that's much less common and syslog will tell
you about it anyway)


Why can't hClose be more... um... lazy?


Stefan


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Sparse documentation

2007-07-03 Thread Tim Newsham

Is there a particular module you're having trouble with?  Or just griping in
general? =)


How about STM?  It would be nice if I didn't have to scan the paper each 
time I do something with STM.  Isn't that the point of having an API 
reference?



-Brent


Tim Newsham
http://www.thenewsh.com/~newsham/
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


  1   2   >