Follow Slashdot blog updates by subscribing to our blog RSS feed


Forgot your password?
DEAL: For $25 - Add A Second Phone Number To Your Smartphone for life! Use promo code SLASHDOT25. Also, Slashdot's Facebook page has a chat bot now. Message it for stories and more. Check out the new SourceForge HTML5 Internet speed test! ×

Comment Re:It has its uses (Score 0) 411

foldl in Erlang is tail recursive automatically. foldr is not by default tail recursive in Erlang, Though I should mention foldr is tail recursive in languages like Haskell, and there are implementations of foldr in terms of foldl and visa versa. The conversions between foldr & foldl (depending on which is tail recursive) make explicit what needs to be done to move from non-tail recursive to tail recursive for recursions. Yet another reason you want to use those.

And as for can't follow. Your claim was about the messiness that these imperative artifacts remained and were worse. To avoid the messiness, you have to use the looping structures of functional programming Doing functional programming imperatively, of course is going to be messy. Doing functional programming functionally and you get the benefits.

Comment Re:It has its uses (Score 0) 411

OK I gotcha. It is shockingly easy in lazy code to write algorithms that are quadratic in memory. Arguably that's one of the big advantages of using standard morphisms and not recursions.

I also agree it is often (very often) easier to write an explicit recursion; and only then if you have to create a morphism structure. That's a different claim though than with loops. Once the algorithm is written as a loop you have all the pieces for a standard design pattern using morphisms. Which was my point to grandparent. The classification of all possible recursions is coming along nicely but we still have about 50 types of morphisms that (at least in theory) can show up. In practice hylomorphism covers most cases for recursions, and how to do this can be non-obvious. But hylomorphism covers all cases, with simple transformations of for-loops. Having written a for-loop you have the structure you need to do the morphism transformation, its the same work. My point above was about the easy case, not the hard case of general recursion you are talking about.

As an aside, I believe (not an expert) the condition for a graph traversal to be hylomorphic is that the operations follow the distributive law. Assuming I'm right on this, that's not a whole lot of math you just check your operation and apply one of the standard graph traversals.

Comment Re:It has its uses (Score 0) 411

Here we disagree. I think the general way you program that sort of thing is via. a fold. I don't know Erlang but it has the classic folds:

foldl(Fun, Acc0, List) -> Acc1
foldr(Fun, Acc0, List) -> Acc1
Fun = fun((Elem :: T, AccIn) -> AccOut)
Acc0 = Acc1 = AccIn = AccOut = term()
List = [T]
T = term()

foldl is the preferred one for Erlang

Comment Re:It has its uses (Score 1) 411

I'm going to argue there are no special cases that don't fit.

the set of all possible for loops (no side effects) \subset the set of all possible hylomorphisms (generalizations of map reduce) \subset of all possible recursions.

That's why I wanted to see a real example, because of mathematically they can't exist.

As for accumulators over loops those can be usually handled via. a fold providing the reduction operation is associative. The initial and final state never present a problem.


I'll agree I was considering lazy part of functional. At this point I think purity allows for laziness and laziness demonstrates a lot of the advantages of purity. Otherwise you are backed to mixed paradigm which I dealt with other places in this thread. As for lazy with large amounts of data, Hadoop is lazy. So I'm not sure what you are saying.

Comment Re:Functional Programming Considered Harmful (Score 1) 411

What you are describing is not remotely how state is handled in functional languages today. What's done is there is a stateful monad (either State, Read, Writer, IO or State&IO) which allows for an imperative style language. That imperative language handles stateful objects and makes function calls to an engine. The engine is stateless. No one is passing around the entire state of the world.

Here is a classic paper from a quarter century ago that summarizes this approach:

Comment Re:It depends on the use (Score 1) 411

ML is a cool language. I don't agree with you that SML issues are driven by lack of popularity. I think the problem was premature specification (essentially the same thing that happened to Common LISP). The spec requires consensus to change and thus SML stagnated. Others in the ML family like F# continue to good work SML started. Arbitrary length integer operations, expression type declaration, string formatting, translations, string joining... Those and many more are real issues.

Comment Re:"Like"? (Score 1) 411

You really do have to start over and write code very differently. That's unavoidable. Procedural languages are good at sequencing things for a von-Neumann architecture. Parallel systems are not von Neumann Architectures. Procedural code encourages bad thinking habits which create runtime problems. To do massive parallelism you want all your code to not not specify order of operations (so the runtime engine can decide) and not involve state changes till the end (since these require synchronizing between computing nodes). If you think about the first thing you learned when you learned to program it was: " a program is a sequence of steps" (order of operations). The second think you learned was print (state change).

You have to reorganize your code in a way consistent with a new paradigm. No library is going to solve that.

Comment Re: It has its uses (Score 1) 411

The classic example is church number subtraction. (I should mention Haskell solves this now via. rank 2 types, but very few languages have this).

So just to define terms church numbers take two arbitrary values: think f = (+1), z = 0 for the trivial case
zero f z = z
one f z = (f z)
two f z = f ( f z)
three f z = f (f (f z))

given two church numbers
minus n m should be the church number for their difference
ie, for all f, z
(minus three one) f z = two f z

generally this is done by using the predecessor function
pred n f z = snd $ n f' z' where
    f' (a,b) = (succ a, a)
    z' = (zero, zero)

and then
(minus m n) f z = (n pred m) f z

minus is not expressible as a rank-1 type in any language. Since most languages don't have rank-2 types...

Comment Re:Right time for functional programming (Score 1) 411

Mixed paradigm languages (like LISP) can be tough to have style guidelines. The purer functional languages enforce a functional style because bad code is a syntax error. You simply don't have syntax to break many of the rules. Haskell programmers often comment that getting a program with rich type definitions to compile is close to getting that program debugged.

Also standardizing form is less important when the number of lines reduces drastically. Functional programming encourages a paradigm that if a program is long there is an abstraction missing and fix the problem that way.

Slashdot Top Deals

Asynchronous inputs are at the root of our race problems. -- D. Winker and F. Prosser