Chris Kuklewicz | 2 Jun 2012 14:22

SafeSemapore

This message is in three parts: a problem, a solution, and a request for help.

The problem is that Control.Concurrent.QSem, QSemN, and SampleVar are all still
broken.  GHC ticket #3160 is still open [1].  These three synchronization
mechanisms can be irretrievable broken by a killThread on a blocked waiter.

The solution is that I am please to announce that SafeSemaphore has been updated
to 0.9.0 on hackage [2] and github.  These provides safe solutions to replace
QSem and QSemN, actually several such solutions.  See the github [2] page
(scroll down for README) for a summary of all the modules.

The request for help is that I would like to unbreak the Haskell Platform by
replacing the guts of QSem, QSemN, and SampleVar with SafeSemaphore.

Do you think my replacement is correct or buggy?  Can we get #3160 closed?

Replacing these will preserve their API but may tinker with corner case
undocumented behavior.  Should waiters block in FIFO order?  Should QSemN starve
big or small requests to be fairer?

[1] http://hackage.haskell.org/trac/ghc/ticket/3160  (three years old!)
[2] http://hackage.haskell.org/package/SafeSemaphore/
[3] https://github.com/ChrisKuklewicz/SafeSemaphore

Sincerely,
  Chris Kuklewicz
Ian Lynagh | 2 Jun 2012 16:09
Picon
Gravatar

Re: SafeSemapore


Hi Chris,

On Sat, Jun 02, 2012 at 01:22:47PM +0100, Chris Kuklewicz wrote:
> 
> The request for help is that I would like to unbreak the Haskell Platform by
> replacing the guts of QSem, QSemN, and SampleVar with SafeSemaphore.

I think these modules are not being well-cared for in base, so can we
solve this by instead removing them from base, and making SafeSemaphore
the recommended library for this functionality?

The HP can then add the SafeSemaphore package instead if it wants to
keep it.

We would need to remove:
* Control.Concurrent.QSem
* Control.Concurrent.QSemN
* Control.Concurrent.SampleVar
* The Control.Concurrent re-exports of the above 3 modules
* Control.Concurrent.mergeIO
* Control.Concurrent.nmergeIO

Patch attached.

Thanks
Ian

Attachment (safesem.patch): text/x-diff, 14 KiB
(Continue reading)

Sean Leather | 3 Jun 2012 18:46
Picon

Re: [Haskell-cafe] Announce: Haskell Platform 2012.2.0.0

On Sun, Jun 3, 2012 at 6:24 PM, Mark Lentczner wrote:

We're pleased to announce the next release of Haskell Platform:
a single, standard Haskell distribution for everyone.

Awesome! Congratulations!

Download Haskell Platform 2012.2.0.0:

   http://haskell.org/platform/

It's a relatively minor thing, but I noticed that the above URL redirects to


which is incidentally considered a different URL from


by Google's +1 service. Perhaps not surprisingly, http://haskell.org/platform redirects to the latter, single-/ Hackage URL.

Regards,
Sean
_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Simon Peyton-Jones | 4 Jun 2012 12:43
Picon
Favicon
Gravatar

RE: Unboxed Vectors of newtype'd values

| I'd like some compiler support for abstracting over unboxed values in
| general and e.g. generate Unbox instances automatically. Then we could
| have other unboxed structures than Vector.

Could someone post an example or two of the problem being described here?

Simon

| -----Original Message-----
| From: libraries-bounces <at> haskell.org [mailto:libraries-
| bounces <at> haskell.org] On Behalf Of Johan Tibell
| Sent: 30 May 2012 17:57
| To: Bryan O'Sullivan
| Cc: Jake McArthur; libraries <at> haskell.org
| Subject: Re: Unboxed Vectors of newtype'd values
| 
| On Wed, May 30, 2012 at 9:50 AM, Bryan O'Sullivan <bos <at> serpentine.com>
| wrote:
| > Likewise, if anyone is listening :-)
| 
| Here too.
| 
| I'd like some compiler support for abstracting over unboxed values in
| general and e.g. generate Unbox instances automatically. Then we could
| have other unboxed structures than Vector.
| 
| _______________________________________________
| Libraries mailing list
| Libraries <at> haskell.org
| http://www.haskell.org/mailman/listinfo/libraries
Andreas Abel | 4 Jun 2012 20:35
Picon
Favicon

Re: [Haskell] Types of when and unless in Control.Monad

On 04/22/2012 01:49 PM, Ivan Lazar Miljenovic wrote:
> On 22 April 2012 21:39, Christian Höner zu Siederdissen
> <choener <at> tbi.univie.ac.at>  wrote:
>> * Julian Gilbey<julian <at> d-and-j.net>  [22.04.2012 09:22]:
>>> On Sat, Apr 21, 2012 at 08:28:27PM -0500, Strake wrote:
>>>> On 21/04/2012, Andreas Abel<andreas.abel <at> ifi.lmu.de>  wrote:
>>>>> to avoid silly "return ()" statements like in
>>>>>
>>>>>     when cond $ do
>>>>>       monadicComputationWhoseResultIWantToDiscard
>>>>>       return ()
>>>>
>>>> (when cond ∘ void) monadicComputationWhoseResultIWantToDiscard
>>>> or
>>>> when cond $ ()<$ monadicComputationWhoseResultIWantToDiscard
>>>
>>> How is that simpler than
>>>
>>>    when cond monadicComputationWhoseResultIWantToDiscard
>>>
>>> which it would be with the suggested new type?
>>>
>>>     Julian
>>
>> Wouldn't "when_" and "unless_" or similar be better? I'd probably like
>> to have the compiler annoy me, since it is not clear that I want to
>> discard the result. If I really want to discard, I should have to make
>> it clear as there is probably a good reason for the inner function to
>> return a result in the first place?
>
> Agreed; I'm not sure if I agree with having such functionality
> (Henning makes some good points), but if people deem it desirable then
> I think it would be better to have them with new names for the reasons
> you state.

Mmh, this discussion has cooled down, but I just found your answers 
which had been stashed away by my mail agent, and I feel I have to reply...

Concerning the suggestion that when_ would be in sync with forM_ and 
whenM_ I'd say: not really.  forM_ and whenM_ discard the result of the 
monadic computation, while when and when_ do not even have such a 
result.  They always just perform some monadic effect and return nothing.

Repeating myself, 'when' can never have a result, since it is an if-then 
without an else.  Thus, it is a proper command; and if you want to have 
a conditional monadic computation which does return a result, you can 
simply not use 'when' or 'unless', logic forces you to use 'if' or 'ifM'.

I do not understand the worries that one could accidentially use 'when' 
with a monadic computation whose result one actually cares for.  If that 
was the intention of the library designers, they should have given many 
other function a more specific type, most prominently

   >> :: m () -> m b -> b

That would have ensured that you cannot discard the result of the first 
computation by accident.  But would you want to work with this?  My 
answer is no.

Other types that would be changed to implement this kind of safety 
policy are:

   mapM_ :: (a -> m ()) -> [a] -> m ()
   forM_ :: [a] -> (a -> m ()) -> m ()
   sequence_ :: [m ()] -> m ()
   forever :: m () -> m ()

and many more, like zipWithM_, foldM_, replicateM_.

Sorry, but I think all these function have been given their maximal 
general type

   ==> to be able to ignore a result of a monadic computation

   ==> without further noise.

In my opinion, the types of when and unless are not general enough, an 
that is, imho, just an accident of history.  Because it is the type that 
inferred for the shortest definition, which is

   when cond m = if cond then m else return ()

Please reevaluate my proposal to change to

   when   :: Bool -> m a -> m ()
   unless :: Bool -> m a -> m ()

in the light of the above arguments.

Cheers,
Andreas

--

-- 
Andreas Abel  <><      Du bist der geliebte Mensch.

Theoretical Computer Science, University of Munich
Oettingenstr. 67, D-80538 Munich, GERMANY

andreas.abel <at> ifi.lmu.de
http://www2.tcs.ifi.lmu.de/~abel/

_______________________________________________
Libraries mailing list
Libraries <at> haskell.org
http://www.haskell.org/mailman/listinfo/libraries
Henning Thielemann | 4 Jun 2012 21:25
Picon

Re: [Haskell] Types of when and unless in Control.Monad


On Mon, 4 Jun 2012, Andreas Abel wrote:

> Concerning the suggestion that when_ would be in sync with forM_ and whenM_ 
> I'd say: not really.  forM_ and whenM_ discard the result of the monadic 
> computation, while when and when_ do not even have such a result.  They 
> always just perform some monadic effect and return nothing.

What is whenM_ ? Do you mean mapM_ ?

>  >> :: m () -> m b -> b
>
>  mapM_ :: (a -> m ()) -> [a] -> m ()
>  forM_ :: [a] -> (a -> m ()) -> m ()
>  sequence_ :: [m ()] -> m ()
>  forever :: m () -> m ()
>
> and many more, like zipWithM_, foldM_, replicateM_.

I would prefer these strict types, too.

Alternatively I have wondered in the past whether it might be a good idea 
to generalize them to:

>  mapM_ :: Monoid b => (a -> m b) -> [a] -> m b
>  forM_ :: Monoid b => [a] -> (a -> m b) -> m b
>  sequence_ :: Monoid b => [m b] -> m b
>  forever :: Monoid b => m b -> m b

This would still propagate monadic result type () if the final monadic 
action has result type ().

http://www.haskell.org/pipermail/haskell-cafe/2009-January/054243.html

> Sorry, but I think all these function have been given their maximal general 
> type
>
>  ==> to be able to ignore a result of a monadic computation
>
>  ==> without further noise.

Since the addition of 'void' the noise has become acceptable for me.

I would follow a kind of "separation of concerns". Ignoring results is one 
step and performing forM_, when etc. is the second step.

> In my opinion, the types of when and unless are not general enough, an that 
> is, imho, just an accident of history.  Because it is the type that inferred 
> for the shortest definition, which is
>
>  when cond m = if cond then m else return ()
>
> Please reevaluate my proposal to change to
>
>  when   :: Bool -> m a -> m ()
>  unless :: Bool -> m a -> m ()
>
> in the light of the above arguments.

Last time I asked the question, what application you do have in mind. Is 
your code cluttered with void's or do you just need it occasionally?
Henning Thielemann | 4 Jun 2012 21:27
Picon

Re: [Haskell] Types of when and unless in Control.Monad


On Mon, 4 Jun 2012, Henning Thielemann wrote:

> On Mon, 4 Jun 2012, Andreas Abel wrote:
>
>> Concerning the suggestion that when_ would be in sync with forM_ and whenM_ 
>> I'd say: not really.  forM_ and whenM_ discard the result of the monadic 
>> computation, while when and when_ do not even have such a result.  They 
>> always just perform some monadic effect and return nothing.
>
> What is whenM_ ? Do you mean mapM_ ?

Ah, I think whenM_ was this one

   whenM_ :: m Bool -> m a -> m ()
Bas van Dijk | 4 Jun 2012 21:40
Picon
Gravatar

Re: Unboxed Vectors of newtype'd values

On 4 June 2012 12:43, Simon Peyton-Jones <simonpj <at> microsoft.com> wrote:
> | I'd like some compiler support for abstracting over unboxed values in
> | general and e.g. generate Unbox instances automatically. Then we could
> | have other unboxed structures than Vector.
>
> Could someone post an example or two of the problem being described here?

The following is some boring code I wrote a while back at work for
storing UUIDs[1] in unboxed vectors:

{-# LANGUAGE MultiParamTypeClasses, TypeFamilies #-}

import Control.Monad (liftM)
import Data.Word (Word32)

import Data.UUID (UUID)
import qualified Data.UUID as UUID

import qualified Data.Vector.Unboxed         as VU
import qualified Data.Vector.Generic         as VG
import qualified Data.Vector.Generic.Mutable as VGM

newtype instance VU.MVector s UUID =
	MV_UUID (VU.MVector s (Word32, Word32, Word32, Word32))

newtype instance  VU.Vector UUID =
	V_UUID (VU.Vector (Word32, Word32, Word32, Word32))

instance VU.Unbox UUID

instance VGM.MVector VU.MVector UUID where
  {-# INLINE basicLength #-}
  {-# INLINE basicUnsafeSlice #-}
  {-# INLINE basicOverlaps #-}
  {-# INLINE basicUnsafeNew #-}
  {-# INLINE basicUnsafeReplicate #-}
  {-# INLINE basicUnsafeRead #-}
  {-# INLINE basicUnsafeWrite #-}
  {-# INLINE basicClear #-}
  {-# INLINE basicSet #-}
  {-# INLINE basicUnsafeCopy #-}
  {-# INLINE basicUnsafeGrow #-}
  basicLength (MV_UUID v) =
    VGM.basicLength v

  basicUnsafeSlice i n (MV_UUID v) =
    MV_UUID $ VGM.basicUnsafeSlice i n v

  basicOverlaps (MV_UUID v1) (MV_UUID v2) =
    VGM.basicOverlaps v1 v2

  basicUnsafeNew n =
    MV_UUID `liftM` VGM.basicUnsafeNew n

  basicUnsafeReplicate n uuid =
    MV_UUID `liftM` VGM.basicUnsafeReplicate n (UUID.toWords uuid)

  basicUnsafeRead (MV_UUID v) i =
    fromQuadruple `liftM` VGM.basicUnsafeRead v i

  basicUnsafeWrite (MV_UUID v) i uuid =
    VGM.basicUnsafeWrite v i (UUID.toWords uuid)

  basicClear (MV_UUID v) =
    VGM.basicClear v

  basicSet (MV_UUID v) uuid =
    VGM.basicSet v (UUID.toWords uuid)

  basicUnsafeCopy (MV_UUID v1) (MV_UUID v2) =
    VGM.basicUnsafeCopy v1 v2

  basicUnsafeMove (MV_UUID v1) (MV_UUID v2) =
    VGM.basicUnsafeMove v1 v2

  basicUnsafeGrow (MV_UUID v) n =
    MV_UUID `liftM` VGM.basicUnsafeGrow v n

instance VG.Vector VU.Vector UUID where
  {-# INLINE basicUnsafeFreeze #-}
  {-# INLINE basicUnsafeThaw #-}
  {-# INLINE basicLength #-}
  {-# INLINE basicUnsafeSlice #-}
  {-# INLINE basicUnsafeIndexM #-}
  {-# INLINE elemseq #-}
  basicUnsafeFreeze (MV_UUID v) =
    V_UUID `liftM` VG.basicUnsafeFreeze v

  basicUnsafeThaw (V_UUID v) =
    MV_UUID `liftM` VG.basicUnsafeThaw v

  basicLength (V_UUID v) =
    VG.basicLength v

  basicUnsafeSlice i n (V_UUID v) =
    V_UUID $ VG.basicUnsafeSlice i n v

  basicUnsafeIndexM (V_UUID v) i =
    fromQuadruple `liftM` VG.basicUnsafeIndexM v i

  basicUnsafeCopy (MV_UUID mv) (V_UUID v) =
    VG.basicUnsafeCopy mv v

  elemseq _ uuid z = VG.elemseq (undefined :: VU.Vector a) a
                   $ VG.elemseq (undefined :: VU.Vector a) b
                   $ VG.elemseq (undefined :: VU.Vector a) c
                   $ VG.elemseq (undefined :: VU.Vector a) d z
      where
        (a,b,c,d) = UUID.toWords uuid

fromQuadruple :: (Word32, Word32, Word32, Word32) -> UUID
fromQuadruple (a,b,c,d) = UUID.fromWords a b c d

Regards,

Bas

[1] http://hackage.haskell.org/packages/archive/uuid/1.2.5/doc/html/Data-UUID.html
Johan Tibell | 4 Jun 2012 21:57
Picon
Gravatar

Re: Unboxed Vectors of newtype'd values

My desire probably doesn't overlap much with what others have
described in this thread, apologies. I *think* they want generalized
newtype deriving to work for Unbox instances.

I want to be able to write definition like this (pseudo code):

  data UnpackedList a = forall a. Unbox a => Cons {-# UNPACK #-} !a
(UnpackedList a) | Nil

and have GHC generate appropriate data type definitions at call sites.
In other words, I want polymorphic unpacking to work as long as the
unpacked field is unboxable (i.e. is member of some Unobx type class.)

I believe I've described this desire to you before. Unfortunately it
seems like a really hard problem.

-- Johan
Boris Kropivnitsky | 5 Jun 2012 06:48
Picon

The 'encoding' package maintainer?

Hello,

I am looking for the maintainer of the 'encoding' library.  I tried to
use it for my little project, but it turned out that it has some
issues and needs some love.  So I've made a few fixes and it now works
reasonably well.  I thought the community will benefit if the new
version is made available.  I've tried to contact the author listed in
the .cabal file  but had no luck.  So I thought I'd ask for help here.

Cheers,
Boris Kropivnitsky

Gmane