Hacker News new | ask | show | jobs
by tormeh 4387 days ago
Can the typechecker ensure that your matrices (constructed from files) have compatible dimensions to be multiplied together? No? None of the compilers I've tried are much good for numeric computing. Since the error-prone parts of writing your code are not made easier by the typechecker, a dynamic language works just as well and has much lower cognitive overhead.

Remember that scientists don't care about the quality of their code. In many cases, once the code is complete, it will only run once and then be thrown away. There is no maintenance. Things like technical debt don't exist.

And pragmatism? Haskell doesn't even have loops. Loops with mutable variables inside are a very intuitive way of thinking about things and often a better fit to a problem than recursion. Sure, you can use tail recursion (which is just ugly looping) instead, but you're adding unwanted cognitive overhead.

What I would like is a functional language with enclosed, sealed off loops. Syntactic sugar for tail recursion, basically, but Haskell isn't built with programmers in mind; it's built for CS researchers. Computer language researchers, more specifically.

5 comments

> Can the typechecker ensure that your matrices have compatible dimensions to be multiplied together? No?

Yes. In fact this is one of the earliest examples [0] of what you can do with the ever more numerous extensions to Haskell's type system.

There are BLAS bindings [1] and several native linear-algebra libraries in Hackage [2] that enlist the type-checker to enforce shape constraints at compile time.

0. See McBride (2001), "Faking It": http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.2...

1. http://hackage.haskell.org/package/blas

2. Repa, for instance: http://hackage.haskell.org/package/repa, http://hackage.haskell.org/package/repa-algorithms

> Remember that scientists don't care about the quality of their code. In many cases, once the code is complete, it will only run once and then be thrown away. There is no maintenance. Things like technical debt don't exist.

The code is usually used once, but it’s modified and “improved” for the next paper. So you add a few new routines here and a few files to read or write there, ... And one day you have a 95 pages fortran 77 program (it’s does’t even follow the fortran 90 standard).

> Can the typechecker ensure that your matrices have compatible dimensions to be multiplied together?

In any dependently typed language, absolutely yes.

Except Haskell isn't dependently typed, right?

I can do it in C# for small matrices, by including the dimensions as type bindings (http://bling.codeplex.com), but that is not practical for larger matrices, nor would it work for matrices loaded from IO.

To the downvoters: are you claiming Haskell is dependently typed? If so, why isn't it used in http://hackage.haskell.org/package/matrix-0.2.1/docs/Data-Ma...? Or just one matrix data type that checks dimension lengths via the type system?

Actually Haskell does have some dependently typed features (and is being extended constantly). The reason it isn't used in that particular package is a mystery, except that a lot of these things are very new and Haskell is an evoloving ecosystem. That particular package simply may not have a release that uses all the latest GHC features.

Repa for instance does provide type errors based on dimensionality of matrices. This is a package on Hackage.

See http://www.haskell.org/haskellwiki/Numeric_Haskell:_A_Repa_T...

Dimensionality is easy, its the lengths of these dimensions that are hard. E.g. you can multiply n by k, k by m matrices to get an n by m matrix, but anything else is a type error. In Bling, I had Matrix<LN,LK> * Matrix<LK,LM> => Matrix<LN,LM>, where LN,LK,LM are type parameters up to around 10 (L0, L1, ..., L10, enough to do 3D graphics, mostly, but wouldn't work for HPC where lengths are much longer and diverse).

Looking at the linked page, extent isn't a part of a matrix's type signature, so it would be checked dynamically, correct?

> you can multiply n by k, k by m matrices to get an n by m matrix, but anything else is a type error.

This is exactly how Repa works, it uses a Peano encoding of the extent of dimensions to make invalid array operations inexpressible.

Ok. This isn't obvious at all by looking at the documentation, also since extent doesn't seem to appear in the type signature of a matrix instance.
Sorry, I forgot to specify that I meant matrices you read at runtime, for example from a csv.
Haskell has a very neat interface for this, in that you build a special type which remembers the dimensions of a matrix as you build them, and then return either the result or a failure.

It's very simple to build a function which doesn't have to understand the possible dimension conflicts and lift it to work on this new type, returning an either (or a maybe, if there's only one failure mode) in place of a definite value.

It's also very simple to propagate such errors forward, so they'll short circuit a computation when you have non-matching matrices used in a calculation that's multiple steps.

In Haskell, I don't have to remember to write special functions which guard against this: I write functions that operate on the matrices and add the guarding at the very end. I can ensure that all my calls use the guarding functions, because they have a different type signature.

Trying to do this same thing in Python require that I remember to always use the guarded calls, and doesn't have as clean of an interface to create the guarded functions from standard functions.

What does it matter? No type-system will magically know ahead of time what the contents of the file will be before you run the program, but it can force you to do the appropriate checks when you do read it from the file.
> No type-system will magically know ahead of time what the contents of the file will be before you run the program.

Yes they can, it's known as 'type providers'. http://blogs.msdn.com/b/dsyme/archive/2013/01/30/twelve-type...

I believe you could enforce something like compatible dimensions in Haskell in a library, but I could be wrong. If not, I wonder if you could do it in idris.
Idris is a wonderful language but the tooling there is even more immature for numerical computing than Haskell.
> Can the typechecker ensure that your matrices (constructed from files) have compatible dimensions to be multiplied together?

It seems so

http://stackoverflow.com/questions/8332392/type-safe-matrix-...