metaperl's blog
Do arrows, monads, monad transformers clash when a large app needs libraries which use each of these?
Now for my question
from my neophyte perspective, Clean has a single easy-to-use mechanism for state maintenance - uniqueness typing.
Haskell has monads.
But then it also has arrows now.
And so there are two XML products, one based on arrows and one based monads.
When one is developing a large project in Haskell, what does one do if certain libraries are done in arrows and others in monads and you need to use both? And what about monad-transformers? Is that not yet a 3rd complication?
A Java programmer only has objects to handle any concept. So the idea of one library doing one thing and another doing another does not come up.
So, is there a difficulty in large application development because of the clashing advanced functional metaphors of arrow, monad, monad transformer?
Let's face it. There are very few large-scale products shipped in Haskell. Period. I dont know how good that is. or why that is.
I suppose Galois is happy with haskell, but the lack of large useable apps make you wonder if something like what I mention is getting in the way.
About my level and interest haskell
I have been through SJT's book. Been through the Haskell Road. Been through Sethi's "Algorithms". Like Bird and Wadler's intro to FP.
Now, I first got interested in Haskell in 2003. I love haskell. It is profoundly elegant. I never quite got over the hump into making it useful... 8 years as a Perl developer spoils you. But as a Perl developer, I think very functionally and studying Haskell has helped me immensely. But i always run back to my crutches when the game gets tight.
QWERTY makes a comeback on Dvorak
If you take a look at handheld computers and/or PDAs, GPSs, etc. you will note that the keys are quite close together.
This is where QWERTY is a good thing. It was a typing system designed to keep subsequent keystrokes from being very close to each other.
This is great for these tiny keyboards... with dvorak, I imagine your fingers would be bumping into each other.
- Login to post comments
Is logging really this tuff with Haskell?
I quote: http://programming.reddit.com/info/5ze57/comments
Haskell is too weird for me (if I want to add a logging statement, I don't want to rewrite ten functions to use monads instead of the types they previously had).
The algorithm for Discordian text encryption
module Crypt_Discordian
where
import List
vowel_list = "aeiouAEIOU"
is_vowel c = c `elem` vowel_list
move_vowels lis = move_vowels' lis [] []
move_vowels' [] c v = v ++ c
move_vowels' (x:xs) c v
| is_vowel x = move_vowels' xs c (x:v)
| otherwise = move_vowels' xs (x:c) v
remove_spaces str = filter (\x -> x /= ' ') str
encrypt str = List.sort $ move_vowels $ remove_spaces str
{-
The algorithm for Discordian text encryption is given at:
http://www.principiadiscordia.com/book/78.php
After implementing this, I realized that all the early steps are a farce.
But anyway, here is the algorithm in case you don't enjoy tilting your
head to read a page:
Step 1. Write out message (HAIL ERIS) and put all vowels at the end
(HLRSAIEI)
Step 2. Reverse order (IEIASRLH)
Step 3. Convert to numbers (9-5-9-1-19-18-12-8)
Step 4. Put into numerical order (1-5-8-9-9-12-18-19)
Step 5. Convert back to letter (AEHIILRS)
This cryptographic cypher code is GUARANTEED TO BE 100% UNBREAKABLE
.. so says the Principia Discordia. But I think we can generate and
test to break it.
Many thanks to kosmikus and Pseudonym for their help in developing
this module
-}
{-
Discordians. They are a
group of people who believe that spirituality is as much about
disharmony as it is about harmony.
So, in their primary book, Principia Discorida:
http://principiadiscordia.com/
you never know what is serious and what is play. The wikipedia has
more to say on them:
http://en.wikipedia.org/wiki/Discordian
-}
- Login to post comments
I've seen the J and the C, how about the Haskell?
C Language
int i, j, maxcol = 0;
float maxval = x[0][0];
for(i = 0;i<=xsize0;++i) {
for(j = 0;j<=xsize1;++j) {
if(x[i][j] > maxval) {
maxval = x[i][j];
maxcol = j;
}
}
}
J Language
maxcol =. (i. >./) >./ x
My that J code is quite concise ... so now we need to see that H language ... heheh.
My recent Factor travels in Light of Haskell
Factor is a modern stack-based language. It has a very interactive and easy-to-use GUI and is fun to work with.
Something was itching me about using this language and it was not until I picked up Haskell Road to Logic Maths and Computer Programming that I knew what was bothering me. He says that _Haskell_ is a type of descriptive programming very different from the prescriptive programming that you see in Java or C.
And that's it. In Factor, one is very mechanical. putting things on the stack, duplicating stack items. Hiding things in a retain stack, etc.
I notice that a lot of Factor functions for stack shuffling scale up to 3 stack elements. Is there something magic about this number of args to a word that it would never have to shuffle on more?
A very telling example of the difference in Haskell and Factor has to do with
this page on the Factor website discussing how to determine if all elements of a sequence obey a boolean:
The word "all"
Tests if all elements in the sequence satisfy the predicate.The implementation makes use of a well-known logical identity:
P[x] for all x <==> not ((not P[x]) for some x)
Let's compare the Factor and the Haskell:
Factor
: all? ( seq quot -- ? )
swap [ swap call not ] contains-with? not
Haskell
all p = and . map p
conclusions
The author of Factor is a very strong mathematician... what provoked him to involve himself in stackrobatics (acrobatics with a stack)?
Haskell Factor again
HaskelL
map putStrLn $
map (\(a,b) -> "Index: " ++ (show b) ++ "element: " ++ a) ( zip ["a" , "b", "c"] [0..] )
Factor
{ "a" "b" "c" } dup length [ "Index: " write . "Element: " write . ] 2each
CONCLUSION
Draw your own conclusions :)
Factor and Haskell comparison
Haskell
let sq = (\x -> x * x) in map sq $ map sq [1 .. 3]
Factor
{ 1 2 3 } [ sq ] map [ sq ] map .
Haskell 2
let sq = (\x -> x*x) in map (sq . sq) [1..3]
Factor 2
{ 1 2 3 } [ sq sq ] map .
Factor 3
3 [ 1+ sq sq ] map .
CONCLUSION
One interesting thing is that no new language mechanisms were necessary in Factor. In Haskell, one had to know $ and the composition operator . as well a varioius precedence rules to make clean concise code.
Haskell is a first-class action language as well
I had been considering Haskell a value-oriented language and had concluded that doing a lot of file system actions would be cumbersome. Dons, put that all to rest:
metaperl: dons - if you are doing a lot of file-system
manipulation, doesnt using a value-oriented language
like Haskell become cumbersome?
metaperl: dons - i mean things like copying files, renaming files, etc
dons: metaperl: hmm, like darcs?
dons: why? you're using a first-class action oriented language too, remember
metaperl didn't think of darcs
dons: so you can string together your manipulting functions in interesting ways
dons: i.e. haskell treats imperative statements as first class citizens
dons: you can pass them to functions, put them in data structures
dons: map over them
dons: > sequence_ $ reverse [readFile "/tmp/x", writeFile "/tmp/y"]
wow. Haskell wins again.
Python optional args - great for evolving source code
Optional args are not part of the Haskell Way. I have about 20 calls to this function:
def archive_zip(my):
for f in path(my.zip).files('*'):
f.move(my.archive)
but then I needed to do the same thing but I needed to prepend the date to the file for one particular invocation of this. So, in Python, I simply tacked on an optional argument and used a default value which led to the behavior that the oroginal 20 calls to this function would expect and then I added some code to handle prepending of date:
def archive_zip(my, prepend_date=False):
for f in path(my.zip).files('*'):
f.move(my.archive)
if prepend_date:
today = datetime.date.today()
s = today.strftime("%b-%d-%y")
newfile = "%s-%s" % (s, f)
syscmd = "cd %s; mv %s %s" % (my.archive, f, newfile)
print syscmd
os.system(syscmd)
Now, I'm not sure how quickly I could evolve this function in Haskell, but I'm dead curious to know.