On Github mdjnewman / have-you-heard
by Matt Newman
There is a widening gap between ambitions and achievements in software engineering … the gap is arising at a time when the consequences of software failure in all its aspects are becoming increasingly serious
Production of large software has become a scare item for management. By reputation it is often an unprofitable morass, costly and unending.
The good systems that are presently working were written by small groups. More than twenty programmers working on a project is usually disastrous.
λ?
A class function should have only one reason to change.
Small, focused functions are good too!
Software entities should be open for extension, but closed for modification.
Composition and higher-order functions to the rescue!
( f ∘ g )( x ) = f ( g( x ) )
Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program.
Don't surprise people!
Also, parametric polymorphism largely avoids these issues.
Clients should not be forced to depend upon interfaces that they do not use.
Specifying small data types is still good practice.
Depend upon abstractions. Do not depend upon concretions.
FP (especially Haskell) is all about abstractions!
(and IOC containers are just the poor cousin of partial functions)
$ let identity = \x -> x $ identity "Hallo!" "Hallo!" $ (identity . identity) "Hallo!" "Hallo!"
$ :t identity identity :: t -> t
main :: IO () main = do putStrLn "Hello, what is your name?" name <- getLine putStrLn ("Hello, " ++ name ++ "!")
upperCaseStrings = strings.stream() .map(String::toUpperCase) .collect(toList());
nonEmptyStrings = strings.stream() .filter(x -> !x.isEmpty()) .collect(toList());
sum = numbers.stream().reduce(0, Integer::sum);
or
sum = numbers.parallelStream().reduce(0, Integer::sum);
Free parallelism too!