News aggregator

Functional programming and William Lawvere's notion of "variable sets"(vs topos of "static sets") in a Topos ...

haskell-cafe - Sat, 08/02/2014 - 7:28am
Hello Haskellers, I have been re-reading William Lawvere's description of "variable sets" (a functor category) in "a elementary topoi" on a discrete poset/preset vs a "abstract sets" in the topos of abstract sets . In Haskell( and other FPLs .. ) aren't "pure" computations just over the topos of abstract sets and "mutable" /"time-varying/stateful" computations aren't just "variable sets" (i.e. a functor over a discrete preset-poset)?? Please forgive my bad English :-( If uncertain aboyt my Englsih, please say so. Kind regards, Vasya P.S. Yes I am familiar with Eugenio Moggi's papers on using monads for stateful computations ..
Categories: Offsite Discussion

Robin KAY: HsQML 0.3.1.1 released: One Thousand Downloads

Planet Haskell - Sat, 08/02/2014 - 5:59am
A few days ago I released HsQML 0.3.1.1, a bug fix to my Haskell binding to the Qt Quick GUI library. You can download the latest release from Hackage as usual.
The primary purpose of this release was to fix issue 20. HsQML has code which monitors variant values created using the Qt library in order to prevent objects which are referenced by a variant from being garbage collected. A flaw in this code caused it to examine the data held inside variants even when it wasn't valid, causing a crash in certain circumstances.
release-0.3.1.1 - 2014.07.31

* Fixed crash when storing Haskell objects in QML variants.
* Fixed corrupted logging output caused by threading.
In related news, HsQML has now reached over 1000 downloads from Hackage since Hackage 2 started collecting download statistics late last year. See the bar chart below:-

The spike in May was owed to the transition to Qt 5 brought about by the release of 0.3.0.0. Hopefully, the graph will climb to new heights with the release of more features in the future!
My target for the next release is to support rendering OpenGL graphics directly from Haskell code and into the QML scene, to better support applications with sophisticated requirements for custom drawing. This is tracked by issue 10.
Categories: Offsite Blogs

Proposal: add unfoldr1 to the somewhere in base

libraries list - Sat, 08/02/2014 - 12:21am
Way back in 2001, Shin-Cheng Mu proposed an unfoldr1 combinator: http://code.haskell.org/~dons/haskell-1990-2000/msg06775.html I discussed this a bit with shachaf in #haskell, and he noted that a similar function, with a slightly different but isomorphic type, appears in Edward Kmett's semigroups package as the unfoldr for NonEmpty. I propose that we add this. It can be written unfoldr1 :: (b -> (a, Maybe b)) -> b -> [a] unfoldr1 f b = go b where go b = case f b of (a, may_b) -> a : maybe [] go may_b With the appropriate RULES, it can be wrapped up in build and fuse properly. I'd love to see this written as an unfoldr instead. Does anyone know if that's possible?
Categories: Offsite Discussion

ICFP 2014 Final Call for Participation

haskell-cafe - Fri, 08/01/2014 - 10:51pm
[ Early registration ends 3 Aug; Invited speakers and conference program have been announced. ] ===================================================================== Final Call for Participation ICFP 2014 19th ACM SIGPLAN International Conference on Functional Programming and affiliated events August 31 - September 6, 2014 Gothenburg, Swedenhttp://icfpconference.org/icfp2014/ ===================================================================== ICFP provides a forum for researchers and developers to hear about the latest work on the design, implementations, principles, and uses of functional programming. The conference covers the entire spectrum of work, from practice to theory, including its peripheries. A full week dedicated to functional programming: 1 conference, 1 symposium, 10 workshops, tutorials, programming contest results, student research competition * Program: http://icfpconference.org/icfp2014/program.html * Accepted Papers: http://icfpconference.org/icfp2014/accepted.html *
Categories: Offsite Discussion

ICFP 2014 Final Call for Participation

General haskell list - Fri, 08/01/2014 - 10:50pm
[ Early registration ends 3 Aug; Invited speakers and conference program have been announced. ] ===================================================================== Final Call for Participation ICFP 2014 19th ACM SIGPLAN International Conference on Functional Programming and affiliated events August 31 - September 6, 2014 Gothenburg, Swedenhttp://icfpconference.org/icfp2014/ ===================================================================== ICFP provides a forum for researchers and developers to hear about the latest work on the design, implementations, principles, and uses of functional programming. The conference covers the entire spectrum of work, from practice to theory, including its peripheries. A full week dedicated to functional programming: 1 conference, 1 symposium, 10 workshops, tutorials, programming contest results, student research competition * Program: http://icfpconference.org/icfp2014/program.html * Accepted Papers: http://icfpconference.org/icfp2014/accepted.html *
Categories: Incoming News

EsseOS: Haskell-based tailored services for the cloud

haskell-cafe - Fri, 08/01/2014 - 6:14pm
Hi, I came across this seemingly interesting paper: EsseOS: Haskell-based tailored services for the cloud http://dl.acm.org/citation.cfm?id=2541587 which is unfortunately behind a paywall. I was wondering if someone knew about a freely accessible version of that paper, or about some project page, or just heard of it. Thank you, Thu
Categories: Offsite Discussion

haskell on Debian

haskell-cafe - Fri, 08/01/2014 - 4:43pm
I want to reinstall Haskell on Debian (in Virtualbox on Windows). So: apt-get remove haskell-platform Deleted all maps with packages in it. apt-get install haskell-platform (installing previous selected ... etc) cabal update All this without errors of warnings. cabal install cabal-install Error: /var/lib/ghc/package.conf.d: openFile: does not exist Why this error? Setup doesn't create this directory? _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Douglas M. Auclair (geophf): 1HaskellADay July 2014 problems and solutions

Planet Haskell - Fri, 08/01/2014 - 3:57pm

  • July 1st, 2014: (text:) "Hi, all! @1HaskellADay problems are back! #YAY First (renewed) problem: a verbose way of saying, 'Give me a deque!' http://lpaste.net/106748" Deque, last, and all that (verbose version with hints) (solution: Deque the halls (with my solution): Data.Deque)
  • July 2nd, 2014: (text:) "Today's Haskell exercise: Vectors, length in constant time, and (bonus) reverse return in constant time. http://lpaste.net/106843" Vector (solution: Vector: Magnitude, and Direction, OH, YEAH! Data.Vector)
  • July 4th, 2014: (text:) "Today's exercise(s). pack/unpack. encode/decode. Cheer up, sweet B'Genes! http://lpaste.net/106912" Cheer up, Sweet B'Genes (solution: GATTACA)
  • July 7th, 2014: (text:) "#haskell daily exercise: ROLL with it, Baby! http://lpaste.net/107047  ('cause I'm feeling a little #forth'y')" Roll (solution: Rollin' on the (finite) river)
  • Bonus problem: July 7th, 2014: (text:) "For those who found the 'roll'-exercise trivial; here's (a more than) a bit more of a challenge for you to play with. http://lpaste.net/107023" Acid rules! (solution: "A solution set to today's challenge exercise: BASIC ... http://lpaste.net/107069  ... and Acidic http://lpaste.net/107071  ... WHEW! That was fun!" BASIC ... and Acitic)
  • July 8th, 2014: (text:) "Today's #Haskell exercise: LOTTO! Powerball! Mega-whatever! Who's the big winner? http://lpaste.net/107104" Lotto (solution: "And the big winner today is ... solution-set to today's #Haskell lotto exercise http://lpaste.net/107130" ... and the winner is ...)
  • Bonus problem: July 8th, 2014: (text:) "#bonus #haskell exercise: Well, that was RND... Randomness, and such (or 'as such') http://lpaste.net/107105" Well, that was RND (solution: For YESTERDAY's bonus question of roll-your-own-rnd-nbr-generator, here's one as comonadic cellular automata (*WHEW*) http://lpaste.net/107205: Data.Random)
  • July 9th, 2014: (text:) "Okay, ... WHERE did yesterday and today GO? :/ #haskell exercise today: "Hey, Buddy!" http://lpaste.net/107181  I will post solution in 4 hours" Hey, Buddy! Distinct sets-of-an-original-set. (solution: "Here's a story ..." A(n inefficient) solution to bunches and cliques. http://lpaste.net/107273" Brady Bunch)
  • July 10th, 2014: (text:) "Today's #haskell list-exercise: "Get out of the pool!" http://lpaste.net/107286  Will post a solution at 9 pm EDT (which is what time CET? ;)" (solution: "She's a supa-freak! She's supa-freaky! (Bass riff) A solution to today's #haskell exercise about list-length-ordering http://lpaste.net/107308")
  • July 11th, 2014: (text:) ""It's Friday, Friday!" So, does that mean Rebecca Black wants to code #haskell, too? Today is a Calendar #exercise http://lpaste.net/107328" (solution: ""In a New York Minute": a solution to today's #haskell exercise that took WAAAY more than a minute to complete! #WHEW http://lpaste.net/107370")
  • July 14th, 2014: (text:) "Today's #haskell exercise: isPrime with some numbers to test against. They aren't even really Mp-hard. ;) http://lpaste.net/107463" First stab at primality-test (solution: "A simple, straightforward stab at the test for primality. #haskell #exercise http://lpaste.net/107483" The start of a primal inquiry
  • July 15th, 2014: (text:) "Primes and ... 'not-primes.' For a prime, p, a run of p-consecutive 'plain' numbers is today's #haskell exercise: http://lpaste.net/107536" (solution: "So ya gotta ask yerself da question: are ya feelin' lucky, punk? Run of p non-primes in linear time http://lpaste.net/107549  #haskell exercise." Alternate solution by Gautier: http://lpaste.net/107549)
  • July 16th, 2014: (text:) "Difference lists? We no need no steenkin' Difference lists!" http://lpaste.net/107593  DList in #haskell for today's exercise. (solution: "DLists? We got'cher DList right here! A solution to today's #haskell exercise is posted at http://lpaste.net/107607")
  • July 17th, 2014 (text:) "http://lpaste.net/107652 Prélude à l'après-midi d'un Stream ... I thought that last word was ... something else...? #haskell exercise today." Comonads for lists and Id. (solution: "Control.Comonad: That was easy! http://lpaste.net/107661 #haskell exercise #solution" Learn you a Comonad for Greater GoodFunny story, bro'! id is not necessarily Id. (I knew that.) http://lpaste.net/107662 #haskell solution")
  • Bonus exercise: July 17th, 2014 (text:) "Streams are natural, streams are fun, streams are best when ... THEY'RE BONUS QUESTIONS! #bonus #haskell exercise http://lpaste.net/107655" LET'S GET THIS PARTY STARTED! (solution: "Take this Stream and ... it! #solution to today's #haskell #bonus exercises http://lpaste.net/107665")
  • July 18th, 2014: (text: "Today's #haskell exercise: Frère Mersenne would like a prime, please. http://lpaste.net/107700") (see solution next bullet)
  • Bonus exercise: July 18th, 2014 (text: "#bonus prime-time! Frère Mersenne would be pleased with a partial proof of a prime ... in good time. http://lpaste.net/107701") (solution: "A #haskell #solution for (monadic?) primes and the #bonus interruptible primes. http://lpaste.net/107708") Primary primes.
  • Bonus-bonus exercise: July 18th, 2014 (text: "Ooh! π-charts! No. Wait. #bonus-bonus #haskell exercise. http://lpaste.net/107702") (solution: "#bonus-bonus: a #solution http://lpaste.net/107718")


  • July 21st, 2014: (text: "Demonstrating coprimality of two integers with examples #haskell exercise http://lpaste.net/107819") (solution: "A coprimes solution #haskell problem is at http://lpaste.net/107843")
  • July 22nd, 2014: (text: "The prime factors of a number (and grouping thereof) as today's #haskell exercise. http://lpaste.net/107878") (solution: "OKAY, THEN! Some prime factors for ya, ... after much iteration (torquing) over this #haskell exercise solution. http://lpaste.net/107939")
  • Bonus exercise: July 22nd, 2014: ("For today's #bonus #haskell exercise you'll find a Bag 'o gold at the end of the rainbow http://lpaste.net/107881") (solution: "Second things first: a definition for the Bag data type as today's #bonus #haskell exercise. http://lpaste.net/107815")
  • July 23rd, 2014: (text: "Today's #haskell exercise, two variations of Euler's totient function http://lpaste.net/107955") (solution: "And, for a very small φ ... http://lpaste.net/107972  is a solution-set to today's #haskell exercise.")
  • July 24th, 2014: (text: "WEAKSAUCE! Goldbach's conjecture irreverently presented as a #haskell exercise. http://lpaste.net/108019") (solution: "That solution to today's #haskell exercise will cost you one Goldbach (*groan!*) http://lpaste.net/108059")
  • July 25th, 2014: LOGIC! Peano series: it's as easy as p1, p2, p3 ... http://lpaste.net/108099 ... in today's #haskell exercise. "Excuse me, Miss, where do we put this Grande Peano?" A solution to today's #Haskell exercise in the HA!-DSL http://lpaste.net/108140
  • Bonus: July 25th, 2014: http://lpaste.net/108108 Bonus #haskell problem for today. But not as easy as λa, λb, λc ... Church numerals and booleans. Correction: Ooh! forall! Church encodings and Haskell have a funny-kind of relationship. Updated the #bonus #haskell exercise with rank-types and forall. Solution: "Gimme that olde-time Church encoding ... it's good enough for me!" A solution to today's #bonus #haskell exercise http://lpaste.net/108114
  • July 28th, 2014: George Boole, I presume? Today's #haskell exercise: http://lpaste.net/108272. Solution: This and-or That ... a NAND-implementation of today's #haskell exercise at http://lpaste.net/108295
  • July 29th, 2014: Readin' 'Ritin' 'Rithmetic: today's #haskell exercise http://lpaste.net/108358 Solution: That's alotta NANDs! A solution to today's exercise at http://lpaste.net/108387
  • July 30th, 2014: ACHTUNG! BlinkenLights! Today's #haskell exercise http://lpaste.net/108420. Solution: Let it Snow! Let it Snow! Let it (binary) Snow! A solution to today's exercise is at http://lpaste.net/108429 
  • July 31st, 2014: π-time! http://lpaste.net/108485 Today's #haskell exercise. BLARG! UPDATE! Please read the update attached to the problem statement, simplifying the calculation quite a bit: http://lpaste.net/108485 Solution: Apple or coconut π? A solution to today's problem http://lpaste.net/108494

Notes on the problems
  • July 9th, 2014. I didn't quite know how to go about this, so I made several attempts with the State pattern. But how to describe it? It's the base pool from which you draw, and each (sub-)choice-point affects it, what's that type? I spent way too much time trying to discern the type, and failing. But now, a much simpler approach suggests itself to me (after experiencing the New York Minute exercise): this is simply a permutation of the list, and then that permutation is partitioned by the sizes of the groups! Implementing permute-then-partition is a much simpler approach than tracking some monster monadic state transformer.

    No, that didn't work, either. A permutation will give you [[1,2], ...] and[[2,1], ...] That is, all solutions, even the redundant ones. So, I reworked the problem simply following the data. With takeout feeding the iterative-deepening function, I finally got a guarded state-like thingie working fast and correctly. The new solution is on the same page as the old one.
  • July 11th, 2014. The New York Minute problem demonstrates the implementation of a rule-based classifer. It takes unclassified numeric inputs, and based on the cues from the rules, either types each number into day, month, year, hour, minute, or rejects the input data as unclassifiable. I was pleased to have implemented this entire system in less than two days of work! Sweet!
  • July 22nd, 2014. So, I've been running up against the double-exponential cost of computing a stream of primes for some time now since I gave the solution to the question of demonstrating the Prime Number Theorem. So now I have to tackle of bringing down that extraordinary, or unreasonable, cost down to something useable, and along those lines (of feasibility), I'm thinking of instead of regenerating and re-searching the primesish stream that we have some kind of State-like thing of ([already generated primes], indexed-primesish) ... something like that. Solution: "General improvement of problem-solving modules in anticipation of solving today's #haskell exercise, including primes: http://lpaste.net/107480"
Categories: Offsite Blogs

Haskell and IO monads

Haskell on Reddit - Fri, 08/01/2014 - 2:09pm

Hey there,

having a list of names of files or folders I'm trying to do the following:

given an (x:xs), if x is a directory, get his content and add it to the list. If x is a file read it.

This is what I'm trying to do:

yascc :: [String] -> IO() yascc (x:xs) = do isDir <- doesDirectoryExist x if isDir then content <- getDirectoryContent x

The rest of the code is not provided because I get a syntactic error in the last line. What is the correct way of doing this?(Not asking for code)

Thank you.

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

Edward Kmett: Letter to a Young Haskell Enthusiast

Planet Haskell - Fri, 08/01/2014 - 1:44pm

The following letter is not about what "old hands" know and newcomers do not. Instead, it is about lessons that we all need to learn more than once, and remind ourselves of. It is about tendencies that are common, and understandable, and come with the flush of excitement of learning any new thing that we understand is important, and about the difficulty, always, in trying to decide how best to convey that excitement and sense of importance to others, in a way that they will listen. It is written more specifically, but only because I have found that if we don't talk specifics as well as generalities, the generalities make no sense. This holds for algebraic structures, and it holds for other, vaguer concepts no less. It is a letter full of things I want to remember, as well as of advice I want to share. I expect I will want to remind myself of it when I encounter somebody who is wrong on the internet, which, I understand, may occur on rare occasion.

You’ve recently entered the world of strongly typed functional programming, and you’ve decided it is great. You’ve written a program or two or a library or two, and you’re getting the hang of it. You hop on IRC and hear new words and ideas every day. There are always new concepts to learn, new libraries to explore, new ways to refactor your code, new typeclasses to make instances of.

Now, you’re a social person, and you want to go forth and share all the great things you’ve learned. And you have learned enough to distinguish some true statements from some false statements, and you want to go and slay all the false statements in the world.

Is this really what you want to do? Do you want to help people, do you want to teach people new wonderful things? Do you want to share the things that excite you? Or do you want to feel better about yourself, confirm that you are programming better, confirm that you are smarter and know more, reassure yourself that your adherence to a niche language is ok by striking out against the mainstream? Of course, you want to do the former. But a part of you probably secretly wants to do the latter, because in my experience that part is in all of us. It is our ego, and it drives us to great things, but it also can hold us back, make us act like jerks, and, worst of all, stand in the way of communicating with others about what we truly care about.

Haskell wasn’t built on great ideas, although it has those. It was built on a culture of how ideas are treated. It was not built on slaying others’ dragons, but on finding our own way; not tearing down rotten ideas (no matter how rotten) but showing by example how we didn’t need those ideas after all.

In functional programming, our proofs are not by contradiction, but by construction. If you want to teach functional programming, or preach functional programming, or just to even have productive discussions as we all build libraries and projects together, it will serve you well to learn that ethic.

You know better than the next developer, or so you think. This is because of something you have learned. So how do you help them want to learn it too? You do not tell them this is a language for smart people. You do not tell them you are smart because you use this language. You tell them that types are for fallible people, like we all are. They help us reason and catch our mistakes, because while software has grown more complex, we’re still stuck with the same old brains. If they tell you they don’t need types to catch errors, tell them that they must be much smarter than you, because you sure do. But even more, tell them that all the brainpower they use to not need types could turn into even greater, bigger, and more creative ideas if they let the compiler help them.

This is not a language for clever people, although there are clever things that can be done in this language. It is a language for simple things and clever things alike, and sometimes we want to be simple, and sometimes we want to be clever. But we don’t give bonus points for being clever. Sometimes, it’s just fun, like solving a crossword puzzle or playing a tricky Bach prelude, or learning a tango. We want to keep simple things simple so that tricky things are possible.

It is not a language that is “more mathematical” or “for math” or “about math”. Yes, in a deep formal sense, programming is math. But when someone objects to this, this is not because they are a dumb person, a bad person, or a malicious person. They object because they have had a bad notion of math foisted on them. “Math” is the thing that people wield over them to tell them they are not good enough, that they cannot learn things, that they don’t have the mindset for it. That’s a dirty lie. Math is not calculation — that’s what computers are for. Nor is math just abstract symbols. Nor is math a prerequisite for Haskell. If anything, Haskell might be what makes somebody find math interesting at all. Our equation should not be that math is hard, and so programming is hard. Rather, it should be that programming can be fun, and this means that math can be fun too. Some may object that programming is not only math, because it is engineering as well, and creativity, and practical tradeoffs. But, surprisingly, these are also elements of the practice of math, if not the textbooks we are given.

I have known great Haskell programmers, and even great computer scientists who know only a little linear algebra maybe, or never bothered to pick up category theory. You don’t need that stuff to be a great Haskell programmer. It might be one way. The only thing you need category theory for is to take great categorical and mathematical concepts from the world and import them back to programming, and translate them along the way so that others don’t need to make the same journey you did. And you don’t even need to do that, if you have patience, because somebody else will come along and do it for you, eventually.

The most important thing, though not hardest, about teaching and spreading knowledge is to emphasize that this is for everyone. Nobody is too young, too inexperienced, too old, too set in their ways, too excitable, insufficiently mathematical, etc. Believe in everyone, attack nobody, even the trolliest.* Attacking somebody builds a culture of sniping and argumentativeness. It spreads to the second trolliest, and soforth, and then eventually to an innocent bystander who just says the wrong thing to spark bad memories of the last big argument.

The hardest thing, and the second most important, is to put aside your pride. If you want to teach people, you have to empathize with how they think, and also with how they feel. If your primary goal is to spread knowledge, then you must be relentlessly self-critical of anything you do or say that gets in the way of that. And you don’t get to judge that — others do. And you must just believe them. I told you this was hard. So if somebody finds you offputting, that’s your fault. If you say something and somebody is hurt or takes offense, it is not their fault for being upset, or feeling bad. This is not about what is abstractly hurtful in a cosmic sense; it is about the fact that you have failed, concretely, to communicate as you desired. So accept the criticism, apologize for giving offense (not just for having upset someone but also for what you did to hurt them), and attempt to learn why they feel how they feel, for next time.

Note that if you have made somebody feel crummy, they may not be in a mood to explain why or how, because their opinion of you has already plummeted. So don’t declare that they must or should explain themselves to you, although you may politely ask. Remember that knowledge does not stand above human behavior. Often, you don't need to know exactly why a person feels the way they do, only that they do, so you can respect that. If you find yourself demanding explanations, ask yourself, if you knew this thing, would that change your behavior? How? If not, then learn to let it go.

Remember also that they were put off by your actions, not by your existence. It is easy to miss this distinction and react defensively. "Fight-or-flight" stands in the way of clear thinking and your ability to empathize; try taking a breath and maybe a walk until the adrenaline isn't derailing your true intentions.

Will this leave you satisfied? That depends. If your goal is to understand everything and have everybody agree with regards to everything that is in some sense objectively true, it will not. If your goal is to have the widest, nicest, most diverse, and most fun Haskell community possible, and to interact in an atmosphere of mutual respect and consideration, then it is the only thing that will leave you satisfied.

If you make even the most modest (to your mind) mistake, be it in social interaction or technical detail, be quick to apologize and retract, and do so freely. What is there to lose? Only your pride. Who keeps track? Only you. What is there to gain? Integrity, and ultimately that integrity will feel far more fulfilling than the cheap passing thrills of cutting somebody else down or deflecting their concerns.

Sometimes it may be, for whatever reason, that somebody doesn’t want to talk to you, because at some point your conversation turned into an argument. Maybe they did it, maybe you did it, maybe you did it together. It doesn’t matter, learn to walk away. Learn from the experience how to communicate better, how to avoid that pattern, how to always be the more positive, more friendly, more forward-looking. Take satisfaction in the effort in that. Don’t talk about them behind their back, because that will only fuel your own bad impulses. Instead, think about how you can change.

Your self-esteem doesn’t need your help. You may feel you need to prove yourself, but you don't. Other people, in general, have better things to do with their time than judge you, even when you may sometimes feel otherwise. You know you’re talented, that you have learned things, and built things, and that this will be recognized in time. Nobody else wants to hear it from you, and the more they hear it, the less they will believe it, and the more it will distract from what you really want, which is not to feed your ego, not to be great, but to accomplish something great, or even just to find others to share something great with. In fact, if anyone's self-esteem should be cared for, it is that of the people you are talking to. The more confident they are in their capacity and their worth, the more willing they will be to learn new things, and to acknowledge that their knowledge, like all of ours, is limited and partial. You must believe in yourself to be willing to learn new things, and if you want to cultivate more learners, you must cultivate that self-belief in others.

Knowledge is not imposing. Knowledge is fun. Anyone, given time and inclination, can acquire it. Don’t only lecture, but continue to learn, because there is always much more than you know. (And if there wasn’t, wow, that would be depressing, because what would there be to learn next?) Learn to value all opinions, because they all come from experiences, and all those experiences have something to teach us. Dynamic typing advocates have brought us great leaps in JIT techniques. If you’re interested in certain numerical optimizations, you need to turn to work pioneered in C++ or Fortran. Like you, I would rather write in Haskell. But it is not just the tools that matter but the ideas, and you will find they come from everywhere.

In fact, we have so much to learn that we direct our learning by setting up barriers — declaring certain tools, fields, languages, or communities not worth our time. This isn’t because they have nothing to offer, but it is a crutch for us to shortcut evaluating too many options all at once. It is fine, and in fact necessary, to narrow the scope of your knowledge to increase its depth. But be glad that others are charting other paths! Who knows what they will bring back from those explorations.

If somebody is chatting about programming on the internet, they’re already ahead of the pack, already interested in craft and knowledge. You may not share their opinions, but you have things to learn from one another, always. Maybe the time and place aren’t right to share ideas and go over disputes. That’s ok. There will be another time and place, or maybe there won’t be. There is a big internet full of people, and you don’t need to be everybody’s friend or everybody’s mentor. You should just avoid being anybody’s enemy, because your time and theirs is too precious to waste it on hard feelings instead of learning new cool stuff.

This advice is not a one-time proposition. Every time we learn something new and want to share it, we face these issues all over again -- the desire to proclaim, to overturn received wisdom all at once -- and the worse the received wisdom, the more vehemently we want to strike out. But if we are generous listeners and attentive teachers, we not only teach better and spread more knowledge, but also learn more, and enjoy ourselves more in the process. To paraphrase Rilke’s “Letter to a Young Poet”: Knowledge is good if it has sprung from necessity. In this nature of its origin lies the judgement of it: there is no other.

Thanks to the various folks in and around the Haskell world who have helped me refine this article. I don't name you only because I don't want to imply your endorsement, or give what is still, at base, a very personal take, any particular sort of imprimatur of a broader group of people, all of whom I suspect will disagree among themselves and with me about various specifics.

*: It has been pointed out to me that this advice is not universal. Clearly there are some things that deserve more pointed responses. Bigotry, outright harassment and poisonous behavior, etc. So please read this paragraph only as it applies to talking about technical issues, not as regards to many other things, where there are people better equipped than me to give advice.

Categories: Offsite Blogs

Robert Harper: A few new papers

Planet Haskell - Fri, 08/01/2014 - 12:40pm

I’ve just updated my web page with links to some new papers that are now available:

  1. Homotopical Patch Theory” by Carlo Angiuli, Ed Morehouse, Dan Licata, and Robert Harper. To appear, ICFP, Gothenburg, October 2014. We’re also preparing an expanded version with a new appendix containing material that didn’t make the cut for ICFP. (Why do we still have such rigid space limitations?  And why do we have such restricted pre-publication deadlines as we go through the charade of there being a “printing” of the proceedings? One day soon CS will step into its own bright new future.). The point of the paper is to show how to apply basic methods of homotopy theory to various equational theories of patches for various sorts of data. One may see it as an application of functorial semantics in HoTT, in which theories are “implemented” by interpretation into a universe of sets. The patch laws are necessarily respected by any such interpretation, since they are just cells of higher dimension and functors must behave functorially at all dimensions.
  2. Cache Efficient Functional Algorithms” by Guy E. Blelloch and Robert Harper. To appear, Comm. ACM Research Highlight this fall.  Rewritten version of POPL 2013 paper meant for a broad CS audience.  Part of a larger effort to promote integration of combinatorial theory with logical and semantic theory, two theory communities that, in the U.S. at least, ignore each other completely.  (Well, to be plain about it, it seems to me that the ignoring goes more in one direction than the other.)  Cost semantics is one bridge between the two schools of thought, abandoning the age-old “reason about the compiled code” model used in algorithm analysis.  Here we show that one can reason about spatial locality at the abstract level, without having to drop-down to low-level of how data structures are represented and allocated in memory.
  3. Refining Objects (Preliminary Summary)” by Robert Harper and Rowan Davies. To appear, Luca Cardelli 60th Birthday Celebration, Cambridge, October, 2014.  A paper I’ve been meaning to write sometime over the last 15 years, and finally saw the right opportunity, with Luca’s symposium coming up and Rowan Davies visiting Carnegie Mellon this past spring.  Plus it was a nice project to get me started working again after I was so rudely interrupted this past fall and winter.  Provides a different take on typing for dynamic dispatch that avoids the ad hoc methods introduced for oop, and instead deploying standard structural and behavioral typing techniques to do more with less.  This paper is a first cut as proof of concept, but it is clear that much more can be said here, all within the framework of standard proof-theoretic and realizability-theoretic interpretations of types.  It would help to have read the relevant parts of PFPL, particularly the under-development second edition, which provides the background elided in the paper.
  4. Correctness of Compiling Polymorphism to Dynamic Typing” by Kuen-Bang Hou (Favonia), Nick Benton, and Robert Harper, draft (summer 2014).  Classically polymorphic type assignment starts with untyped -terms and assigns types to them as descriptions of their behavior.  Viewed as a compilation strategy for a polymorphic language, type assignment is rather crude in that every expression is compiled in uni-typed form, complete with the overhead of run-time classification and class checking.  A more subtle strategy is to maintain as much structural typing as possible, resorting to the use of dynamic typing (recursive types, naturally) only for variable types.  The catch is that polymorphic instantiation requires computation to resolve the incompatibility between, say, a bare natural number, which you want to compute with, and its encoding as a value of the one true dynamic type, which you never want but are stuck with in dynamic languages.  In this paper we work out an efficient compilation scheme that maximizes statically available information, and makes use of dynamic typing only insofar as the program demands we do so.  Of course there are better ways to compile polymorphism, but this style is essentially forced on you by virtual machines such as the JVM, so it is worth studying the correctness properties of the translation, which we do here making use of a combination of structural and behavioral typing.

I hope to comment here more fully on these papers in the near future, but I also have a number of other essays queued up to go out as soon as I can find the time to write them.  Meanwhile, other deadlines loom large.

[Update: added fourth item neglected in first draft.  Revise formatting.  Add links to people. Brief summary of patch theory paper.  Minor typographical corrections.]

[Update: the promised expanded version of the forthcoming ICFP paper is now available.]


Filed under: Programming, Research Tagged: behavioral typing, cache efficient algorithms, compilation, cost semantics, dynamic dispatch, homotopy type theory, ICFP, polymorphism, structural typing, type refinements
Categories: Offsite Blogs

Splitting Network.URI from the network package

libraries list - Fri, 08/01/2014 - 12:31pm
This was brought up last year[1], and I'd like to bring it up again, based on a recent issue I was working through with a user[2]. I realize that this is a breaking change, but: 1. It's a minor breaking change: you simply need to add an extra package to your build-depends. 2. The problems caused by having a parsec dependency in network can be severe, especially for new users (I'll describe the details after the proposal). Concretely, I believe we should do the following: 1. Create a new package, network-uri, version 2.5.0.0, which exposes no modules and has an upper bound `network < 2.6. 2. Create a second release of network-uri, version 3.0.0.0, which provides the Network.URI module verbatim as provided by the network package today, and has a lower bound `network >= 3.0`. 3. Release network version 3.0.0.0, with no changes from the currently released version, except that (a) no Network.URI module is provided, and (b) there is no parsec dependency. I don't remember how the discussion went last time, but
Categories: Offsite Discussion

Does web-based email harm mailman lists?

haskell-cafe - Fri, 08/01/2014 - 10:46am
Beautiful haskell people, Ever noticed the lacunae on some list threads? Someone hits reply and instead of reflecting via mailman, it goes direct to OP. OP notices absence of To:haskell-cafe and adds it back in in their reply to the reply. End result? The thread looks like OP having a convo with themselves. Unless you look at the quoted parts, which you have to click to reveal in web-based email. The convention, say with a google-groups based mailing list, is that conversations in mailing list are public by default. With some manual C&P, you can email responses in private. For cafe participants using web-based email, the situation is reversed, through no fault of their own. Approx 18 months ago, the haskell-beginners list suffered the same problem [1]. After some digging, it looks like there's a configurable option to Do The Right Thing: http://ccit.mines.edu/Mailman-FAQ#25 I was also privately emailed that there are downsides I wasn't aware of: Reply-To Munging Considered Harmful http://www.unicom.
Categories: Offsite Discussion

Attempting to create a new monad / dsl - need help

Haskell on Reddit - Fri, 08/01/2014 - 9:26am

I may be trying to do something impossible here but would like confirmation.

Requirements:

  • Creating a task requires only a task name and a function

    createTask :: String -> (TaskContext -> IO a) -> Task a
  • Task results can be used by subsequent tasks

    do x <- firstTask; secondTask x;

The above is really easy and straight forward.

Here is the hard part:

  • Task metadata can be accessed without actually running the task.
  • In other words, I would like to be able to get the names, order, and total count of all tasks to be run without ever running the task.

I suspect there is some sort of indexed state/continuation monad that could do this; but haven't been able to figure it out.

Any help would be appreciated.

submitted by recty
[link] [13 comments]
Categories: Incoming News

What would be necessary to use ZeroVM as a GHC back end?

Haskell on Reddit - Fri, 08/01/2014 - 9:06am

I just wonder (naive as I am) if it is possible to use GHC to create ZeroVM binaries?

At first glance I see that GHC uses GCC (or LLVM) for compilation and ZeroVM compilation is "just another GCC toolchain". So how hard could that be? (Famous last words)

ZeroVM: http://docs.zerovm.org

submitted by goliatskipson
[link] [6 comments]
Categories: Incoming News

Tor project and Haskell (FPL) ,..

haskell-cafe - Fri, 08/01/2014 - 7:58am
I wasn't trying to offend anybody .... Only trying to provoke a lively discussion in order lift all boats. Sometimes one sentence IHMO provokes thought. In any case I appreciate all responders :-) Kind thanks friends. Vasya _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Well-Typed.Com: Debugging Haskell at assembly level by scripting lldb in Python

Planet Haskell - Fri, 08/01/2014 - 3:17am

Haskell programmers tend to spend far less time with debuggers than programmers in other languages. Partly this is because for pure code debuggers are of limited value anyway, and Haskell’s type system is so strong that a lot of bugs are caught at compile time rather than at runtime. Moreover, Haskell is a managed language – like Java, say – and errors are turned into exceptions. Unlike in unmanaged languages such as C “true” runtime errors such as segmentation faults almost never happen.

I say “almost” because they can happen: either because of bugs in ghc or the Haskell runtime, or because we are doing low level stuff in our own Haskell code. When they do happen we have to drop down to a system debugger such as lldb or gdb, but debugging Haskell at that level can be difficult because Haskell’s execution model is so different from the execution model of imperative languages. In particular, compiled Haskell code barely makes any use of the system stack or function calls, and uses a continuation passing style instead (see my previous blog posts Understanding the Stack and Understanding the RealWorld). In this blog post I will explain a technique I sometimes use to help diagnose low-level problems.

Since I work on OSX I will be using lldb as my debugger. if you are using gdb you can probably use similar techniques; The LLDB Debugger shows how gdb and lldb commands correlate, and the ghc wiki also lists some tips. However, I have no experience with scripting gdb so your mileage may vary.

Description of the problem

As our running example I will use a bug that I was tracking down in a client project. The details of the project don’t matter so much, except that this project happens to use the GHC API to compile Haskell code—at runtime—into bytecode and then run it; moreover, it also—dynamically, at runtime—loads C object files into memory.

In one example run it loads the (compiled) C code

#include <stdio.h> void hello(void) { printf("hello\n"); }

and then compiles and runs this Haskell code:

{-# LANGUAGE ForeignFunctionInterface #-} module Main where foreign import ccall "hello" hello :: IO () main = hello

Sadly, however, this resulted in total system crash.

Starting point

By attaching lldb to the running process we got a tiny bit more information about the crash:

* thread #4: tid = 0x3550aa, 0x000000010b3b8226, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x000000010b3b8226 -> 0x10b3b8226: addb %al, (%rax) 0x10b3b8228: addb %al, (%rax) 0x10b3b822a: addb %al, (%rax) 0x10b3b822c: addb %al, (%rax)

It turns out we have a null-pointer dereferencing here. Anybody who has spent any time debugging Intel assembly code however will realize that this particular instruction

addb %al, (%rax)

is in fact the decoding of zero:

(lldb) memory read -c 8 0x10b3b8226 0x10b3b8226: 00 00 00 00 00 00 00 00 ........

In other words, chances are good we were never meant to execute this instruction at all. Unfortunately, asking lldb for a backtrace tells us absolutely nothing new:

(lldb) bt * thread #4: tid = 0x3550aa, 0x000000010b3b8226, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) * frame #0: 0x000000010b3b8226 Finding a call chain

The lack of a suitable backtrace in lldb is not surprising, since compiled Haskell code barely makes use of the system stack. Instead, the runtime maintains its own stack, and code is compiled into a continuation passing style. For example, if we have the Haskell code

functionA :: IO () functionA = do .. ; functionB ; .. functionB :: () functionB = do .. ; functionC ; .. functionC :: IO () functionC = .. crash .. main :: IO () main = functionA

and we step through the execution of this program in lldb, and we ask for a backtrace when we start executing function A all we get is

(lldb) bt * thread #1: tid = 0x379731, 0x0000000100000a20 Main`A_functionA_info, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 * frame #0: 0x0000000100000a20 Main`A_functionA_info

with no mention of main. Similarly, the backtraces on entry to functions B and C are

* thread #1: tid = 0x379731, 0x0000000100000b90 Main`B_functionB_info, queue = 'com.apple.main-thread', stop reason = breakpoint 2.1 * frame #0: 0x0000000100000b90 Main`B_functionB_info

and

* thread #1: tid = 0x379731, 0x0000000100000c88 Main`C_functionC_info, queue = 'com.apple.main-thread', stop reason = breakpoint 3.1 * frame #0: 0x0000000100000c88 Main`C_functionC_info

none of which is particularly informative. However, stepping manually through the program we do first see function A on the (singleton) call stack, then function B, and finally function C. Thus, by the time we reach function C, we have discovered a call chain A, B, C—it’s just that it involves quite a bit of manual work.

Scripting lldb

Fortunately, lldb can be scripted (see Using Scripting and Python to Debug in LLDB and the LLDB Python Reference). What we want to do is keep stepping through the code, showing the top-level (and quite possibly only) function at the top of the call stack at each step, until we crash.

We can use the following Python script to do this:

import lldb def step_func(debugger, command, result, internal_dict): thread = debugger.GetSelectedTarget().GetProcess().GetSelectedThread() while True: thread.StepOver() stream = lldb.SBStream() thread.GetStatus(stream) description = stream.GetData() print description if thread.GetStopReason() == lldb.eStopReasonException: break def __lldb_init_module(debugger, dict): debugger.HandleCommand('command script add -f %s.step_func sf' % __name__)

For the above example, we might use this as follows: we load our application into lldb

# lldb Main Current executable set to 'Main' (x86_64).

register our new command sf

(lldb) command script import mystep.py

set a breakpoint where we want to start stepping

(lldb) breakpoint set -n A_functionA_info Breakpoint 1: where = Main`A_functionA_info, address = 0x0000000100000b90

run to the breakpoint:

(lldb) run Process 54082 launched: 'Main' (x86_64) Process 54082 stopped * thread #1: tid = 0x384510, 0x0000000100000b90 Main`A_functionA_info, queue = 'com.apple.main-thread', stop reason = breakpoint 1.1 frame #0: 0x0000000100000b90 Main`A_functionA_info

and then use sf to find a call-trace until we crash:

(lldb) sf ... * thread #1: tid = 0x384510, 0x0000000100000bf0 Main`B_functionB_info, queue = 'com.apple.main-thread', stop reason = instruction step over frame #0: 0x0000000100000bf0 Main`B_functionB_info Main`B_functionB_info: ... * thread #1: tid = 0x384510, 0x0000000100000c78 Main`C_functionC_info, queue = 'com.apple.main-thread', stop reason = instruction step over frame #0: 0x0000000100000c78 Main`C_functionC_info Main`C_functionC_info: ... * thread #1: tid = 0x384510, 0x0000000100000d20 Main`crash + 16 at crash.c:3, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x0000000100000d20 Main`crash + 16 at crash.c:3

Note that if you are using the threaded runtime, you may have to select which thread you want to step through before calling sf:

(lldb) thread select 4 (lldb) sf Tweaking the script

You will probably want to tweak the above script in various ways. For instance, in the application I was debugging, I wanted to step into each assembly language instruction but over each C function call, mostly because lldb was getting confused with the call stack. I also added a maximum step count:

def step_func(debugger, command, result, internal_dict): args = shlex.split(command) if len(args) > 0: maxCount = int(args[0]) else: maxCount = 100 thread = debugger.GetSelectedTarget().GetProcess().GetSelectedThread() i = 0; while True: frame = thread.GetFrameAtIndex(0) file = frame.GetLineEntry().GetFileSpec().GetFilename() inC = type(file) is str and file.endswith(".c") if inC: thread.StepOver() else: thread.StepInstruction(False) stream = lldb.SBStream() thread.GetStatus(stream) description = stream.GetData() print i print description i += 1; if thread.GetStopReason() == lldb.eStopReasonException or i > maxCount: break

You may want to tweak this step into/step over behaviour to suit your application; certainly you don’t want to have a call trace involving every step taken in the Haskell RTS or worse, in the libraries it depends on.

Back to the example

Rather than printing every step along the way, it may also be useful to simply remember the step-before-last and show that on a crash; often it is sufficient to know what happened just before the crash. Indeed, in the application I was debugging the call stack just before the crash was:

2583 thread #3: tid = 0x35e743, 0x00000001099da56d libHSrts_thr_debug-ghc7.8.3.20140729.dylib`schedule(initialCapability=0x0000000109a2f840, task=0x00007fadda404550) + 1533 at Schedule.c:470, stop reason = step over frame #0: 0x00000001099da56d libHSrts_thr_debug-ghc7.8.3.20140729.dylib`schedule(initialCapability=0x0000000109a2f840, task=0x00007fadda404550) + 1533 at Schedule.c:470 467 } 468 469 case ThreadInterpret: -> 470 cap = interpretBCO(cap); 471 ret = cap->r.rRet; 472 break; 473 2584 thread #3: tid = 0x35e743, 0x0000000103106226, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x0000000103106226 -> 0x103106226: addb %al, (%rax) 0x103106228: addb %al, (%rax) 0x10310622a: addb %al, (%rax) 0x10310622c: addb %al, (%rax)

Which is a lot more helpful than the backtrace, as we now have a starting point: something went wrong when running the bytecode interpreter (remember that the application was compiling and running some Haskell code at runtime).

To pinpoint the problem further, we can set a breakpoint in interpretBCO and run sf again (the way we defined sf it steps over any C function calls by default). This time we get to:

4272 thread #4: tid = 0x35f43a, 0x000000010e77c548 libHSrts_thr_debug-ghc7.8.3.20140729.dylib`interpretBCO(cap=0x000000010e7e7840) + 18584 at Interpreter.c:1463, stop reason = step over frame #0: 0x000000010e77c548 libHSrts_thr_debug-ghc7.8.3.20140729.dylib`interpretBCO(cap=0x000000010e7e7840) + 18584 at Interpreter.c:1463 1460 tok = suspendThread(&cap->r, interruptible ? rtsTrue : rtsFalse); 1461 1462 // We already made a copy of the arguments above. -> 1463 ffi_call(cif, fn, ret, argptrs); 1464 1465 // And restart the thread again, popping the stg_ret_p frame. 1466 cap = (Capability *)((void *)((unsigned char*)resumeThread(tok) - STG_FIELD_OFFSET(Capability,r))); 4273 thread #4: tid = 0x35f43a, 0x0000000107eba226, stop reason = EXC_BAD_ACCESS (code=1, address=0x0) frame #0: 0x0000000107eba226 -> 0x107eba226: addb %al, (%rax) 0x107eba228: addb %al, (%rax) 0x107eba22a: addb %al, (%rax) 0x107eba22c: addb %al, (%rax)

Ok, now we are really getting somewhere. Something is going wrong when are doing a foreign function call. Let’s re-run the application once more, setting a breakpoint at ffi_call:

(lldb) breakpoint set -n ffi_call Breakpoint 1: where = libffi.dylib`ffi_call + 29 at ffi64.c:421, address = 0x0000000108e098dd (lldb) cont Process 51476 resuming Process 51476 stopped * thread #4: tid = 0x360fd3, 0x0000000108e098dd libffi.dylib`ffi_call(cif=0x00007fb262f00000, fn=0x00000001024a4210, rvalue=0x000000010b786ac0, avalue=0x000000010b7868a0) + 29 at ffi64.c:421, stop reason = breakpoint 1.1 frame #0: 0x0000000108e098dd libffi.dylib`ffi_call(cif=0x00007fb262f00000, fn=0x00000001024a4210, rvalue=0x000000010b786ac0, avalue=0x000000010b7868a0) + 29 at ffi64.c:421 418 /* If the return value is a struct and we don't have a return value 419 address then we need to make one. Note the setting of flags to 420 VOID above in ffi_prep_cif_machdep. */ -> 421 ret_in_memory = (cif->rtype->type == FFI_TYPE_STRUCT 422 && (cif->flags & 0xff) == FFI_TYPE_VOID); 423 if (rvalue == NULL && ret_in_memory) 424 rvalue = alloca (cif->rtype->size);

and let’s take a look at the function we’re about to execute:

(lldb) disassemble -s fn 0x1024a4210: pushq %rbp 0x1024a4211: movq %rsp, %rbp 0x1024a4214: leaq (%rip), %rdi 0x1024a421b: popq %rbp 0x1024a421c: jmpq 0x1024a4221 0x1024a4221: pushq $0x6f6c6c65 0x1024a4226: addb %al, (%rax) 0x1024a4228: addb %al, (%rax) 0x1024a422a: addb %al, (%rax) 0x1024a422c: addb %al, (%rax) 0x1024a422e: addb %al, (%rax)

We were expecting to execute hello:

# otool -tV hello.o hello.o: (__TEXT,__text) section _hello: 0000000000000000 pushq %rbp 0000000000000001 movq %rsp, %rbp 0000000000000004 leaq L_str(%rip), %rdi ## literal pool for: "hello" 000000000000000b popq %rbp 000000000000000c jmpq _puts

and if you compare this with the code loaded into memory it all becomes clear. The jump instruction in the object file

jmpq _puts

contains a symbolic reference to puts; but the jump in the code that we are about to execute in fact jumps to the next instruction in memory:

0x1024a421c: jmpq 0x1024a4221 0x1024a4221: ...

In other words, the loaded object file has not been properly relocated, and when we try to call puts we end up jumping into nowhere. At this point the bug was easily resolved.

Further Reading

We have barely scratched the surface here of what we can do with lldb or gdb. In particular, ghc maintains quite a bit of runtime information that we can inspect with the debugger. Tim Schröder has an excellent blog post about inspecting ghc’s runtime data structures with gdb, and Nathan Howell has written some extensive lldb scripts to do the same, although they may now be somewhat outdated. See also the reddit discussion about this blog post.

Categories: Offsite Blogs