News aggregator

Edward Z. Yang - Sun, 11/30/2014 - 6:28pm
Categories: Offsite Blogs

Mark Jason Dominus: Why my book can be downloaded for free

Planet Haskell - Sun, 11/30/2014 - 6:00pm

People are frequently surprised that my book, Higher-Order Perl, is available as a free download from my web site. They ask if it spoiled my sales, or if it was hard to convince the publisher. No and no.

I sent the HOP proposal to five publishers, expecting that two or three would turn it down, and that I would pick from the remaining two or three, but somewhat to my dismay, all five offered to publish it, and I had to decide who.

One of the five publishers was Morgan Kaufmann. I had never heard of Morgan Kaufmann, but one day around 2002 I was reading the web site of Philip Greenspun. Greenspun was incredibly grouchy. He found fault with everything. But he had nothing but praise for Morgan Kaufmann. I thought that if Morgan Kaufmann had pleased Greenspun, who was nearly impossible to please, then they must be really good, so I sent them the proposal. (They eventually published the book, and did a superb job; I have never regretted choosing them.)

But not only Morgan Kaufmann but four other publishers had offered to publish the book. So I asked a number of people for advice. I happened to be in London one week and Greenspun was giving a talk there, which I went to see. After the talk I introduced myself and asked for his advice about picking the publisher.

Greenspun reiterated his support for Morgan Kaufmann, but added that the publisher was not important. Instead, he said, I should make sure to negotiate permission to make the book available for free on my web site. He told me that compared with the effort that you put into the book, the money you get back is insignificant. So if you write a book it should not be because you want to make a lot of money from it but because you have an idea that you want to present to the world. And as an author, you owe it to yourself to get your idea in front of as many people as possible. By putting the book in your web site, you make it available to many people who would not otherwise have access to it: poor people, high school students, people in developing countries, and so on.

I thought that Greenspun's idea made sense; I wanted my ideas about programming to get to as many people as possible. Also, demanding that I make the book available on my web site for free seemed like a good way to narrow down the five publishers to two or three.

The first part of that plan worked out well. The second part not so well: all five publishers agreed. Some agreed reluctantly and some agreed willingly, but they all agreed. Eventually I had the book published by Morgan Kaufmann, and after a delay that seemed long at the time but in retrospect seems not so long, I put the book on my web site. It has been downloaded many times. (It's hard to say how many, since browsers often download just the portion of the PDF file that they need to display.)

Would the book have made more money if it were not available as a free download? We can't know for sure, but I don't think so. The book has always sold well, and has made a significant amount of money for me and for Morgan Kaufmann. The amount I made is small compared to the amount of work I had to put in, just as Greenspun said, but it was nothing to sneeze at either. Even now, ten years later, it is still selling and I still get a royalty check every six months. For my book to have lasted ten years is extremely rare. Most computer books disappear without a trace after six months.

Part of this is that it's an unusually good book. But I think the longevity is partly because it is available as a free download. Imagine that person A asks a question on an Internet forum, and person B says that HOP has a section that could help with the question. If B wants to follow up, they now must find a copy of HOP. If the book is out of print, this can be difficult. It may not be in the library; it almost certainly isn't in the bookstore. Used copies may be available, but you have to order them and have them shipped, and if you don't like it once it arrives, you are stuck with it. The barrier is just too high to be convenient. But since HOP is available on my web site, A can include a link, or B can find it with an easy web search. The barrier is gone! And now I have another reader who might mention it to someone else, and they might even buy a copy. Instead of drifting away into obscurity, HOP is a book that people can recommend over and over.

So my conclusion is, Greenspun's advice was exactly correct. As an author, you owe it to yourself to make your book available to as many people as possible. And the publisher may agree, so be sure to ask.

[ Addendum: Some people are just getting the news, but the book was published in 2005, and has been available as a free download since 2008. ]

Categories: Offsite Blogs

Oliver Charles: 24 Days of GHC Extensions: Welcome!

Planet Haskell - Sun, 11/30/2014 - 6:00pm

Hello everyone, I’m pleased to announce it’s that time of the year again! Following in the tradition of 24 Days of Hackage 2012 and 2013, it’s time for another advent calendar. However, this year I felt it could be fun to try something a little different.

The previous years have concentrated on using libraries available on Hackage, and this is naturally a very important part of working in Haskell. However, it’s one thing to use libraries, but it’s another to just write code - and for this it’s important to note just what the language itself has to offer.

Haskell itself is a well defined language - officially specified by the Haskell ’98 report, and the subsequent Haskell 2010 report. Language implementers needn’t stop there though, as Haskell is meant to be a rich playground for experimenting with new functional programming constructs. For many years, GHC has embraced the notion of extensions - opt in functionality that gives the user even more tools when writing their programs.

GHC extensions vary from basic syntax sugar, to meta-programming, all the way to full type system extensions. Remarkably, the extension system is extremely mature - where many of the extensions transparently extend syntax, error messages, and is far from an ad hoc approach to extending the language. In fact, it’s hard to avoid using GHC extensions these days - the power and productivity gains they bring is simply too much to ignore.

Over the next few weeks, we’ll explore just a handful of the extensions that GHC supports - a list which as of GHC 7.8 is almost exceeding 100 extensions! I’m also happy to announce that this year will feature some guest posts once again, so the lead up to Christmas should packed with excitement.

If you’re interested in writing a guest post, please do get in touch - there are still spaces! If there’s any extension that excites you, or crops up a lot in your programming, I highly encourage you to volunteer a post about it. As with previous years, I would love it if 24 Days can become a platform for those new to blogging to get their feet wet, along with a fantastic learning resource.

On with the show!

This post is part of 24 Days of GHC Extensions - for more posts like this, check out the calendar.

Categories: Offsite Blogs

Created a small spaced-repetition program to learn Haskell, feedback appreciated

Haskell on Reddit - Sun, 11/30/2014 - 3:24pm

I've been trying to learn Haskell recently (I can't recommend the #haskell IRC group enough), and I've always wanted something like Anki, but on the command line, so I made Clanki in haskell (CL + Anki = Clanki, naming stuff is not a strength of mine). It's very basic spaced-repetition software, you add decks/cards, quiz whenever you want, and the program will determine what cards are due for review using the Super Memo 2 algorithm detailed here :

The full source code is available here if anyone is interested : I'd love for anyone to critique the source and tell me what I did that was wrong, bad practice, ugly, unnecessary, etc. I tried to make it clean but I'm sure there are a bunch of places where a more experienced Haskell dev could steer me in a better direction.

If anyone wants to try it, out it's on cabal, so just run 'cabal install clanki', then run 'clanki', and (hopefully) it will work. 'cabal update' if it's not found, since it was just uploaded.

EDIT : Wrote an article on how what I found most interesting when learning Haskell, link

submitted by mbuffett1
[link] [12 comments]
Categories: Incoming News

How to make this function more elegant and memoized?

Haskell on Reddit - Sun, 11/30/2014 - 3:06pm

Mind the following program:

dist (a:as) (b:bs) = path_a `min` path_b `min` path_c where path_a = (if a == b then 0 else 1) + dist as bs path_b = 1 + dist as (b:bs) path_c = 1 + dist (a:as) bs dist as [] = length as dist [] bs = length bs main = print $ dist "some words" "same words?"

This is stupidly inefficient but kinda elegant. How would an expert Haskeller make it even more elegant? How would you add memoization to it elegantly? (Bonus for single-high-order function that does so automatically.)

submitted by SrPeixinho
[link] [12 comments]
Categories: Incoming News

Which laptop for Haskell Dev

Haskell on Reddit - Sun, 11/30/2014 - 5:15am

Hi know it's a very subjective question, but laptops reviews are too (and outdated, and you never really know what needs reviewers have).

So , I need to upgrade my old macbook pro, which for some reason is getting sluggish and sluggish.

I'm looking for a new laptop (for work) to do mainly CLI based dev (Haskell and R). This is my main computer (my only one in fact). I use it as at work, as a desktop one (plugged to a Monitor and a keyboard) and in the evening as a laptop. I would prefer something fast. As I said, it's for work so money is not a problem. The obvious options is a new Macbook pro retina display, but there is nothing exciting about it (I have had them for years, I miss a control key on the right, and for some reason my Mac always endup being slow. Launching vim take about 2s and I have no idea how to solve it). So I'm open to any suggestion, I understood that for the same price than a mac you could get much better performance. I don't mind of the OS, could be Windows, Windows+Virtual Box, Linux etc ...

What is your experience ?

submitted by maxigit
[link] [74 comments]
Categories: Incoming News

Motivation for Monads - Sun, 11/30/2014 - 12:22am
Categories: Offsite Blogs

Mark Jason Dominus: Impostor syndrome

Planet Haskell - Sat, 11/29/2014 - 6:00pm

I don't have impostor syndrome about programming, advanced mathematics, or public speaking. I cheerfully stand up in rooms full of professional programmers and authoritatively tell them what I think they should do.

However, when I put up shelves in the bathroom back in May, I was a psychological mess. For every little thing that went wrong—and there were quite a lot—I got all stressed out and wondered why I dared to perform this task. The outcome was good, but I had a lot of stress getting there.

I put in one plexiglass shelf, for which I had bought heavy-duty wall anchors in case the kids leaned on it, and two metal shelves higher up, which came with their own screws and anchors.

Here's a partial list of things that worried me:

  1. The two upper shelves came with a paper template that I held up to the wall to mark where the holes should be drilled. What if the two shelves were slightly different and their templates were different and I needed to use both templates on the wall instead of using the same template twice?
  2. When I putting the heavy-duty wall anchors into the drywall, big divots of plaster fell out of the wall around the anchors.
  3. Then I filled in the holes with filler, and got filler in the screw holes in the wall anchors, and stressed about this. What if the filler in the sockets somehow prevented the screws from going into the anchors or caused some other unforeseeable problem?
  4. The filler looked sloppy and I worried that it would look absurdly ugly to everyone who came into the bathroom. (The shelf would have hidden the ugly screw job from a normal view, except that it was made of plexiglass, so the filled holes were visible through it.)
  5. I didn't know how big to drill the holes for the smaller wall anchors and stressed about it, examining the wall anchor packaging for some hint. There was none.
  6. I wanted to insert the wall anchors into the holes with my rubber mallet. Where the hell is it? Then I stressed about using a claw hammer instead and maybe squishing the anchors, and spent a while looking for a piece of wood or something to soften the hammer blows. Eventually I gave up looking, wondering if I was dooming the project.
  7. I guessed how big to make the hole for the anchor, and was wrong; my hole was too small. I didn't realize this until I had the first anchor halfway in. Then I stressed that I might ruin it when I pulled it back out of the wall.
  8. Then I stressed about the size of the holes again when I drilled larger holes. What if I make the hole too big, and then have to fill all the holes and re-measure and re-drill the whole thing?
  9. The anchors didn't go into two of the holes. I needed to yank them back out, then redrill the holes, with the outer end a little messy, or the anchors wouldn't go all the way into the holes. Again I worried about spoiling the anchors.
  10. When I drilled the holes, sometimes the drill suddenly went all the way into the wall and the rotating chuck left a circular scar on the paint.
  11. Also, two of the holes didn't drill easily; I had to lean on the drill really hard to get it to go through. For a while I was concerned that there was some undrillable metal thing in the wall just where I wanted my hole, and I would have to fill in all the holes and remeasure and redrill the whole thing.
  12. Even though I had marked the wall for the lower shelf by holding the shelf against the wall and then poking a pencil through the actual holes, when time came to put the bolts in place, I found that the two holes were slightly too far apart. Somehow this worked itself out.

On review, I see that several of these worries could have been completely avoided if I had had a supply of extra wall anchors.

Stuff that could have worried me but (rightly or wrongly) didn't:

  1. I knew enough to go to the store to buy wall anchors and screws for the bottom shelf, which did not come with its own hardware. There are a lot of different kinds of anchors, and I did not worry too much that I was getting the wrong thing.

  2. I was concerned (although not worried) that the screws holding the bottom shelf to the wall might stress the plastic too much and cause it to crack, either immediately or over time. Obvious solution: insert washers between the screw heads and the shelf. I went to the hardware store to get nylon washers; they didn't have any. So I got thin metal washers instead. I did not worry about this; I was sure (perhaps wrongly) that metal washers would do the job.

  3. When I asked the hardware people for plastic washers, they looked totally blank. “Plastic... washers?” they asked, as if this were a heretofore unimaginable combination. I could have felt like an idiot, but instead I felt, correctly I think, that they were idiots.

  4. For some reason, I was not even slightly worried about properly leveling the marks for the holes. I used a spirit level, which I consider pretty fancy.

  5. I was careful not to over-tighten the screws holding the plexiglass shelf in place, so as to avoid cracking them, but I was at no time afraid that I would somehow crack them anyway.

[Added in July: I have reread this article for the first time. I can report that all the worries I had about whether the shelves would look good have come to nothing; they all look just fine and I had forgotten all the things I was afraid would look bad. But I really do need to buy a couple of boxes of plastic wall anchors so I can stop worrying about spoiling the four I have.]

[The shelves look crooked in the picture, but that is because I am holding the camera crooked; in real life they look great.]

[ A later visit to a better hardware store confirmed that plastic washers do exist, and I did not hallucinate them. The rubber mallet still has not come to light.]

Categories: Offsite Blogs

Philip Wadler: Propositions as Types, with Howard on Curry-Howard

Planet Haskell - Sat, 11/29/2014 - 10:12am
Propositions as Types has been updated, again. Thanks again to all the readers and reviewers who helped me improve the paper. This version includes an appendix, Howard on Curry-Howard, including additional correspondence with Howard not previously published.

Propositions as Types
Philip Wadler
Draft, 29 November 2014The principle of Propositions as Types links logic to computation. At first sight it appears to be a simple coincidence---almost a pun---but it turns out to be remarkably robust, inspiring the design of theorem provers and programming languages, and continuing to influence the forefronts of computing. Propositions as Types has many names and many origins, and is a notion with depth, breadth, and mystery.Comments still solicited!

Categories: Offsite Blogs

Bill Atkins: Unit Testing in Swift

Planet Haskell - Sat, 11/29/2014 - 9:27am
Since Swift was released at the beginning of the month, I've been doing using it for most of my iOS development. It's been a pleasant experience: I've been able to discard huge amounts of boilerplate and take advantage of a few functional programming techniques that were previously unavailable on the iPhone and iPad.

One area where Swift has made huge improvements over Objective-C is unit tests. Objective-C's verbosity made it difficult to create small, focused classes to perform specific tasks. Plus, the language's insistence on keeping only one class to a file and the cumbersome pairing of every implementation file with a header imposed a hefty penalty on programmers who tried to divide their work up into discrete, testable components.

Unit testing in Swift is done with the same XCTest framework introduced back in Xcode 5 for Objective-C. But Swift's concision and its inclusion of modern language features like closures makes XCTest much more pleasant than it was to use under Objective-C. We'll walk through a very simple example of Swift unit testing below.

To get started, create an empty iOS Application project in Xcode called Counter. Xcode will generate a CounterTests folder for you and an associated test target.

First, let's create a simple class to be tested. Create the file "Counter.swift" and add the following code to it:

import Foundation
public class Counter {  public var count: Int    public init(count: Int) {    self.count = count  }    public convenience init() {    self.init(count: 0)  }    public func increment() {    self.count++  }
This is a very simple class, but it will be enough to illustrate how to use XCTest to test your own Swift code.

UPDATE: Note that as of Xcode 6.1, any symbols that you want to be visible in your test case should be declared public so they can be seen from the test target, which is distinct from your main application target. In the above example, the class above and any of its members that need to be accessed in the test case have been declared public. Thanks to Kaan Ersan for pointing this out in the comments.

Create a file called "CounterTest.swift" in the CounterTests folder Xcode generated for you (this simple test will be your "Hello, world" for Swift testing):

import XCTestimport Counter
class CounterTest: XCTestCase {  func testSimpleAddition() {    let counter = Counter()    XCTAssertEqual(0, counter.count)  }
NOTE: In the current version of Swift (Beta 2), you have to import your main target into the test target to get your tests to compile and run. This is why we import Counter at the top.

NOTE: I've seen a few Swift tutorials recommend that you use the built-in Swift function assert in your test cases - do not do this! assert will terminate your entire program if it fails. Using the XCTAssert functions provides a number of important benefits:

  • If one test case fails, your other cases can continue running; assert stops the entire program.
  • Because the XCTAssert functions are more explicit about what you're expecting, they can print helpful failure messages (e.g. "2 was not equal to 3") whereas assert can only report that its condition was false. There's a broad variety of assert functions, including XCTAssertLessThan, XCTAssertNil, etc.
  • The Swift language specification explicitly forbids string interpolation in the message passed to assert; the XCTAssert functions don't face this limitation.
To try your test code out, click "Test" on the "Product" menu. Your single test should pass.
We'll add two more test cases to create and exercise several instances of Counter and to ensure that the counter wraps around when it overflows:
import XCTestimport Test
class CounterTest: XCTestCase {  func testInvariants() {    let counter = Counter()    XCTAssertEqual(0, counter.count, "Counter not initialized to 0")        counter.increment()    XCTAssertEqual(1, counter.count, "Increment is broken")
    XCTAssertEqual(1, counter.count, "Count has unwanted side effects!")  }    func testMultipleIncrements() {    let counts = [1, 2, 3, 4, 5, 6]        for count in counts {      let counter = Counter()            for i in 0..count {        counter.increment()      }            XCTAssertEqual(counter.count, count, "Incremented value does not match expected")    }  }    func testWraparound() {    let counter = Counter(count: Int.max)    counter.increment()        XCTAssertEqual(counter.count, Int.min)  }}
These tests should pass as well.

You can find out more about XCTest in the Apple guide "Testing with Xcode." I hope this was helpful - please feel free to comment if anything is unclear.
Categories: Offsite Blogs

Ajhc is no more

Haskell on Reddit - Sat, 11/29/2014 - 5:12am
Categories: Incoming News

Record equivalent to subclassed member variables?

Haskell on Reddit - Sat, 11/29/2014 - 3:05am

Let's say we're developing some sort of GUI and we want a TextField widget to display text in a window:

data TextField = TextField { text :: String, update :: TextField -> IO TextField, display :: TextField -> IO () }

We can create different kinds of TextFields, e.g.:

{- Assume these are defined: getClockTimeStr :: IO String drawGUIString :: String -> IO () -} clockTextField = TextField { text = "", update = \tf -> getClockTimeStr >>= \time -> return $ tf {text = time}, display = \tf -> drawGUIString $ text tf }

This seems ok so far, but now what if want a more sophisticated TextField that requires keeping track of additional internal state?

For example, maybe we want a complicated TextField that randomly displays either text or an image, and changes the image on mouse click. We now need to store an image in the TextField, but we don't want to just make it an additional field in TextField because it's very specific to this particular TextField behavior. We could parameterize:

data TextField a = TextField { {- ... -} state :: a }

or define a new type ImageTextField except then we lose the ability to have a list of any TextFields with [TextField], which is something we really really want for our GUI windows.

data GUIWindow { {- ... -} textFields :: [TextField] }

In a language with inheritance you can define a TextField abstract class and subclass a ComplicatedTextField with a new image member variable. This isn't applicable here, so I'm trying to figure out the correct alternative. I see two approaches to dealing with this, neither of which seem great:


Approach 1: Closures

{- Assume these are defined: data Image drawGUIImage :: Image -> IO () isMouseClicked :: IO Bool loadRandomImage :: IO Image randomlyTrue :: IO Bool someImage :: Image -} complicatedUpdate :: Image -> TextField -> IO TextField complicatedUpdate image tf = do clicked <- isMouseClicked image' <- if clicked then loadRandomImage else return image return $ tf { update = complicatedUpdate image', display = complicatedDisplay image' } complicatedDisplay :: Image -> TextField -> IO TextField complicatedDisplay image tf = do showImage <- randomlyTrue if showImage then drawGUIImage image else drawGUIString (text tf) complicatedTextField = TextField { text = "foobar", update = complicatedUpdate someImage, display = complicatedDisplay someImage, }

This would work but seems kind of tedious (potentially need to update a lot of functions) and error prone (what if we forget to update a function's closure?)

Approach 2: Data.Dynamic

import Data.Dynamic data TextField = TextField { {- ... -} state :: Dynamic }

and then define data types for each TextField's internal state, and make them instances of Typeable, etc. Now TextField display/update can access the state field and convert from/to Dynamic/the actual data type. This would also work but seems tedious as well (having to convert between the types, and the notion of having a default value for the conversions is odd here).


Is there a better approach to solve this issue? What's the equivalent to subclassed member variables in other languages for haskell records?

submitted by nonexistent_
[link] [20 comments]
Categories: Incoming News

What type does the empty list have

Haskell on Reddit - Sat, 11/29/2014 - 12:41am

In ghci, when I enter :t [], I get [] :: [t]. What does [t] mean?

submitted by lolb
[link] [10 comments]
Categories: Incoming News