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/001734DF-7107-48DB-8CF4-56B429AB93D6%40ccs.neu.edu.
For more options, visit https://groups.google.com/d/optout.

Reply via email to