If I may, let me address the (at least) four dimensions of coding that have come up in this thread, as concretely as possible but with some generalizations added:
1. Performance Generally speaking, Python is a thin layer over C. It comes with almost all the performance advantages of C and all the disadvantages (complete lack of safety). Specifically, the “naive” Racket code (that was mentioned) allocates many intermediate list raising the pressure on memory. As a functional programmer, you need to pay attention to allocation (cons, structs, lambda, objects) when performance matters. ~~ Haskell performs some “loop fusion” aka “deforestation” but the overhead of uniform laziness gets in the way. If you were to ask on a Haskell mailing list, you’d be told “sprinkle ! everywhere” (meaning make the program as strict as possible). The performance of your program also suffers from linking Typed Racket code into Racket code in a critical place in the for loop. The for/ version in Typed Racket is the best you can do in terms of performance. 2. What matters about code (systematic design) Performance, in many cases. But real code is code that survives long enough so that person 2 will open a file many weeks/months/years after after person 1 wrote it. (Person 2 could be an aged version of person 1.) The performance of person 2 on changing this file depends on — how systematically person 1 went about his work — how well person 1 expressed this systematic procedure (— how well person 2 is trained to understand these ideas) The goal of HtDP is to get this idea across. One day I’ll write HtD C/S to scale this up. 2a. Functional programming … excels at designing systematically code at all scales. There are many reasons; here are 3 examples: — fp encourages type-driven design in a rich language of types (even if the types are informal as in HtDP). — fp drives people to match expressions to the type structure (if you add a variant it’s easy to find where to add an action) — fp makes testing very easy If 3 isn’t enough, give me an N and I’ll come up with more. 2b. Functional programming can be done in almost any language, though some make it a bit harder than others. So don’t make judgments across entire languages. (Josh Bloch: “Favor Immutability” (item 13) and “Minimize Mutability” (item 15) in “Effective Java.” He designed the API.) 3. Figuring out a good way of writing this Racket program goes as follows for experienced Racket/FP programmers: FP a la Racket encourages one more way of programming: — design systematically — then transform systematically So in Racket when you see (filter … (map …)) you know that (a) this allocates (b) can be transformed into a for/list comprehension that uses #:when (by practice) (c) (length (for/llist (.. #:when ..) ..)) can be transformed into (for/sum … #:when ) 1) Now in a perfect world, you’d point a performance debugger at this (called optimization coach or profler) and it may tell you that calling isprime? from the Math library imposes a high cost and that adding types to your code will eliminate this “borderline cost” (but not the cost of primality checking). — Matthias -- You received this message because you are subscribed to the Google Groups "Racket Users" group. To unsubscribe from this group and stop receiving emails from it, send an email to racket-users+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/racket-users/76869941-0765-47BC-894D-66488AACA7A8%40felleisen.org. For more options, visit https://groups.google.com/d/optout.