Archive for May, 2008

Is Haskell really that… great as a programming language?

Friday, May 30th, 2008

Reading lots on Haskell recently I’m beginning to feel like it’s very cool from the CS point of view, but too overcomplicated from the practical one. And all attempts to prove otherwise, as far as I think of them, have failed.

I mean, you can definitely write a useful Haskell application but isn’t the cost too high? Isn’t after all its type system too restrictful? Doesn’t messing with ErrorT IO seem to be much ado about nothing?

Yes, it’s cool when you can reason about your programs in almost mathematical sense. It’s great that you can model the domain with types. It’s nice to have lazy pure code… But when you come to side-effects, stateful computation, error handling, &c simultaneously… Well it starts to feel wrong. Just wrong.

All these are just my thoughts based on short time of learning it. Maybe I’m just too stupid. Maybe I will have this “a-ha!” with Haskell sometime so everything will seem natural to me. But maybe Haskell is just too overcomplicated for actual programming.

It feels like Haskell is actually like maths. Mathematics is all very consistent, you can reason about anything there, you can prove theorems, but when things get complicated they get REALLY complicated. And there is no shortcuts or something like that. And as even tensors don’t fit in my head really well, Haskell may not too.

Think of it like having a programmer to study algebraic geometry for example. Though Haskell seems to be lots easier.

Simple State monad step-by-step example.

Thursday, May 29th, 2008

To better understand State monad I have derived it step by step from do notation to it’s constructor form. So to keep the result I post it here.
This is executable Haskell. Save as haskell file & try to run execState tickN 5 for every tickN.

[-]View Code HASKELL
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
module StRed where
import Control.Monad.State
 
{-- Just for reference.
-- | A parameterizable state monad where /s/ is the type of the state
-- to carry and /a/ is the type of the /return value/.
newtype State s a = State { runState :: s -> (a, s) }
 
instance Monad (State s) where
    return a = State $ \s -> (a, s)
    m >>= k  = State $ \s -> let
        (a, s') = runState m s
        in runState (k a) s'
 
instance MonadState s (State s) where
    get   = State $ \s -> (s, s)
    put s = State $ \_ -> ((), s)
--}
 
-- This monad is able to add one to its internal state.
tick :: State Int Int
tick = do n <- get
          put (n+1)
          return n
 
-- What follows is a derivation of this monad into its normal form.
-- Please note, that this derivation doesn't respect Haskell's order of evaluation.
tick1 :: State Int Int
tick1 = get >>= (\n -> put (n+1) >>= (\_ -> return n))
tick2 = (State (\s -> (s,s))) >>=
              (\n -> (State (\_ -> ((), (n+1)))) >>=
                  (\_ -> (State (\p -> (n, p)))))
tick3 = (State (\s -> (s,s))) >>=
              (\n -> (State (\q -> let
                  (a, q') = runState (State (\_ -> ((), (n+1)))) q
                  in runState ((\_ -> (State (\p -> (n, p)))) a) q')))
tick4 = (State (\s -> (s,s))) >>=
              (\n -> (State (\q -> let
                  (a, q') = ((), (n+1))
                  in (n, q'))))
tick5 = (State (\s -> (s,s))) >>=
              (\n -> (State (\_ -> (n, n+1))))
tick6 = State (\p -> let
              (a, p') = runState (State (\s -> (s, s))) p
              in runState ((\n -> (State (\_ -> (n, n+1)))) a) p')
tick7 = State (\p -> let
              (a, p') = (p, p)
              in (a, a+1))
tick8 = State (\p -> (p, p+1))
 
-- So, here you are. This monad contains function which returns current state,
-- and changes internal state by adding one. Exactly what we supposed.
-- Now, when you run it with execState it's easy to see how it works.
a = execState tick8 3
a1 = snd (runState tick8 3)
a2 = snd ((\p -> (p, p+1)) 3)
a3 = snd (3, 4)
a4 = 4
 
-- In fact, I think this monad is easy to write in tick8 form right from the beginning =)

Hope this would help someone.

CD is a fucking past. Should be extinguished.

Thursday, May 8th, 2008

Inspired somewhat by this post I’m going to rant a little about CD as an information storage.

1. CD can and should be replaced by files.
CD is not in any way superior to music stored in files. CD is a digital format which stores musical data as a sequence of bits (that is “0100100100010…”) so you can treat all its contents as just one big file (usually about 650Mb). Music in CD is encoded using PCM, this encoding is used in WAV files on PC. So CD contains just one big WAV file, and some rippers, e.g. EAC, treat it just in a right way. When you rip a CD with EAC you get one big file, which contains exactly the same information (bits) as the CD you’ve ripped.

Now you can compress this file so it would take not so much space on your HDD (or portable player). There are two main options: lossy & lossless compression.

Lossy compression is a kind of compression which throws away some information which is concidered neglegible to achieve very good compressions rates. Examples are: MP3, OGG, AAC. When you compress with lossy codec you get another information and you cannot restore it back to the original. So CD would be always superior to these formats, of course. Especially if you can actually hear the difference between CD and 320Kbps MP3.

Lossless compression, on the other hand, doesn’t throw away any information when you perform compression. So you get much lower compression rates. But all the information is the same when uncompressed. You can restore it to the original. And that’s what happens when you play it. Just think of it, when you zip or 7zip or rar your files, they will be exactly the same when you would uncompress them. zip is a lossless compressor. But zip is not good at compressing PCM, it’s good at textual data, that’s why there are FLAC, APE & Apple Lossless. (Note that you may get binary different file after decompression of FLAC, this is due to some uncertainty in PCM coding.)

So, lossless compressed files hold exaclty the same information as a CD (except CD text, but who the fuck needs CD text, when you have tags?) plus metadata (tags, yes). And files give you some great bonuses, e.g. easy to copy, easy to change tracks and albums (you don’t have to have a CD changer to listen to 40 track from different albums), easy to create playlists, they don’t expire (ever scratched your CD hard?), and on.

Btw, if we talk about CD/DVD as a holder of non-musical data, files are better too when you need the data often (for backups DVD is just good). Have you ever bought a StarForce protected game and then made a little scratch on a CD so your game wouldn’t load? Well, try to refund it, good luck.

2. CD is lossy.
There are some lossless formats which are superior to CD in terms of information storing, they are analog. There are also other lossy formats which are superior to CD but still digital (e.g. digital master recording, 24/96Khz FLAC, and so on).

The only losless formats for storing musical data are analog: vinyl (sure there is noise there, but that’s off-the point), tape (e.g. master tapes, which are used in studios) and the best is the live performance (the only truly lossy one, I suppose). So if you are kind of audiophile, you’d better listen to these. Vinyl is a great choise. And actually you may rip vinyl or tape into a lossy-better-than-CD (e.g. 24/96Khz) format if you have a decent audiocard and some other high-end equipment.

3. SACD and DVDAudio are not the options.
SACD is just the same as CD but with higher definition. The same goes for DVDAudio. And more to this: these formats are so fucking DRM’ed I will never ever use them. I would rather buy vinyl and rip it to FLAC with the same definition as SACD. Btw, analog cannot be DRM’ed ;)

So, that’s all for today.

Haskell is good. Is it?

Thursday, May 8th, 2008

Working through a few tutorials and books on Haskell I think I’m starting to feel that it’s all very good until it comes to Stateful Fucking Computations.

Well, I know that I do not know Haskell. And I know that I cannot wrap may head around all of its concepts right now (Monad Transformers? Arrows for god’s sake?). But on the other hand I see how it becomes, well, almost explosionary more compilcated as you start adding Stateful Fucking Stuff. Monad + Monad + Monad Transformer + Another one… And if you just have missed somehow that you will need, e.g. ST + IO + Error, and have just implemented smth without Error… Well welcome to ErrorT rewriting of great bunch of you functions. And it doesn’t seem to be always easy.

And of course I still have troubles with types. X :: A b c d WTF? Don’t yet clearly understand the difference between type, newtype & data. Well data is for algebraic datatypes. But type and newtype do somewhat confuse me.

And actually, writing an interpreter seems to be much harder (Parsec, State, IO through most of the program, Error throwing anywhere) than writing a compiler (Parsec -> Tree, work on the tree in a purely functional manner, generate code in a purely functional matter, you will only have to handle errors somehow in a good way. But I think it’s not that hard to do this w/o using monads here, actually. And IO only for Input once & Output once, all in main :: IO ()).

Frankly, Scheme seems to be MUCH easier to grasp. But after all, that’s one of the points why I actually did start to grok Haskell.

Good luck me.

Okay… I’m just fooling.

Thursday, May 8th, 2008

I don’t like PHP, but I do like Wordpress, so I’ve decided to give it a chance. Also it somewhat less resource-consuming than RoR.

Powered by nginx =)