
Hulk: A Haskell IRC server - profquail
http://chrisdone.com/posts/hulk-haskell-irc-server
======
jayferd
HULK SMASH SHA1 FOR PASSWORDS!

No seriously, before you get like a million users you should switch to a much
slower hashing alg that's designed for passwords, not for checksums. Scrypt is
good, bcrypt is good, and there are a few others. But here's a(n?) scrypt
package on Haskell that will do it for you and has a really nicely designed
API:
[http://hackage.haskell.org/packages/archive/scrypt/0.3.1/doc...](http://hackage.haskell.org/packages/archive/scrypt/0.3.1/doc/html/Crypto-
Scrypt.html)

~~~
chongli
Could you explain a little more about why you need a slower algorithm? How is
anyone going to crack a well-salted SHA1 password?

~~~
g_lined
It is increasingly trivial to try millions or billions of hashes per second.
Using scrypt forces the computer to use more resources (in this case, memory
in particular) which means that scaling the guess rate is orders of magnitude
slower and cannot be significantly increased by building faster computers
(because it's limited by memory not process speed).

<http://en.wikipedia.org/wiki/Scrypt>

It comes down to this: Why use something which is designed for speed like
hashes to do something that can be broken by highspeed guessing?

~~~
chongli
>Why use something which is designed for speed like hashes to do something
that can be broken by highspeed guessing?

Perhaps you have hundreds of millions of users? The slower your hash algorithm
the more resources it takes to run it.

~~~
jlgreco
At hundreds of millions of users, I rather suspect resources spent on password
hashing are going to be low on the list of concerns.

------
Ao7bei3s
> It’s also common to put all your types into one module named Types, as you
> tend to use types from every module

Is that true? Wouldn't that mean that typical Haskell applications aren't very
modular, if every module needs access to all types? How can this be a good
thing?

[I'm not good with Haskell; I sort of like it, but it makes me feel rather
unintelligent.]

~~~
ionfish
I wouldn't confuse modules with modularity. Think of it like this: types are
the primary API for the program. In fact, I tend to call the modules that
perform this function in my code something like 'Core'. Since they're a shared
language that allow different parts of the code to communicate without knowing
any implementation details, these types actually make it possible to write
code that is more modular, not less. Different parts of the program can go
about their business and perform specialised tasks, while still being
interoperable (and composable) with other parts of the program (and,
hopefully, code not yet written—although this very much depends on how well
your types model your problem domain).

I'm not sure the author's explained this point quite as clearly as it could
have been. One doesn't want to expose every type used in the program across
all modules: there are many that are just used in internal representations
within particular modules.

Here's an example from a project of mine, which is a command line program to
produce truth tables. There's a Core module which contains the types shared
across the whole program, and the most fundamental operations on them.

[https://github.com/beastaugh/hatt/blob/1.5.0.3/src/Data/Logi...](https://github.com/beastaugh/hatt/blob/1.5.0.3/src/Data/Logic/Propositional/Core.hs)

Then there are other modules like Parser which just exposes a single function,
but of course makes use of the core types.

[https://github.com/beastaugh/hatt/blob/1.5.0.3/src/Data/Logi...](https://github.com/beastaugh/hatt/blob/1.5.0.3/src/Data/Logic/Propositional/Parser.hs)

The command line program itself is defined as a Main module, which imports the
pure library modules and does all the I/O. It has a few types of its own but
these aren't shared across the program, because the library doesn't need to
know about all this stuff.

<https://github.com/beastaugh/hatt/blob/1.5.0.3/src/hatt.hs>

~~~
Ao7bei3s
Ah, thanks!

------
1500100900
I don't mean to criticize the blog post, since it's probably valuable to some
people. But if you're sick of Skype for Linux and you realize that something
like IRC would be good replacement, then what's the point of writing an IRC
server in Haskell (except for fun/education/pleasure) when you could use
existing software (open source or not) like Apache Wave, Mumble, one of the
many XMPP servers, IRC servers etc.?

~~~
coldtea
> _But if you're sick of Skype for Linux and you realize that something like
> IRC would be good replacement_

Huh? How do those even compare?

~~~
Zash
I know at least one organization that mainly used the group chat bit of Skype.
In that case, one might think it possible to replace it with XMPP or IRC.

------
revelation
Instead of writing about purity and impurity all day he could have spent that
time improving the IRC server to the point where the authentication can not be
trivially replayed in what is a clear text protocol and implemented IRC over
SSL/TLS.

That sounds a bit snarky; it just seems like purity/impurity is the favorite
bikeshed for haskell programmers.

~~~
tikhonj
He only used part of the blog post to talk about purity; when explaining how
the code is designed and organized, it's not like he could reasonably skip
that part. Besides, Haskell makes the distinction sufficiently natural that it
does but take much effort when actually coding, so the main "cost" in terms of
time was probably in writing the blog post :P.

Since it's an internal effort, simplicity trumps security and features. I
doubt making the IRC server more complete would be worth the effort and
maintenance cost. It's much better to add features only of they are obviously
missing when they actually use the server.

~~~
revelation
Well yes, and then he went on to completely rewrite it, for puritys sake:

[https://github.com/chrisdone/hulk/commit/d9093c76a49ea417091...](https://github.com/chrisdone/hulk/commit/d9093c76a49ea4170917db2c3b3b4109c61c49cf)

~~~
nightski
God forbid someone learns while using a new language and may not implement it
the most optimal way the first time. What a waste!

~~~
pixl97
It is the second time I fear.

<http://en.wikipedia.org/wiki/Second-system_effect>

------
jayferd
Neat trick with the generalized derived classes! You don't actually need to
make IRC a monad transformer if you don't need it. Just drop the `m` from the
`newtype` declaration, and you have a nice simple `IRC a` monad.

~~~
tel
It's a common trick from the 'transformers' lib to define type SomeMonad =
SomeMonadT Identity

~~~
jayferd
Ooooooooo neat!

------
d0m
We agreed something like IRC would be good, _so I thought it would be easy in
Haskell to make such a thing_.

Or you can use any of the thousand services running IRC servers ;-)

~~~
wonderzombie
Why pass up the opportunity for a valuable learning experience? Even if it
doesn't pan out, chances are that you'll learn _something_ , no?

------
ibotty
that blog post is from 2011. just so you know...

