Send Beginners mailing list submissions to
        [email protected]

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        [email protected]

You can reach the person managing the list at
        [email protected]

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1. Re:  Re: Parsing a file with data divided into    sections
      (Brent Yorgey)
   2.  Just how unsafe is unsafe (Andrew Wagner)
   3.  Re: [Haskell-cafe] Just how unsafe is unsafe (Peter Verswyvelen)
   4.  Re: [Haskell-cafe] Just how unsafe is unsafe (Max Rabkin)
   5.  Re: [Haskell-cafe] Just how unsafe is unsafe (Jonathan Cast)
   6.  Re: [Haskell-cafe] Just how unsafe is unsafe (Jake McArthur)
   7.  Re: [Haskell-cafe] Just how unsafe is unsafe (Jake McArthur)


----------------------------------------------------------------------

Message: 1
Date: Wed, 4 Feb 2009 09:49:27 -0500
From: Brent Yorgey <[email protected]>
Subject: Re: [Haskell-beginners] Re: Parsing a file with data divided
        into    sections
To: [email protected]
Message-ID: <[email protected]>
Content-Type: text/plain; charset=us-ascii

On Wed, Feb 04, 2009 at 12:10:02PM +0100, Heinrich Apfelmus wrote:
> Magnus Therning wrote:
> 
> Here's a version using  span  from the Prelude:
> 
>   main = interact $ unlines . map show . countDays . lines
> 
>   countDays []       = []
>   countDays (day:xs) = (day, length people) : countDays xs'
>      where (people, xs') = span (isSpace . head) xs
> 
> 
> Note that this file format is very simple and it's ok to use  lines  and
>  isSpace  to parse it. But the tool of choice are parser combinators
> like  Text.Parsec  or  Text.ParserCombinators.ReadP .

Let me also point out that using the 'split' package from Hackage [1], we
can implement this nicely without any icky manual recursion, and
without resorting to a full-blown parsing library:

  import Data.List.Split
  import Data.Char

  main = interact (unlines . map show . countDays . lines)

  countDays = map length . tail . splitWhen isDay
    where isDay = not . isSpace . head

'splitWhen' splits the list of lines into chunks using things that
satisfy the predicate as delimiters; then we just 'map length' over
those chunks to count the people for each day.  The 'tail' is
necessary because the split actually produces a blank list of people
*before* the first day, but otherwise this is entirely
straightforward.

-Brent

[1] http://hackage.haskell.org/cgi-bin/hackage-scripts/package/split


------------------------------

Message: 2
Date: Thu, 5 Feb 2009 16:11:17 -0500
From: Andrew Wagner <[email protected]>
Subject: [Haskell-beginners] Just how unsafe is unsafe
To: Haskell Cafe <[email protected]>,    Beginners Haskell
        <[email protected]>
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

So we all know the age-old rule of thumb, that unsafeXXX is simply evil and
anybody that uses it should be shot (except when it's ok).
I understand that unsafeXXX allows impurity, which defiles our ability to
reason logically about haskell programs like we would like to. My question
is, to what extent is this true?

Suppose we had a module, UnsafeRandoms, which had a function that would
allow you to generate a different random number every time you call it. The
semantics are relatively well-defined, impurity is safely sectioned off in
its own impure module, which is clearly labeled as such. How much damage
does this do?

Can we push the lines elsewhere? Is sectioning unsafeXXX into Unsafe modules
a useful idiom that we can use for other things as well?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090205/e24438ba/attachment-0001.htm

------------------------------

Message: 3
Date: Thu, 5 Feb 2009 23:47:28 +0100
From: Peter Verswyvelen <[email protected]>
Subject: [Haskell-beginners] Re: [Haskell-cafe] Just how unsafe is
        unsafe
To: Jake McArthur <[email protected]>
Cc: Beginners Haskell <[email protected]>,  Haskell Cafe
        <[email protected]>
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset="iso-8859-1"

Well, one could say that a truly random number function takes as input time
and some constant unique identifier (serial number) of the TRND device and
gives you the random value measured at that time by this device. Of course
this would mean the random value is not really random, since "the potential
creator of the universe" would have known the value already, but to all
humble beings living in the bubble, it would be Truly Random :)
Then the question is, is time a function? If so, is it discrete?

Okay, this is not Haskell anymore, this would become philosophy, and since a
good and smart friend of mine told me that nobody really knows what time is,
this is off topic. Sorry!  :)

On Thu, Feb 5, 2009 at 11:31 PM, Jake McArthur <[email protected]> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Peter Verswyvelen wrote:
> | I do have asked myself the question whether a "really random generating"
> | function could be regarded as "pure" somehow (actually would a true
> | random function still be a mathematical function?)
> |
> | E.g. the function would return a true (not pseudo) random number,
> | practically unpredictable (e.g. hardware assisted, using some physical
> | phenomenon, e.g. using atmospheric noise or something). So you surely
> | won't get referential transparency but since the function is really
> | random, this would be correct behavior?
>
> An informal definition of a function might be something like a black box
> that takes and input and produces an output, and for each possible
> input, the output must be the same. Taking this to be a function, there
> is really no such thing as a random function, and if there was, it
> wouldn't even need to be a function. (What would the input to it be?)
>
> If you wanted to mathematically represent a random number, it would, in
> most cases I can think of, best be represented as a free variable. In a
> program, such a free variable could be filled in by the runtime.
> Conveniently, (and by no coincidence) this is something the IO monad can
> provide for us! :)
>
> | Of course you could just put this random generator in the IO monad, but
> | certain algorithms- like Monte Carlo - intuitively don't seem to operate
> | in a IO monad to me.
>
> Why not?
>
> A Random monad might be more appropriate in this case anyway. Such a
> monad is a State monad that hold a random seed. Every time a random
> number is needed, the seed is passed to a deterministic psuedo-random
> number generator, and a new seed is put as the next state.
>
> If a truly random number is ever needed, either IO or unsafeInterleaveIO
> will be needed. The use of unsafeInterleaveIO would be a (rightly)
> controversial choice though.
>
> - - Jake
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iEYEARECAAYFAkmLaK4ACgkQye5hVyvIUKk88QCfRksu7z80QmzgjUvmiyrzDDjl
> QnsAn1R5DHz2tJpWP3yb0+U+loyBdyCX
> =RIX9
> -----END PGP SIGNATURE-----
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20090205/c98379ee/attachment-0001.htm

------------------------------

Message: 4
Date: Thu, 5 Feb 2009 14:22:45 -0800
From: Max Rabkin <[email protected]>
Subject: [Haskell-beginners] Re: [Haskell-cafe] Just how unsafe is
        unsafe
To: Peter Verswyvelen <[email protected]>
Cc: Beginners Haskell <[email protected]>,  Haskell Cafe
        <[email protected]>, Jake McArthur <[email protected]>
Message-ID:
        <[email protected]>
Content-Type: text/plain; charset=UTF-8

2009/2/5 Peter Verswyvelen <[email protected]>:
> Of course you could just put this random generator in the IO monad, but
> certain algorithms- like Monte Carlo - intuitively don't seem to operate in
> a IO monad to me.

For PRNGs, only State is needed, not IO.

But you might find the `randoms' function useful: it returns in
infinite list of pseudo-random values.

--Max


------------------------------

Message: 5
Date: Thu, 05 Feb 2009 13:33:13 -0800
From: Jonathan Cast <[email protected]>
Subject: [Haskell-beginners] Re: [Haskell-cafe] Just how unsafe is
        unsafe
To: Andrew Wagner <[email protected]>
Cc: Beginners Haskell <[email protected]>,  Haskell Cafe
        <[email protected]>
Message-ID: <1233869593.19682.61.ca...@jcchost>
Content-Type: text/plain

On Thu, 2009-02-05 at 16:11 -0500, Andrew Wagner wrote:
> So we all know the age-old rule of thumb, that unsafeXXX is simply
> evil and anybody that uses it should be shot (except when it's ok). 

> I understand that unsafeXXX allows impurity, which defiles our ability
> to reason logically about haskell programs like we would like to.

Not just that!  Parametric polymorphism is unsound in combination with
mutable values; but unsafePerformIO turns on exactly that combination.

unsafeCoerce :: alpha -> beta
unsafeCoerce x = unsafePerformIO $ do
  let r = unsafePerformIO $ newIORef undefined
  r `writeIORef` x
  readIORef r

> My question is, to what extent is this true? 

unsafePerformIO is a true function --- in the absence of any fancy
compiler trickery --- on a small subset of its domain.  Outside of that
subset, I would regard use of unsafePerformIO simply as a bug ---
violation of an unchecked precondition.  Period.

> Suppose we had a module, UnsafeRandoms, which had a function that
> would allow you to generate a different random number every time you
> call it.

unsafePerformIO does not allow you to guarantee this!  If I defined

  myRandomNumber = unsafePerformIO $ randomNumber

then the compiler is permitted to call randomNumber (at most) *once*,
and use that number throughout the program.

> The semantics are relatively well-defined,

Leaving aside the issue above, I would think complete randomness was
nearly the worst possible case, semantically.  (The *worst* worst
possible case would be non-statistical non-determinism --- which is what
you actually get here).

> impurity is safely sectioned off in its own impure module, which is
> clearly labeled as such. How much damage does this do?

Well, it forces me to chase your libraries import lists to decide
whether I want to trust your code, for one thing.  Haskell is all about
making it easier to audit code, not harder.

> Can we push the lines elsewhere?

I'd rather not.

> Is sectioning unsafeXXX into Unsafe modules a useful idiom that we can
> use for other things as well?

I'd rather not write other unsafe functions at all.  Sectioning off
things that need to be unsafe into pure solutions --- like, say, monads
--- is a much better idea.  (Go read the global variables thread from
last year).

jcc




------------------------------

Message: 6
Date: Thu, 05 Feb 2009 15:36:51 -0600
From: Jake McArthur <[email protected]>
Subject: [Haskell-beginners] Re: [Haskell-cafe] Just how unsafe is
        unsafe
To: Andrew Wagner <[email protected]>
Cc: Beginners Haskell <[email protected]>,  Haskell Cafe
        <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Andrew Wagner wrote:
| I understand that unsafeXXX allows impurity, which defiles our ability
| to reason logically about haskell programs like we would like to. My
| question is, to what extent is this true?

My opinion is that unsafeXXX is acceptable only when its use is
preserved behind an abstraction that is referentially transparent and
type safe. Others may be able to help refine this statement.

| Suppose we had a module, UnsafeRandoms, which had a function that would
| allow you to generate a different random number every time you call it.
| The semantics are relatively well-defined, impurity is safely sectioned
| off in its own impure module, which is clearly labeled as such. How much
| damage does this do?

This does not preserve referential transparency, so by my criteria above
this is an unacceptable use of an unsafe function. One reason it's a bad
idea is that it removes determinism, which may be very important for
testability.

- - Jake
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkmLW/MACgkQye5hVyvIUKniOACfQGPLiY65+eiMfsv7BlbYLI++
Bd0An1N5wp6TDkJzhmdw831/Gj45Bv9S
=TnQg
-----END PGP SIGNATURE-----


------------------------------

Message: 7
Date: Thu, 05 Feb 2009 16:31:10 -0600
From: Jake McArthur <[email protected]>
Subject: [Haskell-beginners] Re: [Haskell-cafe] Just how unsafe is
        unsafe
To: Peter Verswyvelen <[email protected]>
Cc: Beginners Haskell <[email protected]>,  Haskell Cafe
        <[email protected]>
Message-ID: <[email protected]>
Content-Type: text/plain; charset=ISO-8859-1; format=flowed

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Peter Verswyvelen wrote:
| I do have asked myself the question whether a "really random generating"
| function could be regarded as "pure" somehow (actually would a true
| random function still be a mathematical function?)
|
| E.g. the function would return a true (not pseudo) random number,
| practically unpredictable (e.g. hardware assisted, using some physical
| phenomenon, e.g. using atmospheric noise or something). So you surely
| won't get referential transparency but since the function is really
| random, this would be correct behavior?

An informal definition of a function might be something like a black box
that takes and input and produces an output, and for each possible
input, the output must be the same. Taking this to be a function, there
is really no such thing as a random function, and if there was, it
wouldn't even need to be a function. (What would the input to it be?)

If you wanted to mathematically represent a random number, it would, in
most cases I can think of, best be represented as a free variable. In a
program, such a free variable could be filled in by the runtime.
Conveniently, (and by no coincidence) this is something the IO monad can
provide for us! :)

| Of course you could just put this random generator in the IO monad, but
| certain algorithms- like Monte Carlo - intuitively don't seem to operate
| in a IO monad to me.

Why not?

A Random monad might be more appropriate in this case anyway. Such a
monad is a State monad that hold a random seed. Every time a random
number is needed, the seed is passed to a deterministic psuedo-random
number generator, and a new seed is put as the next state.

If a truly random number is ever needed, either IO or unsafeInterleaveIO
will be needed. The use of unsafeInterleaveIO would be a (rightly)
controversial choice though.

- - Jake
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkmLaK4ACgkQye5hVyvIUKk88QCfRksu7z80QmzgjUvmiyrzDDjl
QnsAn1R5DHz2tJpWP3yb0+U+loyBdyCX
=RIX9
-----END PGP SIGNATURE-----


------------------------------

_______________________________________________
Beginners mailing list
[email protected]
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 8, Issue 3
***************************************

Reply via email to