News aggregator

Dimitri Sabadie: Never forget your git stashes again!

Planet Haskell - Sun, 08/16/2015 - 12:10pm

It’s been a while I’m experiencing issues with git stash. If you don’t know that command yet, git stash is used to move all the changes living in your staging area into a special place: the stash.

The stash is a temporary area working like a stack. You can push changes onto it via git stash or git stash save; you can pop changes from top with git stash pop. You can also apply a very specific part of the stack with git stash apply <stash id>. Finally you can get the list of all the stashes with git stash list.

We often use the git stash command to stash changes in order to make the working directory clear again so that we can apply a patch, pull some changes, change branch, and so on. For those purposes, the stash is pretty great.

However, I often forget about my stashes – I know I’m not the only one. Sometimes, I stash something and go to cook something or just go out, and when I’m back again, I might have forgotten about what I had stashed, especially if it was a very small change.

My current prompt for my shell, zsh, is in two parts. I set the PS1 environnment variable to set the regular prompt, and the RPROMPT environnment variable to set a reversed prompt, starting from the right of the terminal. My reversed prompt just performs a git command to check whether we’re actually in a git project, and get the current branch. Simple, but nice.

I came up to the realization that I could use the exact same idea to know whether I have stashed changes so that I never forget them! Here’s a screenshot to explain that:

As you can see, my prompt now shows me how many stashed changes there are around!

The code

I share the code I wrote with you. Feel free to use it, modify it and share it as well!

# …

function gitPrompt() {
# git current branch
currentBranch=`git rev-parse --abbrev-ref HEAD 2> /dev/null`
if (($? == 0))
then
echo -n "%F{green}$currentBranch%f"
fi

# git stash
stashNb=`git stash list 2> /dev/null | wc -l`
if [ "$stashNb" != "0" ]
then
echo -n " %F{blue}($stashNb)%f"
fi

echo ''
}

PS1="%F{red}%n%F{cyan}@%F{magenta}%M %F{cyan}%~ %F{yellow}%% %f"
RPROMPT='$(gitPrompt)'

# …

Have fun!

Categories: Offsite Blogs

Mark Jason Dominus: Math.SE report 2015-07

Planet Haskell - Sun, 08/16/2015 - 10:38am

My overall SE posting volume was down this month, and not only did I post relatively few interesting items, I've already written a whole article about the most interesting one. So this will be a short report.

  • I already wrote up Building a box from smaller boxes on the blog here. But maybe I have a couple of extra remarks. First, the other guy's proposed solution is awful. It's long and complicated, which is forgivable if it had answered the question, but it doesn't. And the key point is “blah blah blah therefore code a solver which visits all configurations of the search space”. Well heck, if this post had just been one sentence that ended with “code a solver which visits all configurations of the search space” I would not have any complaints about that.

    As an undergraduate I once gave a talk on this topic. One of my examples was the problem of packing 31 dominoes into a chessboard from which two squares have been deleted. There is a simple combinatorial argument why this is impossible if the two deleted squares are the same color, say if they are opposite corners: each domino must cover one square of each color. But if you don't take time to think about the combinatorial argument you could waste a lot of time on computer search learning that there is no solution in that case, and completely miss the deeper understanding that it brings you. So this has been on my mind for a long time.

  • I wrote a few posts this month where I thought I gave good hints. In How to scale an unit vector in such way that where is a scalar I think I did a good job identifying the original author's confusion; he was conflating his original unit vector and the scaled, leading him to write . This is sure to lead to confusion. So I led him to the point of writing and let him take it from there. The other proposed solution is much more rote and mechanical. (“Divide this by that…”)

    In Find numbers so that the OP got stuck partway through and I specifically addressed the stuckness; other people solved the problem from the beginning. I think that's the way to go, if the original proposal was never going to work, especially if you stop and say why it was never going to work, but this time OP's original suggestion was perfectly good and she just didn't know how to get to the next step. By the way, the notation here means the number .

    In Help finding the limit of this series it would have been really easy to say “use the formula” or to analyze the series de novo, but I think I almost hit the nail on the head here: it's just like , which I bet OP already knows, except a little different. But I pointed out the wrong difference: I observed that the first sequence is one-fourth the second one (which it is) but it would have been simpler to observe that it's just the second one without the . I had to review it just now to give the simpler explanation, but I sure wish I'd thought of it at the time. Nobody else pointed it out either. Best of all, would have been to mention both methods. If you can notice both of them you can solve the problem without the advance knowledge of the value of , because you have and then solve for .

    In Visualization of Rhombus made of Radii and Chords it seemed that OP just needed to see a diagram (“I really really don't see how two circles can form a rhombus?”), so I drew one.

Categories: Offsite Blogs

What are Haskellers' critiques of Scala?

Haskell on Reddit - Sun, 08/16/2015 - 9:19am

/u/klaxion kicked off a great discussion a few days ago regarding Haskellers' critiques of Clojure. To continue the theme: what are our critiques of Scala?

submitted by tew88
[link] [227 comments]
Categories: Incoming News

ANN: Amazonka 1.0

Haskell on Reddit - Sun, 08/16/2015 - 9:00am

A rather large number of updates to all of the Amazonka AWS SDKs have been released, including new features as well as some breaking changes. (Signified by the bump in major version.) In addition, there is now support for a total of 52 different AWS services.

Some formatted release notes are available here.

submitted by brnhy
[link] [9 comments]
Categories: Incoming News

ghc-mod makes Emacs freeze on "Initializing..."

Haskell on Reddit - Sun, 08/16/2015 - 3:43am

Hello everyone,

3 down vote favorite I've been trying to learn Haskell the last couple of days so it was finally time to setup my environment. Thus, I installed Haskell Platform and cabal.

My editor is emacs and my OS is Windows.

I downloaded the ghc-mod's master branch from github and using cabal I installed the dependencies and then built the project. Everything went fine and the executable seems to work.

Commands like ghc-mod --version or ghc-mod boot work as expected.

Then, I installed haskell-mode on emacs and modified .emacs to use ghc. But when I tried to open a Haskell file, emacs froze saying "Initializing...".

What is the problem?

GHC version: 7.10.2 cabal version: 1.22.6.0 using version 1.22.4.0 of the cabal library ghc-mod version: 5.3.0.0 compiled by GHC 7.10.2

Here are the lines I added to my .emacs:

; haskell-mode (add-hook 'haskell-mode-hook 'haskell-indentation-mode) ; ghc-mod for haskell ; I added to list path to ghc elisp file because I read somewhere that that's ; better than installing it from MELPA. I DID try to install it from melpa ; though. Didn't solve anything. (add-to-list `load-path "~/cabal/x86_64-windows-ghc-7.10.2/ghc-mod-5.3.0.0/elisp") (autoload 'ghc-init "ghc" nil t) (autoload 'ghc-debug "ghc" nil t) (add-hook 'haskell-mode-hook (lambda () (ghc-init)))

Emacs freeze when I try to open a haskell file for the first time. So I guess it stacks in an infinite loop inside ghc-init().

submitted by The-Crafter
[link] [15 comments]
Categories: Incoming News

ACM Classic Books Series

Lambda the Ultimate - Sun, 08/16/2015 - 12:24am

This list of classic books is the result of a poll ACM conducted where members named their favorite computer science books.

Good list. Bar the last two, which I have nothing against, the list consists of favorites of mine. It is always nice to see how many classics of CS come from work on programming languages. Not a surprise for anyone here, of course, but not always acknowledged. While we are on the subject of classic books, check out Luke's twitter poll here.

Categories: Offsite Discussion

Ken T Takusagawa: [clomduww] Foldable with metadata

Planet Haskell - Sat, 08/15/2015 - 11:29pm

The Foldable instances of Array and Map in Haskell do not provide access to the index or key respectively. It is possible to provide such access, but doing so requires defining Foldable differently, making it a multiparameter type class and explicitly specifying an intermediate type that packages up the element and metadata, e.g., index or key.

GHC 7.10.1, array-0.5.1.0, base-4.8.0.0, containers-0.5.6.2

{-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, ScopedTypeVariables #-}
module FoldableWithKey where {
import Data.Array.IArray;
import qualified Data.Map as Map;

-- similar to Foldable, except the intermediate type can be different from the element type.
class FoldableWithKey collection intermediate where {
foldWithKey :: (intermediate -> b -> b) -> b -> collection -> b;
};

-- unclear why OVERLAPPABLE is needed here, as Map is clearly not an IArray
instance {-# OVERLAPPABLE #-} (IArray a e, Ix i) => FoldableWithKey (a i e) (i,e) where {
foldWithKey f z = foldr f z . assocs ;
};

instance FoldableWithKey (Map.Map k a) (k,a) where {
foldWithKey f = Map.foldWithKey $ \xk xa xb -> f (xk,xa) xb;
};

-- Overlapping Instance
-- Allows foldWithKey to be a drop-in replacement for foldr.
instance {-# OVERLAPPABLE #-} (Foldable t) => FoldableWithKey (t a) a where {
foldWithKey = foldr;
};

test1 :: [Int] -> Int;
test1 = foldWithKey (+) 0;

test2 :: Map.Map String Int -> Int;
test2 = foldWithKey (+) 0;

test3 :: Map.Map String Int -> (String,Int);
test3 = foldWithKey (\(s,i) (sold,iold) -> (s ++ sold, i + iold)) ("",0);

test4 :: Map.Map String Int -> Int;
-- explicit type signature weirdly needed on s
test4 = foldWithKey (\(s :: String, i) iold -> length s + i + iold) 0;

test5 :: Array Int Double -> Double;
-- explicit type signature weirdly needed on i
test5 = foldWithKey (\(i :: Int , d) dold -> d + dold + fromIntegral i) 0;
}

Categories: Offsite Blogs

libiconv trouble?

General haskell list - Sat, 08/15/2015 - 9:26pm
Anyone else hit this, after updating to the new Haskell Platform? Davids-MacBook-Air-2:tmp dbanas$ ghci GHCi, version 7.10.2: http://www.haskell.org/ghc/ :? for help <command line>: can't load .so/.DLL for: libiconv.dylib (dlopen(libiconv.dylib, 5): image not found) Thanks, -db _______________________________________________ Haskell mailing list Haskell< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell
Categories: Incoming News

Redundant entries in .cabal file?

General haskell list - Sat, 08/15/2015 - 4:03pm
Hi all, Does anyone know why I’m getting redundant entries in my ‘cabal init’ generated .cabal file: library exposed-modules: Language.Broker, Language.Broker ? Is it because I’m using a *.hsc file, as my source, and cabal is finding both files: Broker.hsc, and Broker.hs in the Language directory? Thanks, -db _______________________________________________ Haskell mailing list Haskell< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell
Categories: Incoming News

Neil Mitchell: Testing is never enough

Planet Haskell - Sat, 08/15/2015 - 3:40pm

Summary: Testing shows the presence, not the absence of bugs.

Recently, someone suggested to me that, thanks to test suites, things like changing compiler version or versions of library dependencies was "no big deal". If dependency changes still result in a passing test suite, then they have caused no harm. I disagree, and fortunately for me, Dijkstra explains it far more eloquently than I ever could:

Testing shows the presence, not the absence of bugs. Dijkstra (1969)

While a test suite can give you confidence in changes you make, it does not provide guarantees. Below are just a few reasons why.

The test suite does not cover all the code

For any reasonably sized code base (> 100 lines), covering all the lines of code is difficult. There are a number of factors that mean that mean a test suite is unlikely to provide 100% coverage:

  • Producing tests is a resource intensive activity, and most projects do not have the necessary manpower to test everything.
  • Sometimes there is no good way to test simple sugar functions - the definition is a specification of what the function should do.
  • Testing corner cases is difficult. As the corners get more obscure, the difficulty increases.
  • Testing error conditions is even harder. Some errors conditions have code to deal with them, but are believed to be unreachable.

The test suite does not cover all the ways through the code

Assuming the test suite really does cover every line of the code, making it cover every path through the code is almost certainly computationally infeasible. Consider a program taking a handful of boolean options. While it might be feasible to test each individual option in the true and false states, testing every state in conjunction with every other state requires an exponential amount of time. For programs with loops, testing every number of loop iterations is likely to be highly time consuming.

There is plenty of code you can't see

Even if you cover every line of source code, the compiler may still thwart your valiant efforts. Optimising compilers like to inline code (make copies of it) and specialise code (freeze in some details that would otherwise be dynamic). After such transformations, the compiler might spot undefined behaviour (something almost all C/C++ programs contain) and make modifications that break your code. You might have tested all the source code, but you have not tested all the code generated by the compiler. If you are writing in C/C++, and undefined behaviour and optimisation doesn't scare you a lot, you should read this LLVM article series.

Functions have huge inputs

Testing functions typically involves supplying their input and inspecting their output. Usually the input space is too large to enumerate - which is likely to be the case even if your function takes in an integer. As soon as your function takes a string or array, enumeration is definitely infeasible. Often you can pick cases at which the code is likely to go wrong (0, 1, -1, maxBound) - but maybe it only fails for Carmichael numbers. Random testing can help, and is always advisable, but the effort to deploy random testing is typically quite a bit higher than input/output samples, and it is no panacea.

Functions are not functions

Testing functions usually assumes they really are functions, which depend only on their input. In pure functional languages that is mostly true, but in C/C++ it is less common. For example, functions that have an internal cache might behave differently under parallelism, especially if their cache is not managed properly. Functions may rely on global variables, so they might perform correctly until some seemingly unrelated operation is performed. Even Haskell programs are likely to depend on global state such as the FPU flags, which may be changed unexpectedly by other code.

In my experience, the non-functional nature of functions is one of the biggest practical difficulties, and is also a common place where dependency changes cause frustration. Buggy code can work successfully for years until an improved memory allocator allows a race condition to be hit.

Performance testing is hard

Even if your code gives the correct results, it may take too long or use too much memory. Alas, testing for resource usage is difficult. Resource numbers, especially runtime, are often highly variable between runs - more so if tests are run on shared hardware or make use of parallelism. Every dependency change is likely to have some impact on resource usage, perhaps as dependencies themselves chose to trade time for memory. Spotting erroneous variations often requires a human to make a judgement call.

What is the solution?

Tests help, and are valuable, and you should aim to test as much as you can. But for any reasonably sized program, your tests will never be complete, and the program will always contain unknown bugs. Most likely someone using your code will stumble across one of these bugs. In this case, it's often possible (and indeed, highly desirable) to add a new test case specifically designed to spot this error. Bugs have a habit of recurring, and a bug that happens twice is just embarrassing.

Thinking back to dependency versions, there is often strength in numbers. If all your users are on the same version of all the dependencies, then any bug that is very common is likely to be found by at least one user and fixed for all.

Thinking more generally, it is clear that many of these issues are somewhat ameliorated by pure functional programming. I consider testability and robustness to be one of the great strengths of Haskell.

Categories: Offsite Blogs

Redundant entries in .cabal file?

haskell-cafe - Sat, 08/15/2015 - 3:00pm
Hi all, Does anyone know why I’m getting redundant entries in my ‘cabal init’ generated .cabal file: library exposed-modules: Language.Broker, Language.Broker ? Is it because I’m using a *.hsc file, as my source, and cabal is finding both files: Broker.hsc, and Broker.hs in the Language directory? Thanks, -db _______________________________________________ Haskell-Cafe mailing list Haskell-Cafe< at >haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Categories: Offsite Discussion

Cross-compiling fails for package 'directory'

haskell-cafe - Sat, 08/15/2015 - 1:46pm
Following <https://github.com/ku-fpg/raspberry-pi/wiki/GHC-Cross-Compiler-for-Raspberry-Pi>, I have built a cross-compiling ghc for creating programs that run on the raspberry pi. This ghc has built a "hello world" program that runs on the rpi: OK so far. Unfortunately, building the package 'directory-1.2.3.0' with this cross- compiler fails with the following error message: "System/Directory/Internal.hsc:31 directive const_str cannot be handled in cross-compilation mode" The offending function from System.Directory is this one: Although one can imagine that the meaning of this function is tricky when cross-compiling, I don't think that has actually anything to do with the error. The problem is that hsc2hs cannot handle this 'const_str' directive; see <https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/hsc2hs.html#hsc2hs_cross>. Now my question: how can this be fixed? Is the failure of hsc2hs to support this directive just a matter of "not implemented right now", maybe by lack of
Categories: Offsite Discussion

Reactive config file generation

haskell-cafe - Sat, 08/15/2015 - 10:48am
Hi all, I am using Apache Zookeeper as a service directory: I have a bunch of services which announce their presence by making nodes in Zookeeper, so that dependent services can update their configuration to make use of the available services, and stop trying to use services that have died. Zookeeper is a pretty nice fit for this because it supports watching a node for changes, so in theory there is no need to poll Zookeeper periodically. The services that I control work with this just fine, but there are some (e.g. an Nginx reverse-proxy) that are reconfigured using the rather more common approach of updating a file (or files) and then sending the process a signal. I am currently pondering how to make this work without polling, or manually triggering a refresh script, which is how it is currently done. I've never used FRP, but am at least vaguely aware of it and from my high-level understanding it seems like this could be a very good fit. The Zookeeper state is a time-varying value which I want to conver
Categories: Offsite Discussion

TExpQ a to a?

Haskell on Reddit - Sat, 08/15/2015 - 10:12am
-- Function: maybeParseTextTH :: TExpQ (Text -> Maybe a) -> Text -> TExpQ a maybeParseTextTH mk txt = case (??? what should I put here ??? mk) txt of Just _ -> [|| fromJust $ $$mk $$(textTExp txt) ||] Nothing -> fail ("Parse error " ++ show txt) -- I want to use it like this: parseSomethingTH :: Text -> TExpQ Something parseSomethingTH = maybeParseTextTH [|| parseSomething ||] submitted by lamefun
[link] [comment]
Categories: Incoming News

stack/cabal repl zsh prompt indicator

Haskell on Reddit - Sat, 08/15/2015 - 6:25am

I created a small indicator for stack projects/cabal projects as I am working with multiple versions of ghc (btw. thanks hvr for the ppa-repo) and often do not have the correct ghc version in my path, maybe it is useful to some of you. It is based on one of the many "cabal sandbox indicators for zsh" i found using google.

cabal sandboxes are indicated by a ghc version liked [7.10.2]

  • green ghc version indicates that there is a cabal project, and there exists a directory in the sandbox with libraries built with the current ghc (in the path)

  • a list of red ghc versions indicates cabal projects, which would be available

for stack projects the indicator is like: [rts-3.0|7.10.0]

  • green resolver info and green ghc version indicate a proper stack project

  • red resolver info indicate that the current resolver is not initialized

https://gist.github.com/epsilonhalbe/e9af1d8dccc654ebd641

submitted by epsilonhalbe
[link] [2 comments]
Categories: Incoming News

Documenting generated declarations?

Haskell on Reddit - Sat, 08/15/2015 - 5:22am

There seem to be no Template Haskell structures for code comments or documentation. Is there a way to document declarations generated by it?

submitted by lamefun
[link] [5 comments]
Categories: Incoming News

C-style fork with ContT

Haskell on Reddit - Sat, 08/15/2015 - 5:18am

The thread about monads as variable substitution happened to make me think of the continuation monad's ability to bind the same variable several times, and I realized how easy it would be to implement C-style fork. Maybe this exists in a library somewhere, I just decided to try it and see if it might be of use as a refresher on continuations.

Let's see if my literate Haskell will collaborate with Reddit's formatting...

The continuation monad is a little scary, but it's also useful when you want to do something unusual with your control flow.

Like what?

Consider the fork function in Unix. It works differently from Haskell's forkIO in that instead of accepting a function to run in the background, it returns twice, once for the parent, and once for the child.

That can be a mind-bender since we're used to thinking of programs as progressing linearly, but the name fork tips us off that they can branch, too.

So the fork function introduces a split in the program's execution, and by checking its return value, the remainder of the program can figure out whether it's executing as the parent or as the child.

It's like if your mind was cloned and you woke up in two different places, you would just check where you are and then go on with your day.

So how can we implement this funny operation in Haskell? ContT and IO to the rescue! The continuation monad grants us access, whenever we want, to a representation of the remainder of the program, and lets us execute it twice with no questions asked.

> module Fork where > > import Control.Monad (void) > import Control.Monad.IO.Class (liftIO) > import Control.Monad.Cont (ContT, runContT, callCC) > import Control.Concurrent (forkIO)

In C, fork returns a boolean, but it's clearer to use a sum type.

> data Forking = Parent | Child

So let's look at an example program. I'll make the parent print a backslash and the child print a slash, and then they'll both print a period and newline. The liftIO is necessary to embed IO actions inside the ContT transformer.

> main :: IO () > main = runForking $ do > status <- fork > case status of > Parent -> liftIO (putStr "\\") > Child -> liftIO (putStr "/") > liftIO (putStrLn ".")

Here's how we turn these ContT computations into IO computations using runContT.

Note that ContT has three type variables, like this:

newtype ContT r m a :: * -> (* -> *) -> * -> *

Here r means "final result," m means "underlying monad" and a means "intermediate value."

The final result is what's returned by the final continuation, which we must provide when we run the ContT computation. The final continuation receives the intermediate value and returns an action of the underlying monad that produces the final result.

We don't really care about the final result, so let's just set it to () and not think about it too much.

> runForking :: ContT () IO a -> IO () > runForking m = runContT m (const (return ()))

Let's define a little function just to make the actual IO forking look cleaner:

> inBackground :: IO () -> ContT () IO () > inBackground = void . liftIO . forkIO

And now the main course! Here we use callCC which gives us access to a function representing the remainder of the execution. The type of that function goes from Forking to ContT () IO Forking.

Since Forking only has two different values, we can see this function as a kind of pair of continuations. I'll construct this pair just for demonstrative purposes.

> fork :: ContT () IO Forking > fork = callCC $ \k -> do > let (childK, parentK) = (k Child, k Parent) > inBackground (runForking childK) > parentK

Now we can run it:

Fork> main \. /.

Voila, both branches are run.

submitted by mioloko
[link] [8 comments]
Categories: Incoming News