News aggregator

Bill Atkins: NSNotificationCenter, Swift and blocks

Planet Haskell - Mon, 01/11/2016 - 7:32am
The conventional way to register observers with NSNotificationCenter is to use the target-action pattern. While this gets the job done, it's inherently not type-safe.

For example, the following Swift snippet will compile perfectly:

    NSNotificationCenter.defaultCenter().addObserver(self, selector: Selector("itemAdded:"),      name: MyNotificationItemAdded, object: nil)
even though at runtime it will fail unless self has a method named itemAdded that takes exactly one parameter (leaving off that last colon in the selector will turn this line into a no-op). Plus, this method gives you no way to take advantages of Swift's closures, which would allow the observer to access local variables in the method that adds the observer and would eliminate the need to create a dedicated method to handle the event.
A better way to do this is to use blocks. And NSNotificationCenter does include a block-based API:
    NSNotificationCenter.defaultCenter().addObserverForName(MyNotificationItemAdded, object: nil, queue: nil) { note in      // ...    }
This is much nicer, especially with Swift's trailing closure syntax. There are no method names to be looked up at runtime, we can refer to local variables in the method that registered the observer and we can perform small bits of logic in reaction to events without having to create and name dedicated methods.
The catch comes in resource management. It's very important that an object remove its event observers when it's deallocated, or else NSNotificationCenter will try to invoke methods on invalid pointers.
The traditional target-action method has the one advantage that we can easily handle this requirement with a single call in deinit:
  deinit {    NSNotificationCenter.defaultCenter().removeObserver(self)  }
With the block API, however, since there is no explicit target object, each call to addObserverForName returns "an opaque object to act as observer." So your observer class would need to track all of these objects and then remove them all from the notification center in deinit, which is a pain.
In fact, the hassle of having to do bookkeeping on the observer objects almost cancels out the convenience of using the block API. Frustrated by this situation, I sat down and created a simple helper class, NotificationManager:
class NotificationManager {  private var observerTokens: [AnyObject] = []
  deinit {    deregisterAll()  }
  func deregisterAll() {    for token in observerTokens {      NSNotificationCenter.defaultCenter().removeObserver(token)    }
    observerTokens = []  }
  func registerObserver(name: String!, block: (NSNotification! -> Void)) {    let newToken = NSNotificationCenter.defaultCenter().addObserverForName(name, object: nil, queue: nil, usingBlock: block)

    observerTokens.append(newToken)  }    func registerObserver(name: String!, forObject object: AnyObject!, block: (NSNotification! -> Void)) {    let newToken = NSNotificationCenter.defaultCenter().addObserverForName(name, object: object, queue: nil, usingBlock: block)        observerTokens.append(newToken)  }}
First, this simple class provides a Swift-specialized API around NSNotificationCenter.  It provides an additional convenience method without an object parameter (rarely used, in my experience) to make it easier to use trailing-closure syntax. But most importantly, it keeps track of the observer objects generated when observers are registered, and removes them when the object is deinit'd.

A client of this class can simply keep a member variable of type NotificationManager and use it to register its observers. When the parent class is deallocated, the deinit method will automatically be called on its NotificationManager member variable, and its observers will be properly disposed of:

class MyController: UIViewController {  private let notificationManager = NotificationManager()    override init() {    notificationManager.registerObserver(MyNotificationItemAdded) { note in      println("item added!")    }        super.init()  }    required init(coder: NSCoder) {    fatalError("decoding not implemented")  }}
When the MyController instance is deallocated, its NotificationManager member variable will be automatically deallocated, triggering the call to deregisterAll that will remove the dead objects from NSNotificationCenter.
In my apps, I add a notificationManager instance to my common UIViewController base class so I don't have to explicitly declare the member variable in all of my controller subclasses.

Another benefit of using my own wrapper around NSNotificationCenter is that I can add useful functionality, like group observers: an observer that's triggered when any one of a group of notifications are posted:

struct NotificationGroup {  let entries: [String]    init(_ newEntries: String...) {    entries = newEntries  }
}
extension NotificationManager {  func registerGroupObserver(group: NotificationGroup, block: (NSNotification! -> ()?)) {    for name in group.entries {      registerObserver(name, block: block)    }  }}
This can be a great way to easily set up an event handler to run when, for example, an item is changed in any way at all:
   let MyNotificationItemsChanged = NotificationGroup(      MyNotificationItemAdded,      MyNotificationItemDeleted,      MyNotificationItemMoved,      MyNotificationItemEdited    )
    notificationManager.registerGroupObserver(MyNotificationItemsChanged) { note in      // ...    }
Categories: Offsite Blogs

ANN: true-name 0.1.0.0 released

haskell-cafe - Mon, 01/11/2016 - 6:44am
It is with some shame that I announce ‘true-name’, a package to assist one in violating those pesky module abstraction boundaries via the magick of Template Haskell. http://hackage.haskell.org/package/true-name Take ‘Control.Concurrent.Chan’ for example; you can get your grubby mitts on the ‘Chan’ data constructor, despite it not being exported. Here we pattern match on it, and bind ‘chanR’ and ‘chanW’ to the ‘MVar’s containing the read and write ends of the channel respectively: Now, the type of ’chanR’ references the unexported ‘Stream’ and ‘ChItem’ types. We need the ‘ChItem’ data constructor―which is hidden under a few indirections—but that's not a problem: This gives us a rather dodgy ‘peekChan’. This sort of thing is usually a Bad Idea™, but may sometimes be more palatable than the alternatives. Full example: https://github.com/liyang/true-name/blob/master/sanity.hs Taking another example, suppose we want the ‘Array’ type constructor hidde
Categories: Offsite Discussion

ANN: true-name 0.1.0.0 released

General haskell list - Mon, 01/11/2016 - 6:40am
It is with some shame that I announce ‘true-name’, a package to assist one in violating those pesky module abstraction boundaries via the magick of Template Haskell. http://hackage.haskell.org/package/true-name Take ‘Control.Concurrent.Chan’ for example; you can get your grubby mitts on the ‘Chan’ data constructor, despite it not being exported. Here we pattern match on it, and bind ‘chanR’ and ‘chanW’ to the ‘MVar’s containing the read and write ends of the channel respectively: Now, the type of ’chanR’ references the unexported ‘Stream’ and ‘ChItem’ types. We need the ‘ChItem’ data constructor―which is hidden under a few indirections—but that's not a problem: This gives us a rather dodgy ‘peekChan’. This sort of thing is usually a Bad Idea™, but may sometimes be more palatable than the alternatives. Full example: https://github.com/liyang/true-name/blob/master/sanity.hs Taking another example, suppose we want the ‘Array’ type constructor hidde
Categories: Incoming News

Access files one at a time?

Haskell on Reddit - Mon, 01/11/2016 - 3:43am

Hello,

I am writing a function that reads and writes data to hard disk. Since the application is multithread, I think the data on hard disk should be accessed one at a time. Can anyone tell me how can I do that?

submitted by notooth1
[link] [7 comments]
Categories: Incoming News

New release of the book Haskell Programming from first principles

Haskell on Reddit - Mon, 01/11/2016 - 1:46am

I'd been reticent in the past to ping y'all about each release, but it's pretty comprehensive now and we have enough ecstatic readers learning Haskell with it that I thought I'd update y'all on what we've been up to.

We're writing this Haskell book (http://haskellbook.com/) because many have found learning Haskell to be difficult and it doesn't have to be. We have a strong focus on writing it to be a book for learning and teaching - it's not just a reference or review of topics. Particularly, we strive to make the book suitable for self-learners. We think Haskell is a really nice language and learning Haskell should be as nice as using it is.

The new release puts the book at 26 chapters and 1,156 pages. You can track our progress here: http://haskellbook.com/progress.html

The latest release included parser combinators, composing types, and monad transformers.

My coauthor Julie Moronuki has never programmed before learning Haskell to work with me on this book. She has written about using the book to teach her 10 year old son as well https://superginbaby.wordpress.com/2015/04/08/teaching-haskell-to-a-10-year-old-day-1/

Julie has also written about learning Haskell more generally https://superginbaby.wordpress.com/2015/05/30/learning-haskell-the-hard-way/

We'll be looking for a press to do a print run of the book soon as it's about 80% done. If anyone has any pointers or recommendations on whom to work with, particularly university presses, please email me. My email can be found on my Github profile at https://github.com/bitemyapp/

If you've been reading the book, please speak up and share your thoughts. We have some reader feedback on the site at http://haskellbook.com/feedback.html

submitted by Mob_Of_One
[link] [110 comments]
Categories: Incoming News

String manipulation Guide?

Haskell on Reddit - Sun, 01/10/2016 - 11:32pm

I haven found a complete guide to introduce string manipulation in Haskell, such as OverloadedStrings, String, Text, Bytestring, formatting(pretty printing) ....

-- update: I find a outline by fpco : all about strings

submitted by n00bomb
[link] [7 comments]
Categories: Incoming News

Eq1, Ord1, Show1: move from eq1, compare1, showsPrec1 to liftEq, liftCompare, liftShowsPrec

libraries list - Sun, 01/10/2016 - 3:08pm
In transformers-0.5:Data.Functor.Classes class methods like eq1 are replaced by liftEq. With transformers-0.4 I could define: data T a = complicated definition ... deriving (Eq, Ord, Show) instance Eq1 T where eq1 = (==) instance Ord1 T where compare1 = compare instance Show1 T where showsPrec1 = showsPrec In transformers-0.5 it seems that I have to implement Eq1, Ord1, Show1 instances manually. Is there some assistance to define eq1 and compare1 for an ADT? What are the use cases where eq1 was not powerful enough and liftEq is needed?
Categories: Offsite Discussion

suppress warning "Defined but not used: type variable ‘x’" in GHC-8.0

glasgow-user - Sun, 01/10/2016 - 12:57am
GHC-8.0 emits several new warnings of this kind: Defined but not used: type variable ‘x’ for declarations like type instance Snd x y = y Enthusiastically, I started to replace unused type function arguments by underscores, only to find out that older GHC versions do not accept that. With what option can I disable this warning? Or can it be removed from -Wall for now?_______________________________________________ Glasgow-haskell-users mailing list Glasgow-haskell-users< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/glasgow-haskell-users
Categories: Offsite Discussion

CfP: Workshop on Program Transformation for Programmability in Heterogeneous Architectures (Co-located with CGO16); Deadline Jan 15

General haskell list - Sat, 01/09/2016 - 2:02pm
[Apologies if you receive multiple copies of this announcement.] ********************************************************************************* PROHA 2016, CALL FOR PAPERS First Workshop on Program Transformation for Programmability in Heterogeneous Architectures http://goo.gl/RzGbzY Barcelona, 12th March 2016, in conjunction with the CGO'16 Conference ********************************************************************************* Important Dates: Paper submission deadline: 15 January 2016 23:59 (UTC) Author notification: 5 February 2016 Final manuscript due: 26 February 2016 Scope: Developing and maintaining high-performance applications and libraries for heterogeneous architectures is a difficult task, usually requiring code transformations performed by an expert. Tools assisting in and, if possible, automating such transformations are of course of great interest. However, such tools require significant knowledge and reasoning capabilities. For example, the former could be a machine-unders
Categories: Incoming News

New gtk2hs 0.12.4 release

gtk2hs - Wed, 11/21/2012 - 12:56pm

Thanks to John Lato and Duncan Coutts for the latest bugfix release! The latest packages should be buildable on GHC 7.6, and the cairo package should behave a bit nicer in ghci on Windows. Thanks to all!

~d

Categories: Incoming News