Dec 24, 2015 · 4 minute read · Comments
HaskellHackageReddit
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 24
(Reddit discussion)
Whew, it’s finally over, this “24 days of Hackage, 2015” project!
I never expected to do something like this, ever, and I am grateful to
everyone who encouraged me while I was engaged in it. I enjoyed the
quality of comments and corrections I got as well as links to related
Haskell libraries.
Some closing thoughts:
Read On →
Dec 23, 2015 · 5 minute read · Comments
HaskellHackageLiquid Haskellcontractsrefinement typesSMT
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 23
(Reddit discussion)
During the course of this article series “24 days of Hackage, 2015”,
I’ve made an effort to give a flavor of using QuickCheck to specify
contracts that should be satisfied by our code that are not checked at
compile time but are checked through randomized testing at run
time. But we know that just because code has hundreds or thousands of
tests, that is not a proof that code is actually correct for all
possible cases. I’ve also used newtype
as a way of indicating
intent that I want to restrict legal values for a type, such
as
on day 15
when I laboriously intended refinements of existing types but with
no automatically checkable proof that I was populating them correctly.
-- | User input without a newline, and not equal to "secret".
newtype NotSecretString =
NotSecretString { getNotSecretString :: NotNewlineString }
type NotNewlineString = [NotNewlineChar]
newtype NotNewlineChar =
NotNewlineChar { getNotNewlineChar :: Char }
deriving (Show)
This is why I’m so excited about
Liquid Haskell,
a static analysis system for Haskell that is under very active
development. It provides a refinement type system that allows you to
write, in a natural and clear way, certain varieties of contracts that
can be verified at compile time. I believe this sort of system will
be a game changer in the future of programming languages.
Read On →
Dec 22, 2015 · 5 minute read · Comments
HaskellHackageshakemakeSConsPython
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 22
(Reddit discussion)
make
, the venerable build system, is flawed in many ways. For me,
the main two problems were
- handling dynamic builds, where something during the build triggers
dependencies
- wanting to write code in a real language, not
make
-the-Turing-complete-language
Many improved build systems have come along since make
. For example,
a couple of years ago, I discovered SCons,
the Python-based dynamic build system, and it made my life so much
better, because I could treat it as an embeddable library and have
tasks call my Python code. I still have SCons programs in use.
However, Shake has come along, and I’m not
looking back. It has the virtues of SCons and more. I already use
Shake for new build setups and plan to migrate my old SCons builds to
Shake the next time they need any significant reworking.
Note that the
GHC build is migrating to Shake,
so serious dogfooding is going on.
Read On →
Dec 21, 2015 · 7 minute read · Comments
HaskellHackagegoodGHoodHoeddebugging
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 21
(Reddit discussion)
How do you debug your Haskell code?
I have to confess up front that I don’t have a good answer to the
question of how I debug in Haskell.
I’m not really the right person to talk about debuggers, because the
last time I used an official debugging tool was when I was developing
in C and C++ and used tools such as gdb
and higher-level interfaces
to that, and since then, my debugging process for most languages has
involved looking at stack traces and logs, insertion of “print”
statements, writing finer-grained tests, and refactoring code to find
out the root cause of a problem. I do not use official debugger
applications any more (with breakpoints, stepping, etc.). But should
I?
The question becomes even more complicated when working in Haskell,
because I think it honest to say that Haskell
does not have a great story for debugging.
I’ve taken a look into a family of debugging tools for Haskell,
including hood
,
GHood
, and
Hoed
, which are all based on the
same concept: manual annotation of source code in order to generate
traces that can later be analyzed in interesting ways.
Read On →
Dec 20, 2015 · 5 minute read · Comments
HaskellHackageFsharpdimensional
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 20
(Reddit discussion)
One thing that my science teachers in high school always emphasized,
when we did calculations, was to be explicit about the units of
measurement. They were very stern that we show our units, carry them
and cancel them as appropriate, in order to get a final answer that
was meaningful. And for good reason! If you add a distance (such as in
meters) and a velocity (such as kilometers per second), that is a
type error. It is also a type error to add the numerical value of a
distance in meters and a value of a distance in feet: to perform such
an addition, you have to convert to a common unit first and then add
the numbers.
The programming language F# comes with
units of measure
built into its type system. This is a really cool feature. How can we
do this in Haskell?
It turns out that with a lot of fancy type machinery, people have done
this sort of thing in Haskell. A library I looked at for making
unit-checking into type-checking for physical quantities is the
actively evolving
dimensional
library.
Today I’ll show a little bit of code using it to give a flavor of what
you can do with it.
Read On →
Dec 19, 2015 · 10 minute read · Comments
HaskellHackagefusionGHCghc-core-htmllist-fusion-probe
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 19
(Reddit discussion)
The single coolest feature of using Haskell, for me, has to be
fusion. The GHC compiler
performs this remarkable optimization that can erase entire
intermediate data structures from existence.
What does that mean, and how can we know it happened? Today I’ll show
how ghc-core-html
and list-fusion-probe
can sort of help in
determining what the compiler actually did to your intermediate data
structures.
I’ll give examples with lists as the intermediate data, but also
mention vectors because yesterday,
day 18,
I briefly mentioned fusion in the context of vectors.
Read On →
Dec 18, 2015 · 11 minute read · Comments
HaskellHackagevectorvector-algorithmsarrayrepaarraysmutationC
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 18
(Reddit discussion)
Often in programming, the right data structure to use is a C-style
array, whether treated as immutable or mutable.
Ideally, I didn’t need to write this article, but I’ve gotten the
impression that many newcomers to Haskell don’t know about
vector
, the library for
zero-indexed C-style arrays, and use lists where arrays are better suited to
the problem. Arrays are efficient for indexing and are memory and
cache efficient also, being allocated in a block of memory rather than
spread out over pointer chasing.
The terminology regarding arrays in the Haskell ecosystem is confusing
because Haskell in the 1990s originally came with a data structure
called an Array
, and there’s even a supporting
array
package, but in
practice I never use it because it’s more generic and weird than the
simple data structure later provided called “vectors” (for lack of a
better name).
There are good tutorials on vector
I recommend:
I thought it would be useful to give a fully worked out example of
using both immutable and mutable vectors. In particular, we’ll use
unboxed vectors that are specialized and therefore contain no
indirection and are basically equivalent to C-style arrays. We’ll do
some low-level C-style programming.
Read On →
Dec 17, 2015 · 4 minute read · Comments
HaskellHackageansi-wl-pprintannotated-wl-pprint
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 17
(Reddit discussion)
Today we do the inverse of what we did on
day 14,
which was parsing from text to an abstract syntax tree. Today we
pretty-print an abstract syntax tree to text.
I think that in the wider world of programming, it’s very common to
see ad hoc, inflexible solutions to this problem, using string hacking
and maybe at best some string-based templates. It’s typically hard to
quickly customize indentation styles, expression wrapping, and other
such features when using such an ad hoc solution.
In the Haskell community, a better solution is more often used,
because of the number of quality libraries out there to help in
pretty-printing.
ansi-wl-pprint
is one such library, that includes not only a lot of useful
convenience combinators, but also provides support for colored
terminal output, if you want to use that (you don’t have to).
Update
A commenter on Reddit noted that there’s another version of the
pretty-printing library,
annotated-wl-pprint
. This
looks really cool, and here’s a
video by David Christiansen on its usage in Idris.
Read On →
Dec 16, 2015 · 7 minute read · Comments
HaskellHackagesafesafetyexceptionsPureScriptElmpsychology
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 16
(Reddit discussion)
Today I’m doing something strange: up till now, I’ve discussed
libraries and tools I actually use. Today I’m discussing a library I
do not use, while thinking about why I not, and why you or I might
want to use it. This library is
safe
, which aims to
protect against the unfortunate “unsafety” of common functions in the
standard Prelude.
That’s a good thing, right? After all, on
day 7,
I promoted the use of the NonEmpty
list, and again used in
day 14. I
like safety, but what does “safety” mean anyway?
Read On →
Dec 15, 2015 · 7 minute read · Comments
HaskellHackageIOSpecIOtestingQuickCheckquickcheck-unicodecoercion
Table of contents for the whole series
A table of contents is at the top of the article for day 1.
Day 15
(Reddit discussion)
On
day 11,
I tangentially mentioned feeling embarrassed that unlike all of my
other code examples, because I was using IO
, I didn’t approach it by
writing tests up front. I didn’t want to distract from the topic at
hand, which had nothing to do with IO
but to do with general monadic
combinators.
But now I’m back to fill in the gap by showing one way of “mocking
out” IO
, the IOSpec
library. This isn’t a perfect solution, and I wish there were some
kind of standard way of testing IO
in the Haskell ecosystem, rather
than the various different methods (often reinvented) floating around
out there, but at least gives the flavor of one approach.
Ironically, I found and
fixed a bug in my code
for day 11 in the process of writing a test for it!! Sometimes I feel
I’m super unlucky because when I do last-minute edits of code without
tests (in this case to turn one print statement into two, in the
course of revising the day 11 article), I inevitably introduce
bugs. This is precisely why I like to write tests. I do not trust
myself without tests.
Read On →