Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon. Entire thread

Simple made easy

Name: Anonymous 2011-10-21 10:06

http://www.infoq.com/presentations/Simple-Made-Easy

Rich Hickey's presentation which received a standing ovation from Dr. Sussman.

Name: Anonymous 2011-10-21 23:59

Escape analysis gets rid of it.
Does that mean it'll be converted into an in-place modification?
That's not what my code does; you are doing an in-place modification of the original list, and you forgot to add the one
Yes, my point was to demonstrate the in-place modification. The +1 is not in your first code fragment either.

Name: Anonymous 2011-10-22 0:28

Well, putting aside the debate over the value of FP, there were a few sparks of real genius in Hickey's lecture.  The "simple vs complex" point is brilliant.  The "knitted castle vs Lego castle" is also brilliant.

If he has one valuable theme, it's the goal of reducing complexity and even seeing complexity as a poison that spreads all through your program as soon as you stop guarding against it.  But he's silly to assume that "state" is the source of unwanted complexity.

As >>39 points out, state is just a fact of life.  There's nothing inherently complex about an integer or a function that increments an integer in place.

Name: Anonymous 2011-10-22 0:44

Sometimes performance just doesn't matter, compared to the idea behind a piece of code. The in-place C for loop example makes functional programming versions look bad when looked at strictly to performance, but the C for loop has traded meaning for concrete but naive performance.

In fact, the C for loop has so little "meaning" that compilers won't optimize them, without some explicit pragma to do so, out of fear of fucking them up just on aliasing alone. And then it generates basically the steps: is i < l? get at location i * sizeof(a) + a, multiply by 5, store at location i * sizeof(a) + a, increment i, repeat, etc. just run at a brute force execution speed expected of a program written in C.

On the other hand, a form with non-ambiguous meaning can be slow, but it does have meaning and a potential to have better instructions generated.

It's a waste of memory and time.

For sorting, I'd figure if the waste of memory was significant, it would not be a significant waste of time, and vice versa.

It's interesting that computations can be modeled without state and the lambda calculus etc., but it's all just mental masturbation.

Functional does not model without state though, functional simply doesn't hide state. Functional languages force state to be explicitly brought to the attention to the programmer, and forces him to take care of the stateful behavior all the way through the function. The real complexity of any location of code can be eyeballed right away by the number of arguments within all function scopes of that location. What is actually different about functional is non-destructive updates and immutability, this forces a different approach to computation with the benefit of added guarantees in larger concurrent systems. The lack of destructive updates requires one to become creative, this discourages concern of manipulation/curating of data and encourages relationship modeling of data. It is the forced writing of non-retarded code.

Imperative languages hide the real deal about state, and therefore hide real complexity, by not requiring any of this. On the other hand, sometimes the real complexity between objects is understood to be just too big (I'd say things like games would fall under this) and one ends up using something else and put up with the post facto extra debugging that may entail from it.

Given that, it is just one paradigm, it's not particularly great for some domains compared to other domains. I think it works best when the target design has a "tree shape".

Real computers

... use GOTO extensively.

Name: Anonymous 2011-10-22 0:56

>>43
Sometimes performance just doesn't matter, compared to the idea behind a piece of code.
I just don't think that's true... ever.  If you didn't care about "performing" your algorithm quickly, you'd just do it on paper and you wouldn't bother using a computer.  The only reason computers exist is to do what we want them to do faster than we could do it by hand.  I could make a FPS game where I draw each frame on paper and show it to you, then ask "now which button do you press?"

Name: Anonymous 2011-10-22 1:02

>>39

I have seen many beginning programmers write code that makes lots more copies of data than necessary (especially objects, which have more overhead due to constructors etc.), so immutability may be "easier" to think about in some ways, but once you learn how a computer really works (and that should have been the first thing you learned), it's trivial to see how much more efficient it is to not make new copies unless they're actually needed.

Immutability can sometimes save on copying. It is true that every time you want to directly modify an object, you must create a transformed version of the object, and then use the new transformed version in place of that object. If objects are defined recursively in terms of other objects however, immutability will allow you to have objects share data, and you will never need to worry about one of the objects modifying the data for its own purposes, causing strange effects on the other objects sharing the data. If you are going to make a copy of an object (get a reference to a version of an object that will not suddenly change state on you), then that operation is much more efficient in an immutable setting. All you have to do is acquire an extra reference or pointer to the object. If mutability is allowed, then you must make a deep copy of the object, and return a reference to this deep copy. The only way to know that no one else will modify an object is to create a new one, and not tell anyone else about it.

Name: Anonymous 2011-10-22 1:12

>>44

performance mattering is subjective, and it depends on the application of the program. If rendering code for a video game takes a while and yields 1 frame per second game play, then that will ruin the experience for the player, making the game useless and inaccessible. If a script that is run twice a day to make back ups of some logs takes a couple minutes longer than it could have if it was written in C, then most likely, nothing bad will happen, and the choice of using the scripting language over C would pay off in terms of development time.

But back the functional and immutability stuff, some algorithms need to have mutability in order to keep their asymptotic bounds on their running times. There are efficient data structures that are completely immutable, but stuff like hash tables with arbitrary sequences of insertions and deletions need to have mutability.

Name: Anonymous 2011-10-22 1:21

>>46
If a script that is run twice a day to make back ups of some logs takes a couple minutes longer than it could have if it was written in C, then most likely, nothing bad will happen
A) In your example, performance still matters, because you do need the script to run faster than 12 hours in order for it to run twice per day.
B) It would be beneficial for that script to run faster because you'd reduce CPU load on that system.
C) It's pretty pathetic to imply that some programming paradigm is valid because, hey, sure it's horrible, but there are some rare cases where it's OK to be horrible and you probably won't notice the difference in these rare cases.

Name: Anonymous 2011-10-22 1:39

>>47

Performance always matters in the sense that there is a notion of what is acceptable. However, not optimal but adequate is often acceptable.

CPUs are pretty fast. It might be cheaper to just buy a faster computer.

It pretty much comes down to the cost of development time. If a programmer could write a quick script for something in 15 minutes, where writing a program in a high performance language would take a day or two, then the script is much cheaper. If there are no practical gains of using the more expensive program, then any rational person would choose the cheaper program. Some applications just don't require the speed to justify putting that amount of time and money into development. You could use the same argument to explain why people use C and not assembly for everything.

Name: Anonymous 2011-10-22 2:08

Just wanted to say, it's slow on computers designed to run C.
http://www.cs.york.ac.uk/fp/reduceron/
Computers are just tools, they should accomodate our needs.

Please, continue.

Name: Anonymous 2011-10-22 2:10

>>47
C) It's pretty pathetic to imply that some programming paradigm is valid because, hey, sure it's horrible, but there are some rare cases where it's OK to be horrible and you probably won't notice the difference in these rare cases.
Implying that the cases are rare, writing multi-threaded code in most mainstream languages is shit, and in this century a significant amount of code is server-side.

It is up to the programmer to produce the metric of what constitutes comparably horrible. A metric should consider trade-offs between different variables to satisfy the customer. Since you may feel file backup scripts could preferably be written in macro assembler with optimal placement of mnemonics to get the job done, it is probably not worth persuading you to the virtues of HASKAL.

Name: Anonymous 2011-10-22 2:28

>>49
Conspiracy by Intel to made CPU which run C fast, and intentionally cripple languages to make them compile to C or lose the performance edge held by C.

Name: Anonymous 2011-10-22 2:41

>>51

architectures run their assembly instruction set as fast as they operate. Any language that is translated to assembly instructions has an equal opportunity to run fast, although different languages have different assumptions about what's going on in the code, which makes it easier or harder to get good optimization. C is pretty simple and close to assembly, so it is good for that.

Name: Anonymous 2011-10-22 3:24

>>52
close to assembly
Not always. Some of these assembly instructions are more complex than anything in the C standard library.
http://publib.boulder.ibm.com/infocenter/iseries/v7r1m0/index.jsp?topic=/rzatk/mitoc.htm

Name: Anonymous 2011-10-22 4:31

There seems to be a lot of misconception in this thread about state, why it's complex how it can be fixed. Some quotes:

He seems to think it's something called "managed refs" and that sounds like some kind of dog shit you'd find in .NET to me.
As >>39 points out, state is just a fact of life.  There's nothing inherently complex about an integer or a function that increments an integer in place.
There is actually another presentation from Rich that explains all this points: http://www.infoq.com/presentations/Are-We-There-Yet-Rich-Hickey

I recommend you to watch it before discussing any further here, because at this point the thread has degraded completely into empty talks about assembly, CPUs and other irrelevant bullshit.

Also, I think this talk is even more informative and insightful than the one from this thread and I'll create a separate thread for it so more people would have a chance to see it.

Name: Anonymous 2011-10-22 4:44

Incrementing an Int? Heresy.
 You create a new Object.IntFactory and pass OldInt value to Incrementator method which determines the proper return value and checks for overflows, thread-safely creates a new Int with value equal to OldInt + IncrementatorAddValue(default is 1, but you can override the method by calling IncrementatorByValue or SetDefaultIncrement(thread-local)).

Name: Anonymous 2011-10-22 4:48

>>39

purity is relative, obviously you are going have side effects but the idea is to isolate them and keep them separate from the actual program logic.

and the reason that old copies exist is so that other processes can access it. if you look at guy steele's talk, he mentions that parralell programs have to use more memory to decouple time from value. it's a necessary tradeoff for building large systems.

i dont think you ever read sicp or studied any functional language

Name: Anonymous 2011-10-22 5:02

SICP is obsolete. Clojure is dinosaur language paleontology. Java was a sick dog that Oracle put to sleep. The future is FIOC: Forever Indenting Our Code.

Name: VIPPER 2011-10-22 5:04

>>57
Then maybe you should go to /g/ or /pr/ or some other place that isnt about obsolete stuff.

Name: Anonymous 2011-10-22 5:10

Every intertwining add burden to our brain
Every bug was written by someone, compiled cleanly, and passed all the tests.
Focusing on ease, you will get complexity that kills you
If you go for simple, you start slow, and eventually go faster
OO is easy, but yields complexity
Incidental complexity—incidental is Latin for "your fault"
We can learn more things, but can't get smarter
Simple doesn't mean less parts. Sometimes we need to have more parts to make every part simple
State/Object is complex; Values are simple
Methods are complex; functions/namespaces are simple
Variables are complex; managed refs are simpler
Inheritance/switches are complex; polymorphism à la carte is simple
Syntax is complex; data is simple
Loops are complex; set functions are simple
Actors are complex; queues are simple
ORM is complex; declarative data manipulation is simple
I did years and years of stateful programming, and it sucked
Nothing makes state simple
If you take two things from this talk: the first is simple vs. easy; the second is that you do not need the complex tools
Use only
values
functions
namespaces
data
polymorphism à la carte
set functions
queues
learn SQL
rules
We create complex data structures around data rather than dealing with data directly. Use a map rather than defining a type
You have to analyse the problem and make a decision on the result
Abstraction should separate What, Who, How, When/Where, and Why
Information is simple. The only thing you can do is ruin it
Leave data alone
It's your fault if you don't have a simple system
Guardrails don't yield simplicity
Develop your sensibility around disentanglement
All reliability tools (tests, etc.) doesn't matter

Name: Anonymous 2011-10-22 5:10

Every intertwining add burden to our brain
Every bug was written by someone, compiled cleanly, and passed all the tests.
Focusing on ease, you will get complexity that kills you
If you go for simple, you start slow, and eventually go faster
OO is easy, but yields complexity
Incidental complexity—incidental is Latin for "your fault"
We can learn more things, but can't get smarter
Simple doesn't mean less parts. Sometimes we need to have more parts to make every part simple
State/Object is complex; Values are simple
Methods are complex; functions/namespaces are simple
Variables are complex; managed refs are simpler
Inheritance/switches are complex; polymorphism à la carte is simple
Syntax is complex; data is simple
Loops are complex; set functions are simple
Actors are complex; queues are simple
ORM is complex; declarative data manipulation is simple
I did years and years of stateful programming, and it sucked
Nothing makes state simple
If you take two things from this talk: the first is simple vs. easy; the second is that you do not need the complex tools
Use only
values
functions
namespaces
data
polymorphism à la carte
set functions
queues
learn SQL
rules
We create complex data structures around data rather than dealing with data directly. Use a map rather than defining a type
You have to analyse the problem and make a decision on the result
Abstraction should separate What, Who, How, When/Where, and Why
Information is simple. The only thing you can do is ruin it
Leave data alone
It's your fault if you don't have a simple system
Guardrails don't yield simplicity
Develop your sensibility around disentanglement
All reliability tools (tests, etc.) doesn't matter

Name: Anonymous 2011-10-22 5:24

Syntax is complex; data is simple
fuck off lithpfag

Name: Anonymous 2011-10-22 7:02

Inheritance/switches are complex; polymorphism à la carte is simple
switch(x) is more complex than a whole class of zygohistomorphic prepromorphisms? Cool. I could certainly feel its more capable.

Name: Anonymous 2011-10-22 7:03

If a script that is run twice a day to make back ups of some logs takes a couple minutes longer than it could have if it was written in C, then most likely, nothing bad will happen, and the choice of using the scripting language over C would pay off in terms of development time.
Except if that script will be run twice a day, every day, for an undetermined number of years. An extra minute a day is 6 hours every year. If that script took several more minutes to develop in C, you've still gained that time back after a while.

"Programmer time is expensive" only makes sense in the context of writing code that will be used a very limited number of times by a very limited number of users. Otherwise the initial time investment will be recovered very quickly.

I can write a script in an HLL in 2 minutes to perform a task in 10 minutes, or I could take 10 minutes to write it in C, so it will perform the same task in 5 minutes. If I'm only going to run it once, the HLL makes sense - 12 minutes total vs 15 minutes for C. If I'm going to run it twice, it changes -- 10*2 + 2 = 22 minutes, vs 5*2 + 10 = 20 minutes. And the more times you need to do that task, the more time you'll save with your initial investment.

CPUs are pretty fast. It might be cheaper to just buy a faster computer.
Speed is NOT infinite. Do not assume hardware will keep getting faster, because its improvement is already slowing down.

It pretty much comes down to the cost of development time. If a programmer could write a quick script for something in 15 minutes, where writing a program in a high performance language would take a day or two, then the script is much cheaper.
No. It depends on how many times the script will be used, and by how many users.

Name: Anonymous 2011-10-22 7:56

>>62
Watch the video to understand in what meaning the word "complex" is used here.

Name: Anonymous 2011-10-22 7:58

>>63
But is the machine loaded to the point that those extra minutes matter?

Name: Anonymous 2011-10-22 8:17

>>59
I'm interjecting again for a moment, but
OO is easy, but yields complexity
OO really means nothing, even Haskell can be OO by some definitions of OO. I'm assuming Java-style class-based OO.
State/Object is complex; Values are simple
State is not complex, unmanaged state is. Clojure has state.
Variables are complex; managed refs are simpler
No, conflating the concept of mutability and variables is complex. Variables should be immutable, and a dedicated datatype/thing should be used for mutability. Clojure does get it right, and also do ML (refs), Racket (boxes, although it hasn't immutable variables).
Inheritance/switches are complex; polymorphism à la carte is simple
No, conflating subclassing, subtyping and polymorphism is complex.
Syntax is complex; data is simple
Complex syntax is complex.
Loops are complex; set functions are simple
Loops are not complex, not having a way to abstract them away is.
Actors are complex; queues are simple
You just said functions are simple, actors can't be complex. The Sussman noted they are equivalent.
Nothing makes state simple
Again, state is ok if controlled.

Name: Anonymous 2011-10-22 9:53

>>63

You do realize that run-time does matter as much, because it (in the backup script example) involves only machine-time, not human-time?

putting electricity and server upkeep aside, development time is much more relevant than the time it takes the machine to run your code

Name: Anonymous 2011-10-22 14:05

>>39
the advantage is not having to think about whether you need it later. It's incredibly freeing for your brain. The whole point of non-assembly programming is to let you ignore details.

Maybe a metaphor gets it across: imperative programming says
I have this shiny new 2. It is good and serves my purposes. I WUV U 2!! ... FUCK YOU 1 I NEVER LIKED YOU GO FUCKING DIE AND- wait you don't have any fiends or family right? Probably not. *shoots 1 in the face* *plops 2 down on his corpse.*

FP says
I have this shiny new 2. It is good and serves my purposes. I WUV U 2!! who the fuck is 1?

Name: Anonymous 2011-10-22 14:42

How would you do this efficiently in a purely functional way? It's for simplifying a multiplication.
; Not tested, but I hope you get the idea.
(let ((vars nil)
      (consts nil))
  (dolist (x terms `(* ,@vars ,(apply #'* consts)))
; AIF is the anaphoric if macro.
; CONST tries to coerce its parameter into a constant number and returns NIL if it can't.
    (aif (const x)
      (if (zerop it)
        (return 0)
        (push it consts))
      (push x vars))))

Name: Anonymous 2011-10-22 15:01

>>69
It's a simple accumulator loop.
(define (simplify terms)
 (let loop ((terms terms) (vars '()) (consts '()))
  (cond ((null? terms) `(* ,@vars ,(apply * consts)))
         (const (car terms))
          => (lambda (x)
              (if (zero? x) 0
                  (loop (cdr terms) vars
                        (cons x consts)))))
         (else (loop (cdr terms) (cons x vars) consts)))))

Name: Anonymous 2011-10-22 15:06

>>70
Oh, I see. Thanks for your insight.
I feel bad for having forgotten the equivalence between accumulation parameters and mutable places.

Name: Anonymous 2011-10-22 17:03

In all this discussion, I still haven't really seen a reasonable argument against state.  Hickey just says it's complex because "it complects time and value."  Pretty vague.

If I have an egg, and then I fry it, I have a fried egg.  Physics doesn't allow me to pass a copy of the egg to the frying pan and keep the original egg in the carton for later.  Passing everything by value/copy is a more complex concept because it's not intuitive in our universe.

Name: Anonymous 2011-10-22 17:08

>>72
Physics doesn't allow me to pass a copy of the egg to the frying pan and keep the original egg in the carton for later.
You don't have to ask em.

Name: Anonymous 2011-10-22 17:14

>>72
Because state isn't bad if you control it, make it explicit, or both.

Name: Anonymous 2011-10-22 20:25

>>72
State in itself isn't bad. However, many bugs are introduced because programmer's expectations are not consistent when state changes and all sorts of state related assumptions are made. State related bugs don't happen in functional algorithms because the logic is consistent.

it's not intuitive in our universe
Please try not to use intuitive in the context of programming as this word is meaningless in this context.

Name: Anonymous 2011-10-22 22:27

>>72

Your roommates expect the egg to not be fried though.

Name: Anonymous 2011-10-22 22:40

>>72
I add 2 and 2, no more 2. 4 only.

Name: Anonymous 2011-10-22 22:41

imperative:

x = 2
x += 2
return x


functional:

2 + 2

Name: Anonymous 2011-10-23 0:53

State related bugs don't happen in functional algorithms because the logic is consistent.

Infinite loops don't happen in non-Turing-complete languages because there is no provision for looping indefinitely.

Name: Anonymous 2011-10-23 1:14

Imperative programming is easy for people to grasp intuitively, functional programming isn't.

Newer Posts
Don't change these.
Name: Email:
Entire Thread Thread List