Domain: haskell.org
Stories and comments across the archive that link to haskell.org.
Comments · 393
-
Re:Um, what?I've programmed quite a bit in Haskell. GHC is the most popular compiler by far and it implements all the latest parallelization and concurrency extensions (The last standard, Haskell 98, doesn't specify anything in this area).
There are two approaches to using multiple cores in GHC:
Concurrency; which ranges from explicitly created threads (either OS threads or lightweight runtime scheduled threads or some combination) that communicate through channels or locked variables or another traditional method, to STM.
The other is parallelism. Whereas the concurrency methods all use monads to sequence and control operations and produce code that looks more like that of an imperative language, parallelism is done entirely in pure functional code. The short description of pure functional is that all data is immutable. This is very useful for parallel execution because it greatly simplifies evaluation dependencies. You don't have to worry about modifying things in the right order or change conflicts because nothing is allowed to be mutated in the first place. This enables non-strict evaluation, which means that the various values in a program (even those nested in data structures) can be evaluated at any time during program execution, and in any order (as long as they are evaluated by the time they're needed). Parallel approaches include:- Simple use of par and seq . seq ties the evaluation of one term to another, to force a term to be evaluated immediately even if it isn't strictly needed yet. par creates a "spark" to evaluate a value. This spark may be executed by a different runtime thread than is currently running. Together, you can specify one value to be evaluated locally and another to be potentially evaluated by another CPU. This will work well if the values are reasonably expensive to evaluate (otherwise the overhead of creating the spark, while small, will be greater than the benefits) and independent. Can easily be used with e.g. evaluating all the elements in a list in parallel; runtime threads will pick up and execute the sparks as they are created.
- Parallel strategies. Create an evaluation strategy that mirrors the layout of your program, identifying the parts that can benefit from executing in parallel.
- Data parallel Haskell is an upcoming method that allows you to define parallel array structures that the compiler can see through to determine vectorized evaluation strategies.
In short, none of Haskell's methods of parallelization require you to be aware of threads or synchronization.
-
Re:Um, what?I've programmed quite a bit in Haskell. GHC is the most popular compiler by far and it implements all the latest parallelization and concurrency extensions (The last standard, Haskell 98, doesn't specify anything in this area).
There are two approaches to using multiple cores in GHC:
Concurrency; which ranges from explicitly created threads (either OS threads or lightweight runtime scheduled threads or some combination) that communicate through channels or locked variables or another traditional method, to STM.
The other is parallelism. Whereas the concurrency methods all use monads to sequence and control operations and produce code that looks more like that of an imperative language, parallelism is done entirely in pure functional code. The short description of pure functional is that all data is immutable. This is very useful for parallel execution because it greatly simplifies evaluation dependencies. You don't have to worry about modifying things in the right order or change conflicts because nothing is allowed to be mutated in the first place. This enables non-strict evaluation, which means that the various values in a program (even those nested in data structures) can be evaluated at any time during program execution, and in any order (as long as they are evaluated by the time they're needed). Parallel approaches include:- Simple use of par and seq . seq ties the evaluation of one term to another, to force a term to be evaluated immediately even if it isn't strictly needed yet. par creates a "spark" to evaluate a value. This spark may be executed by a different runtime thread than is currently running. Together, you can specify one value to be evaluated locally and another to be potentially evaluated by another CPU. This will work well if the values are reasonably expensive to evaluate (otherwise the overhead of creating the spark, while small, will be greater than the benefits) and independent. Can easily be used with e.g. evaluating all the elements in a list in parallel; runtime threads will pick up and execute the sparks as they are created.
- Parallel strategies. Create an evaluation strategy that mirrors the layout of your program, identifying the parts that can benefit from executing in parallel.
- Data parallel Haskell is an upcoming method that allows you to define parallel array structures that the compiler can see through to determine vectorized evaluation strategies.
In short, none of Haskell's methods of parallelization require you to be aware of threads or synchronization.
-
Re:Um, what?I've programmed quite a bit in Haskell. GHC is the most popular compiler by far and it implements all the latest parallelization and concurrency extensions (The last standard, Haskell 98, doesn't specify anything in this area).
There are two approaches to using multiple cores in GHC:
Concurrency; which ranges from explicitly created threads (either OS threads or lightweight runtime scheduled threads or some combination) that communicate through channels or locked variables or another traditional method, to STM.
The other is parallelism. Whereas the concurrency methods all use monads to sequence and control operations and produce code that looks more like that of an imperative language, parallelism is done entirely in pure functional code. The short description of pure functional is that all data is immutable. This is very useful for parallel execution because it greatly simplifies evaluation dependencies. You don't have to worry about modifying things in the right order or change conflicts because nothing is allowed to be mutated in the first place. This enables non-strict evaluation, which means that the various values in a program (even those nested in data structures) can be evaluated at any time during program execution, and in any order (as long as they are evaluated by the time they're needed). Parallel approaches include:- Simple use of par and seq . seq ties the evaluation of one term to another, to force a term to be evaluated immediately even if it isn't strictly needed yet. par creates a "spark" to evaluate a value. This spark may be executed by a different runtime thread than is currently running. Together, you can specify one value to be evaluated locally and another to be potentially evaluated by another CPU. This will work well if the values are reasonably expensive to evaluate (otherwise the overhead of creating the spark, while small, will be greater than the benefits) and independent. Can easily be used with e.g. evaluating all the elements in a list in parallel; runtime threads will pick up and execute the sparks as they are created.
- Parallel strategies. Create an evaluation strategy that mirrors the layout of your program, identifying the parts that can benefit from executing in parallel.
- Data parallel Haskell is an upcoming method that allows you to define parallel array structures that the compiler can see through to determine vectorized evaluation strategies.
In short, none of Haskell's methods of parallelization require you to be aware of threads or synchronization.
-
Re:I'm guessing the CPU limits are generous.
Haskell makes quicksort run slow?
It would be more accurate to say that you can't implement the QuickSort algorithm properly with immutable arrays; its performance relies on being able to sort the elements in-place, without allocating new memory at every step. Haskell does have mutable arrays, however: IOArray and STArray. (more info) There are also sorting algorithms better suited to immutable data.
Note that the introduction of mutable references makes the GC process much less efficient. The unboxed mutable array types (IOUArray, STUArray) do not have this drawback, but are limited to plain, fixed-size values.
-
Re:Many good choices
Perhaps you might be interested in the article in the Monad.Reader Issue 13 (warning: pdf) where the TeX language is used to solve the 2008 ICFP programming contest.
He writes a program to control a Mars rover in TeX, it is really impressive. You can even download the source code.
-
Re:Need to decouple Javascript before it's too lat
Want to innovate by using a functional language to bring your solution to market faster? No can do.
That's not entirely true - you could write in Haskell and compile to JavaScript.
-
No way of verifying/validating software?
"It is well-known in our community that there is no scientific, firm way of actually completely verifying and validating software."
It’s called Haskell with QuickCheck, idiots! Look it up!
And yes! It gives you guarantees on the level of mathematical proof, that it’s doing what it’s supposed to do!How can someone work in an area where it’s about life and death of real people, and not know that??
Imagine someone saying that who works in the business of heart-lung-machine development. It’s hair-raising! -
Veeery old news.
I thought a lot about these things (like “truth” and beliefs), and here is what I came up with:
————————————————————
- You can not prove that anything, except for yourself, exists. It can only be deduced.
- There is no absolute knowledge (aka facts / truth). Knowledge is relative to the the ingoing information that it’s based on.
- There is no “neutral“ information. Information is defined trough being a difference from the neutral default, and then it’s modulated by all the sources that it passed trough.
- Every source has an associated trustworthiness factor for every point in time, that is calculated out of the consistency {{of the past experiences and the new experiences} from that source} with all the other knowledge. (I’m unsure about the weighting though.) [= Network of trust]
- There is always another source behind any source. [Causality]
- That is why there is no “guilt” of a source.
- The primordial original source is unascertainable. [What caused the big bang? “God” as a trick to protect the mind from getting stuck over this.]
————————————————————
- Every input (=information) changes us. (Physically mandatory.)
- And we act (=react) solely on the basis of our state at a point in time.
- Our state is defined by the folding (foldl over t) of all earlier inputs.
- Folding" in the sense of
- the self-modulating superpositions of the learning effect of the neural network, in particular
- and fundamentally of all changes of us (as matter) caused by that input, in general.
- Put simply: So the question is, what it makes out of you, and what you then make out of it. [=Causality]
- Our mental existence is thus defined by a sequence of transformation of our inputs.
————————————————————
We are only
- expanding bio-mass ((self-)organizing matter/energy)
- expanding ideas (in the sense of the input transformation)
fighting for available resources
- Bio-mass: space-time, matter/energy,
- Ideas: space-time, mental energy.
————————————————————
I’m obviously open for corrections. But beware that I blew my own mind, multiple times, while in the progress of understanding it. So your quick shot will most likely turn out to be only valid until you think a bit more about it.
;) -
Veeery old news.
I thought a lot about these things (like “truth” and beliefs), and here is what I came up with:
————————————————————
- You can not prove that anything, except for yourself, exists. It can only be deduced.
- There is no absolute knowledge (aka facts / truth). Knowledge is relative to the the ingoing information that it’s based on.
- There is no “neutral“ information. Information is defined trough being a difference from the neutral default, and then it’s modulated by all the sources that it passed trough.
- Every source has an associated trustworthiness factor for every point in time, that is calculated out of the consistency {{of the past experiences and the new experiences} from that source} with all the other knowledge. (I’m unsure about the weighting though.) [= Network of trust]
- There is always another source behind any source. [Causality]
- That is why there is no “guilt” of a source.
- The primordial original source is unascertainable. [What caused the big bang? “God” as a trick to protect the mind from getting stuck over this.]
————————————————————
- Every input (=information) changes us. (Physically mandatory.)
- And we act (=react) solely on the basis of our state at a point in time.
- Our state is defined by the folding (foldl over t) of all earlier inputs.
- Folding" in the sense of
- the self-modulating superpositions of the learning effect of the neural network, in particular
- and fundamentally of all changes of us (as matter) caused by that input, in general.
- Put simply: So the question is, what it makes out of you, and what you then make out of it. [=Causality]
- Our mental existence is thus defined by a sequence of transformation of our inputs.
————————————————————
We are only
- expanding bio-mass ((self-)organizing matter/energy)
- expanding ideas (in the sense of the input transformation)
fighting for available resources
- Bio-mass: space-time, matter/energy,
- Ideas: space-time, mental energy.
————————————————————
I’m obviously open for corrections. But beware that I blew my own mind, multiple times, while in the progress of understanding it. So your quick shot will most likely turn out to be only valid until you think a bit more about it.
;) -
Re:That's small
Pff. GHC takes over 8 hours and eats up to 8 GB of RAM (per compiled file) in the process.
I literally start compilation when I go to bed, and it’s nearly finished when I wake up.
-
Re:The optimal blend...
So why do we have so many unique languages?
It's because we don't have a clear idea on which language features are good, and which aren't. If you ask someone (say, me ~), you'll probably get a straightforward reply, but if you ask another guy, he is quite likely to strongly disagree on many major points.
There are many arguments both for and against dynamic typing, for example. There are similarly many arguments for and against OOP. There are advantages of having code pre-compiled to native, and there are also advantages of having a VM with a JIT compiler. Tracing GC vs manual memory management (+ smart pointers). The list goes on and on...
Within the static typing camp, there are still unsolved issues with the expressivity of type systems - some believe that typeclasses (Haskell-style) are the way to go, but there are still some unresolved problems there for more complex things. Some want effect typing. Some decry both as overcomplicated, and say that they're overkill, and it's easier to simplify the code.
Then there are bleeding-edge language features. Do we need STM? Do we even want it - can it be efficiently implemented at all?
Consequently, you get different languages, depending on which of the above (and many other) points are emphasized. Lately, we're starting to get more "kitchen sink" languages combining all approaches in hope that all of them are useful to one extent or another. F# is actually such a language, in a sense, being hybrid FP/OO (it also has "duck typing" member access, though no means to define true dynamic classes as in Python or Ruby). Scala is even more so.
Existing languages are also heading in the same direction - C# is a good example of that, starting its life as Java-like OO language, then getting some FP features in 2.0, a major FP'esque facelift in 3.0, and now duck typing in the upcoming 4.0.
By the way, F# isn't really a new language. The base language is ML, which is over 30 years old now. The specific ML dialect from which F# is derived is OCaml - that one is still in active development, but got started 14 years ago.
-
xmonad + KDE = awesome
This may not be exactly what you want, but you can actually run XMonad as the WM on top of KDE or GNOME. It comes with a configuration so you still have the Kicker wherever you put it. XMonad also can float arbitrary windows, either programmatically by their name or class, or manually by dragging them out of the tiles. I've been using XMonad for about three days, with KDE at work, and I like it tremendously; prior to this my only real experience with tiling WMs was with Ion/Pwm, which apparently intentionally does not support Xinerama in the core, though there is a plugin for it. Tuomo is about the whiniest programmer on the planet though. Something about Finnish programmers...
;)Another thing to consider, though I'm not sure how doable this is in actuality, would be some kind of X proxy to launch your apps in, and then just run two X sessions, one for each display, and manually migrate them through the proxy when you need to. This, if it can be done, would be completely WM/DE agnostic.
-
xmonad + KDE = awesome
This may not be exactly what you want, but you can actually run XMonad as the WM on top of KDE or GNOME. It comes with a configuration so you still have the Kicker wherever you put it. XMonad also can float arbitrary windows, either programmatically by their name or class, or manually by dragging them out of the tiles. I've been using XMonad for about three days, with KDE at work, and I like it tremendously; prior to this my only real experience with tiling WMs was with Ion/Pwm, which apparently intentionally does not support Xinerama in the core, though there is a plugin for it. Tuomo is about the whiniest programmer on the planet though. Something about Finnish programmers...
;)Another thing to consider, though I'm not sure how doable this is in actuality, would be some kind of X proxy to launch your apps in, and then just run two X sessions, one for each display, and manually migrate them through the proxy when you need to. This, if it can be done, would be completely WM/DE agnostic.
-
Re:xinerama and xrandr
If its using the same X session (the same user login), then this is possible. I have 2 monitors, both running 2 different "deskstops". The wm lets me switch workspaces on each one seperatly. xmonad so does enlightenment 17. I bet there are a few more wms that can do this as well, those are just the two that i've tried.
BTW, i can't believe this made it to the front page, its really a question that just belongs to your favorite distro's forums. Since we are on the topic, does anyone know how to get printers working in linux
:)? -
xmonad and gnome/kde can live together
I spent months trying to do the same thing with a normal window manager but I never found a way that worked well. xmove sounded promising but I couldn't get it to run. Now I use xmonad and it behaves exactly the way I want. You can set it up with window decorations and run it in Gnome and whatever else you want to do. It's really not as big of a leap as you think it is. If you're scared of the "tiling" aspect, you can set every workspace to floating and it will never do any tiling.
-
Re:what's new?; bazaar versus git
I want lazy evaluation. I want to be able to do this:
(setq some-variable (lazy (some-function foo bar)))
And then I want the next thing after that to go ahead and be evaluated. I don't want execution to pause and wait for some-function to complete until some computation actually needs the value of some-variable.I can't tell from just one small example using metasyntax, but that looks more like you want a future. Those would be nice, but I don't see emacs doing those anytime soon. If you don't want to compute something right away, wrap it up in a lambda and bind it to a symbol. Emacs's brand of lisp lets you funcall a symbol through as many layers of indirection as you want. I think you can even get closures from the cl package, even if they're not implemented terribly nicely.
Selective lazy evaluation is more of an occasional syntax convenience for specific problems like streams, but outside of those areas, it's one of the leakiest abstractions you can get -- you end up having to sprinkle laziness declarations all over unrelated code to maintain the laziness you want.
Much as I love emacs, I think you can be reasonably sure that the emacs lisp environment is purely in maintenance mode and will never see significant architectural changes. You want an editor with a pervasively lazy extension language, try Yi.
-
Re:AppleScript?
They don't claim it for all cases. Of course, there are adversarial cases for every approach. But, section 3.3 of this page claims that most programs are shorter by a factor of 2 to 10. Higher-order programming is just more tight (and ultimately maintainable)--that much is undeniable (and when programs are written correctly in o-o/imperative languages [i.e., when they are well-factored] they start to approach the functional style). It is much better in my opinion to go straight to FP and not rely on such crutches to try to get you there [especially when even in best case, you can only approach it--worst case is much worse!]. [And, btw, I do the functional style of programming in C++ and there's a lot more syntax around such than with a language like F# or Haskell. It's much better to just go with a language which was built with FP as the emphasis].
And, I'd be curious to see how you think that user interfaces or calling other programs are problems for functional languages though. I think the difference in conciseness from one program to the next has more to do with its factorability. -
Re:Concurrency?
That's what I really wasn't understanding: Haskell does let you create side effects. But it is still a "pure functional" language in the sense that the side effects are implemented in such a way that you can still analyze Haskell programs as pure functional programs, because the side effects that Haskell lets you create are entirely hidden from the universe that Haskell knows about.
This isn't quite right. Haskell can model side effects, and the side effects do not have to be hidden from Haskell. This is typically done with monads, which are formally equivalent to state machines. Every monad has a function called "eval" which can be defined in terms of bind (>>=) and return. eval does what it says: it runs the state machine and returns a value.
IO is a "special" monad because its eval function is written in C instead of in terms of its Haskell bind and return functions. It can inject state into pure code, as arguments to functions. If you were to re-write the IO eval function in terms of >>= and return, IO would merely simulate input and output. For example, if your program is supposed to write to a file, it would in fact be creating a representation of a file in memory and storing it there until the program terminated. Depending on where you gutted the eval function, you could theoretically have a representation as abstract as a "File" type value, or as concrete as a sequence of bytes as yet unwritten data in the binary ordering of your choice. You would be unable to write the file to disk without the special eval function.
The IO monad's bind and return functions are pure. Indeed, the entire language is. The only construct that isn't is a function you can't call from within the language, because it calls your program.
http://haskell.org/ghc/docs/latest/html/libraries/base/src/GHC-IOBase.html#IO
-
Re:on haskell quicksort
Data.List.sort uses mergesort (and the implementation is actually a bit shorter than your code, though yours seems a bit more readable to me). http://www.haskell.org/ghc/docs/latest/html/libraries/base/src/Data-List.html#sort
-
Re:Not to sound like an ass, but...
EmptyDataDeclarations allows for data types without a constructor... but to be perfectly honest I haven't quite figured out what practical benefit they have
:). I'm sure there is a reason, but I don't think it's as trivial or obvious as you make out.Consider the tag struct idiom in C++:
struct open_read_t {};
struct open_read_write_t {};class File {
File(const string& name, open_read_t); // Open for reading.
File(const string& name, open_read_write_t); // Open for writing.
};The tag structs are not used to carry data; their only purpose for existing is to disambiguate the two constructors.
Similarly, in the STL, tag structs are also used to mark iterator categories, to make sure that when you could use more than one algorithm for a container, the most appropriate one is selected.
This is essentially what empty data declarations are for in Haskell, except that by having no constructors, you can guarantee that they will never be instantiated. The most common use is in conjunction with phantom types.
-
on haskell quicksort
I agree it's not always the best example, but there are four reasons why "qsort [1..10000]" is slow, and you can address three of them without writing something that's "100 times less readable than C".
The first problem is that naive quicksort on an already-sorted list/array is O(N^2). The fix is to grab an element out of the middle and use that as your pivot. That alone will make qsort far faster. (I tried it.*) The resulting code is, of course, a bit messier.
Secondly, the qsort function has no type signature, so it will default to the most polymorphic implementation, which is something like qsort
:: Num a -> [a] -> [a]. Typing "qsort [1..10000] probably (though I'm not sure, it's a ghci-specific thing) defaults to using Integer, which is less efficient than a machine Int. If you constrain the type signature the code will be faster.Thirdly, you're using ghci. Code compiled with "ghc -O2" is far faster. (Be sure not forget that -O2, it make the code about 10x faster.)
The fourth reason is that C is doing in-place array swaps. (You can do the same thing in Haskell using the ST monad if you really want to. I don't think the result will be "100 times less readable", but it will be fairly ugly compared to the pure version. There are a couple such implementation here.) Whether doing quicksort with lists is good enough really depends on what you're doing.
* Quicksort modified with a swap, then mangled by slashdot:
module Qsort where qsort [] = [] qsort xs = let n = length xs in if n > 100 then let split = n `div` 2 (a,b) = splitAt split xs in _qsort $ (xs!!split) : (a ++ (tail b)) else _qsort xs _qsort [] = [] _qsort (x:xs) = qsort (filter (= x) xs)
-
Re:Is it just me ?
Hehe
/. screwed the Haskell code, look here for the source :http://www.haskell.org/haskellwiki/Introduction#Quicksort_in_Haskell
;-))) -
Re:Not to sound like an ass, but...
Moreover, the DoAndIfThenElse extension merely extends the "do" syntax with if/then/else clauses; it is syntactic sugar. Empty data declarations are essentially union types unioned over no labels and therefore can have no values except for the bottom value.
References:
http://hackage.haskell.org/trac/haskell-prime/wiki/DoAndIfThenElse
http://hackage.haskell.org/trac/haskell-prime/wiki/EmptyDataDecls -
Re:Not to sound like an ass, but...
Moreover, the DoAndIfThenElse extension merely extends the "do" syntax with if/then/else clauses; it is syntactic sugar. Empty data declarations are essentially union types unioned over no labels and therefore can have no values except for the bottom value.
References:
http://hackage.haskell.org/trac/haskell-prime/wiki/DoAndIfThenElse
http://hackage.haskell.org/trac/haskell-prime/wiki/EmptyDataDecls -
Re:Such dependancies annoy nLite users!
Would you like to see a fully compliant XML parser, written in a few hundred lines?
Writing an XML parser in a few hours is impossibly difficult. Writing it in a few days is not. It's no harder than writing an S-expression parser. This is a task freshmen students are given in Introductory Scheme courses. (Typically, they get a few weeks to write parsers and evaluators, in order to implement a Scheme runtime, written in Scheme.)
-
Re:Such dependancies annoy nLite users!
A fully compliant XML parser is only a few hundred lines of Haskell code. A fast XML parser is a little longer.
See http://hackage.haskell.org/packages/archive/HaXml/1.19.7/doc/html/src/Text-XML-HaXml-XmlContent-Parser.html for an XML parser implementation.
-
Re:Duct Tape
More seriously, you may wish to investigate 'Software Transactional Memory' (STM).
-
Poetic justice
Well, to be fair, Microsoft didn't just come up with customXML on its own, they "partnered" with i4i, learned all about their product, then copied what they wanted from it and shafted i4i. While I do NOT like software patents and think they should be abolished, I'm not really going to defend Microsoft here. They're getting a bit of poetic justice, IMHO.
Granted, I would like this lawsuit to instead concern whatever contracts Microsoft had with i4i instead of patent law (claims which aren't worth pursuing when you can get $300 million judgments from patent claims), but I honestly think that this case is, overall, a good thing because it:
A) Highlights how ridiculously overpowered software patents--even those for fairly trivial "inventions"--have become.
B) Punishes one of the biggest proponents of software patents, proving that they were lying when they talked up how much they "respect" IP.So make no mistake: I still want to abolish software patents completely. They're patents on mathematics (and there's mathematical proof of their equivalence available) and they shouldn't exist. But as long as they do exist, I can think of nothing better to happen than for their biggest proponents to get shafted by one of the patents.
-
Yes it is! And here's the proof!
> Software is just a step-by-step instruction list. It's is no more a form of math than is a cookbook.
You might want to look up Curry-Howard correspondence someday.
Not only is software math, there's an equivalence theorem relating the two. If that were not the case, the people over at MetaMath wouldn't be able to get very far.
In other words, that statement isn't just wrong, it's provably wrong and you'll have to prove the Curry-Howard correspondence wrong before you can claim otherwise. One of the weird properties of a correspondence is that you can turn software back into math.
I know that people think that math is all arithmetic and integrals or something, but that's just not true.
-
Re:Huh??
I just replied to your blog. This is what I wrote.
It seems that the example I typed up broke. I meant:
do
x <- MonadInstance a
y <- MonadInstance b
return (x + y)is equivalent to
MonadInstance a >>= ( \x -> (MonadInstance b >>= ( \y -> ( return x + y )))
If this code runs at all, the function bindings force the order of evaluation.
Even if the runtime is making promises (thunks in Haskell-speak), it is going to have have to unroll those promises and compute x before it can compute f x in a computation (A x) >>= f. There's just no way around that. If an operation is going to occur at all, laziness can't change the order in which its sub-operations occur. It merely means that the runtime performs computations on demand.
Beta reduction is what allows different computational orders, depending on the functional argument dependency tree. For example, in the computation f (g x) (h y), (g x) or (h y) can be computed first, but they BOTH have to be computed before f (g x) (h y) (the whole thing).
But the whole point of a monad is that the monadic combinators bind the output of one computation to the input of a one argument function. There is no ambiguity about the order of f $ g $ h $ i $ k, and laziness will not change the order in which these functions are called. k goes first. The monadic combinators have semantics similar to the application operator $.
http://en.wikipedia.org/wiki/Beta_reduction
Also note the Control.Monad documentation (http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Monad.html#v%3A%3E%3E%3D), which describes the semantics of >>= and >> as:
(>>=) Sequentially compose two actions, passing any value produced by the first as an argument to the second.
(>>) Sequentially compose two actions, discarding any value produced by the first, like sequencing operators (such as the semicolon) in imperative languages.
Laziness does not change the order in which operations occur. Beta-reduction (what the Haskell literature calls "non-strict reduction" or "evaluation") is what does that. These are related but NOT synonymous. You can have an eager, non-strict language. Or lazy and strict semantics. A web server like Apache is lazy and potentially strict as a computational system, since it lazily dispatches requests to a runtime of your choice.
-
Re:A language with a popular forum.
The Haskell School of Expression by Paul Hudak actually is surprisingly multimedia-oriented. The only problem is its price.
-
The C definition, same token on both sides.
I wasn't logged in before, GP anon was me. Anyhow, the period was the end of the sentence, not some attempt to make it into a float/string/boolean/whatever and I certainly didn't use the Python operators. It's supposed to be the same token (1) on both sides. But that's why we use formal languages that are picky about syntax and which can be checked automatically to avoid people finding weird ambiguities to question.
The theorem I was mentioning above is called Curry-Howard-Lambek correspondence (it took me a while to find all the links):
The Curry-Howard-Lambek correspondance is a three way isomorphism between types (in programming languages), propositions (in logic) and objects of a Cartesian closed category. Interestingly, the isomorphism maps programs (functions in Haskell) to (constructive) proofs in logic (and vice versa).
(Wiki links added because most people are too lazy to Google the terms they don't understand. Especially if they don't realize that they don't actually understand them.)
So even if you find some crazy language where they define != to be an equality operator or something equally unusual, software is still equivalent to math. Metamath wouldn't be possible otherwise. And as you can see, they're doing just fine.
-
Re:Top 3 features
I played with this some time ago. I'm not really into Haskell, just wanted to see what's so special about it (yes, it has some nice features and I think guards could be a nice addition to C# but the language is not for me I think), so I don't know much about it.
-
Re: Sieve of Eratosthenes
Sieve of Eratosthenes is a good example because it has been solved but the discussion of the flaws in older solutions are quite subtle. http://www.haskell.org/pipermail/haskell-cafe/2007-February/022666.html
The "flawed" version was written by David Turner over 30 years ago. At that time, his version was meant to illustrate the expressiveness of pure functional languages, not to achieve speed.
The discussion you reference was as much about what algorithm is "the genuine sieve of Eratosthenes" as about speed. You can read all about it in O'Neil's paper that came out of that discussion, "The Genuine Sieve of Eratosthenes".
But yes, there are subtle issues in the speed of sieve algorithms. And yes, this is a good example. Compare O'Neil's work to the imperative papers she references. You can see how much easier it is to achieve the same results in a functional setting than in an imperative one.
-
Re:Scala
Sieve of Eratosthenes is a good example because it has been solved but the discussion of the flaws in older solutions are quite subtle.
http://www.haskell.org/pipermail/haskell-cafe/2007-February/022666.html -
Re:LISP
As best I can tell, Template Haskell is still in the experimental stage, and the input must fit in a valid parse tree. If Haskell didn't already have, e.g., "let decls in e", and you wanted to add it, how could you possibly define "let" and "in" and get the parse you wanted? In Lisp you can create "let" from scratch in maybe a dozen lines and have it behave exactly as if the language designers had put it there from day one.
-
Re:Speed is not all
I fail to see how lazy eval. or lazy casting or similar things could help us to have more error-prone, robust, easy to debug and reliable code.
Potentially useless, but canonical example of quicksort:
qsort [] = []
qsort (x:xs) = qsort (filter (< x) xs) ++ [x] ++ qsort (filter (>= x) xs)
Want to select k-best elements? Just do take k (quicksort input). Laziness reduces O(N.log N) to just O(N) *and* you don't have to construct a heap. More to see here and here.
I prefer to be in control of things, even if that means a small speed penalty.
Well, it is Lisp, for one, that gives you the ultimate control of things.
:-)Runtime code juggling might a nightmare to debug in production environment
Lua people had this to say to that: "If you don't want to do it, just don't do it." Nobody is forcing you to abuse the Turing-completeness of C++ templates, either.
-
Re:Please ban them
Potential buffer overflows, de-referencing null pointers etc should not get past the *compiler*.
Note, however, that there's nothing stopping you from writing socket [...] system(recv()) if your language has sockets and the ability to run other programs.
Some security problems arise not because you failed at expressing what you meant, but because you (probably unknowingly) meant the wrong thing.
That being said,
To be honest I do not have a prefered language to suggest
Python does all your buffer work for you. It doesn't have null, although the None object acts kinda' like it. I'm sure similar things can be said about perl, ruby and shell scripts.
But that's probably not the answer you wanted.
I can also say good things about Haskell. It's a functional language similar to ML*. The type system forces you to be explicit about anything with side effects, in particular I/O. It doesn't have pointers (well, except behind the surface), so there are no nulls.
There's an algebraic datatype called Maybe (taking a type parameter t) which can either be "No value" or "Some value of type t", so there's your null-equivalent. But---you have to be explicit about wanting a 'Maybe t' rather than just a 't', and the compiler warns you if you don't handle the no-value case (similar to C's switch/enum warning).
The thing I like the most: even though you can violate the rules about being explicit about your side effects, the way to do it is by calling a function named unsafePerformIO. If you read the documentation of it (http://cvs.haskell.org/Hugs/pages/libraries/base/System-IO-Unsafe.html), you god damn know that you're being a naughty boy. And it's easy for your version control system to grep for this and automatically reject checkins using it
;-)* ML similarities: type inference, the type system, how algebraic data types work and look, syntax of function application (both partial and complete), lists are fairly important, has map/filter/reduce, you can define your own operators and their precedence.
-
Re:Sigh. Every time I see Stallman quoted.....
If you think it's trivial, you haven't tried recently. I mean, sure, the Solaris linker is pretty spartan, but bootstrapping gcc on OpenSolaris is a nightmare. Autotools can't figure out proper ABIs on Solaris (you have to pass it to configure an awful lot), set -R and -L, etc. Compiling ghc (Haskell) is a bigger adventure, as the GNU autotools are pathetic on systems other than Linux.
Frankly, the GNU-isms running rampant make it really goddamn difficult to compile software that's supposed to be portable without building the entire GNU toolchain (and even then, autotools often doesn't work properly). The sooner LLVM blows away GCC, the better. This is not at all reasonable, and that's assuming you're not trying to use some dirty compiler like Sun Studio.
Until the developers bother with some basic portability which doesn't involve setting environment variables which shouldn't need to be set, you can keep your "GNU/" off the front of my OpenSolaris/BSD. -
Re:AdaptThe blocking problem of dynamic dataflow architectures is the amount of content-addressable (or associative) memory.
It is very easy to overflow any amount of CAM/AM by using just matrix multiplication. For N^2 data items matrix multiplication produces N^3 multiplications that can be executed in parallel. So for reasonable N=1000 we get 10^9 multiplications, stored as 2*10^9 multiplicands in CAM.
We found a way to overcome that problem while I worked at IPMCE. We use "program time" to sort tokens out of the AM. Those that are "most far away in future" swapped out to free space for more needed ones. That way we control available parallelism and guarantee that tokens eventually meet their pairs so computation won't get stuck.
It's like "bubble sort" of tokens with a window instead of single element, so we called it sorting dataflow machine.
It is not unlike throttling which was used to control parallelism in CM-5/Id90 implementations (AFAIRC). The only difference is that usual dataflow throttling should be applied carefully as it is not guarantee computation progress (it can get stuck).
To verify our suggestions I developed a model of that architecture: http://thesz.mskhug.ru/browser/hiersort
The model exhibits some architectural decisions to speed up the whole computation sorting process. Take a look at it as the source files are there (except they are in Haskell programming language;).
For first version of completely new architecture developed under three months of free time it worked pretty well. It do not stop, it sorts and it provides ~70% of "FPU" load in my testing tasks.
-
Re:Huh?
They're not looking for vendor tools to come out of it, they're looking for research to come out of it to help build such a tool.
http://www.haskell.org/haskellwiki/GHC/Data_Parallel_Haskell
-
Re:try something new
Can the xmonad window manager be used in a desktop environment like KDE or Gnome?
Excellent question, AC! Yes, it is being used this way by some people with Gnome. Help with setting that up here.
-
try something new
I'd like to take this opportunity to suggest that people try something exciting and different! The xmonad window manager!
It's a tiling-style wm like ion, ratpoison and dwm (in fact it started out as a reimplementation of dwm's features with the addition of xinerama support). xmonad is very small, very fast, very stable. Written in the Haskell programming language. And supported by a very helpful and friendly bunch on #xmonad at freenode.
Try this kind of window manager, you may just like it quite a bit more than the conventional model of dragging and sizing your life away. I went from fluxbox to xmonad last summer and use it on everything, period. It's that good.
-
Re:Darcs
The largest user of Darcs, GHC, just stitched to git because of serious merge/conflict issues, bugs, and performance problems. They have posted an evaluation of their situation.
-
Re:Darcs
Check out GitForDarcsUsers. Also, you may be interested in why ghc switched to git.
-
Re:Darcs
Check out GitForDarcsUsers. Also, you may be interested in why ghc switched to git.
-
Re:Darcs vs. Git
I can understand the advantage of using distributed version control. But given all the Haskell people involved (who came in via Pugs) I'm surprised they went with Git vs. Darcs.
Does anyone know if speed is as large of an issue as it is for Linux kernel or was there another reason?
Actually, you might not know this, but the Haskell folks already moved over to git from darcs a while ago. They were having scalability issues and did a 6 month survey to determine which distributed version control they should go with and determined that git was the best of the breed. Here are the links:
- Announcement: http://article.gmane.org/gmane.comp.lang.haskell.glasgow.user/14819 [gmane.org]
- Comparisons: http://hackage.haskell.org/trac/ghc/wiki/DarcsEvaluation [haskell.org]
-
Re:Convince your boss.
There is a relatively small but active community of open source functional programming languages. The big names (for this relatively small group) are Scheme, Haskell, ML and Ocaml, and Erlang. Lisp and the new open source JVM language Scala also support functional-only programming styles. So does Microsoft's language F#. (But Lisp, Scala, and F# can be used in non-functional ways.)
There are some great discussions on the advantages of functional programming. Here's one on the Haskell website: http://www.haskell.org/haskellwiki/Introduction Another one is this paper on the subject: http://www.md.chalmers.se/~rjmh/Papers/whyfp.pdf
I am not very experienced with functional programming at all. But if I understand it correctly, one of the ways functional programming makes parallel processing easier is the fact that variables are immutable. That is, variable values can't be changed once they are assigned.
So if you want to do a String reverse in a functional style with immutable variables, it could be (Java):
public String reverse(String s) {
if (s == null || s.length() < 2) return s;
else return (s.substring(s.length() - 2, s.length() - 1) + reverse (s.substring(0,s.length() - 2);
}
That's awkward an inefficient in Java, but you hopefully see how it works. A lot of the difficulties with parallel programming come from having multiple threads accessing and changing shared mutable (changeable) variables. You have to coordinate access carefully or there can be big problems. With immutable variables, that particular source of bugs does not exist. -
Re:An brief introduction to functional programming
Notably, it's impossible to do a quicksort in a functional language
Some Haskell guy seems to disagree.
-
Re:Anonymous Coward
See http://www.haskell.org/haskellwiki/99_questions/90_to_94 for the really obvious solution.