The Artima Developer Community
Sponsored Link

Articles Forum
Time is the New Memory

46 replies on 4 pages. Most recent reply: Oct 2, 2009 3:25 PM by Raoul Duke

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 46 replies on 4 pages [ 1 2 3 4 | » ]
Bill Venners

Posts: 2284
Nickname: bv
Registered: Jan, 2002

Time is the New Memory Posted: Sep 21, 2009 10:00 AM
Reply to this message Reply
Advertisement
In this Artima interview from the JVM Languages Summit, Rich Hickey, the creator of the Clojure programming language, discusses his perspective on mutable state and what programming languages should do about it.

Read this Artima.com interview:

http://www.artima.com/articles/hickey_on_time.html

What is your opinion of Hickey's notion that the problems people usually associate with mutable state are problems of time? What do you think of the idea that you should write as much of your program as possible with immutable objects (or data) and pure functions?


Carson Gross

Posts: 153
Nickname: cgross
Registered: Oct, 2006

Re: Time is the New Memory Posted: Sep 21, 2009 10:36 PM
Reply to this message Reply
And yet, despite it all, the vast majority of useful software is built using the old imperative/mutable warhorses.

Plato may be rolling over in his grave (and good, the totalitarian bugger) but Aristotle is laughing.

Cheers,
Carson

Fred Finkelstein

Posts: 48
Nickname: marsilya
Registered: Jun, 2008

Re: Time is the New Memory Posted: Sep 22, 2009 12:38 AM
Reply to this message Reply
> If there was a way to glance at a date, at one point in time, there would be no problem

Of course there is and it is as simple as that: Make a monitor for date. In java it is the key synchronization concept.

Krisztian Sinka

Posts: 30
Nickname: skrisz
Registered: Mar, 2009

Re: Time is the New Memory Posted: Sep 22, 2009 1:17 AM
Reply to this message Reply
> Of course there is and it is as simple as that: Make a
> monitor for date. In java it is the key synchronization
> concept.

Yes but the question still remains: "How do you know you got it right?" ;-)

Peace
K

Fred Finkelstein

Posts: 48
Nickname: marsilya
Registered: Jun, 2008

Re: Time is the New Memory Posted: Sep 22, 2009 1:30 AM
Reply to this message Reply
> Yes but the question still remains: "How do you know you got it right?" ;-)

if you make every public method in class date synchronized + if you allow access to attribute only via methods, than I strongly assume that there cannot occur any concurrency problems.

Rob Lally

Posts: 7
Nickname: roblally
Registered: Dec, 2007

Re: Time is the New Memory Posted: Sep 22, 2009 3:53 AM
Reply to this message Reply
>if you make every public method in class date synchronized + if you allow access to attribute only via methods, than I strongly assume that there cannot occur any concurrency problems.

If you remove any potential for concurrency then you certainly cut down on potential concurrency problems.

The point is that the objective isn't to eliminate concurrency, it is to enable concurrency whilst maintaining consistency and correctness. Your suggestion of synchronising every method on date won't make this code safe:

if(date.getDay().equals(3)) date.setDay(4)

... because the synchronisation of the date object doesn't ensure that another thread can't change it between the get and the set method. This is one of the problems that Clojure is trying to solve.

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: Time is the New Memory Posted: Sep 22, 2009 3:53 AM
Reply to this message Reply
> In this Artima interview from the JVM Languages Summit,
> Rich Hickey, the creator of the Clojure programming
> language, discusses his perspective on mutable state and
> what programming languages should do about it.
>
> Read this Artima.com interview:
>
> http://www.artima.com/articles/hickey_on_time.html
>
> What is your opinion of Hickey's notion that the problems
> people usually associate with mutable state are problems
> of time? What do you think of the idea that you should
> write as much of your program as possible with immutable
> objects (or data) and pure functions?

I think the Pure Functional Programming people are leaving in a fantasy land. They speak about Pure FP as if it makes it impossible to introduce bugs, which, of course, it's not the case at all. They blame the concept of "state" for everything, which is absurd, to say the least. Their programs are full of monadic type declarations, since almost everything requires state, and when they are asked to produce a quicksort implementation that is as fast as in-place quicksort, or when they are asked to solve the problem of tree (parent points to child, child points to parent), they mumble something about some very strange patterns (they call it the zip pattern or something like that) that requires you to interleave your code (whatever that is: a calculation, event management in a gui app, packet reception from the network) with the tree manipulation structure, resulting in a big spaghetti mess.

The advantages of functional programming include the strong and static type system and the functions as first class entities. Pureness is a straitjacket and a severe disadvantage.

Here is an example of the madness (quote taken from the article):

A large system that's a graph of mutable objects is just very hard to understand.

And in Pure FP, a large computation that's a graph of function calls is also very hard to understand. The wrong values appear at function parameters instead of object members. There is no difference in reality between objects that are inconsistent internally and functions with wrong parameters. In Pure FP, the problem of wrong values is transferred from objects to functions.

The real issue behind programming is not time or pureness or immutability.

First of all, there is no such thing as an impure function, unless the function reads some value from the hardware. Each and every procedure/function/subroutine/calculation in a program will give the exact same result, if given the exact same parameters. And by parameters, I mean not only the values passed to it, but implicit parameters like global variables. External variables to a function are input variables to the function as well. Given a function F and and input I, where I is P (parameters passed to the function) and G (variables accessible in the context of F), the output is always O:

I = {P, G}
F(I) = O

The real issue in programming is partial functions. Most, if not all, programming functions, allow for partial functions, i.e. for functions where not all the possible values of the input are mapped to a result.

For example (to take an example from the article), A Date object is inconsistent because of violation of the mathematical function that defines the date. When we have month = February and then we set the day = 31, we have violated the definition of Date. There is no date February, 31. It's not a problem of time, it's a problem of partiality: at that specific point of computation, we have violated the definition of Date.

The problem of partial functions extends to everything. For example, the function 'fclose' is defined as a function that takes as input an open file, not a closed one. But there is no check from the compiler if we pass a closed file or not.

Another example is functions that do not accept null pointers. The input set of such a function does not include the null value, but the compiler does not complain. FP languages somewhat address the problem by using Maybe types, but the solution does not cover the whole range of problems. For example, it's not possible to say that the input pointer for a function can take values within the range X..Y.

One solution to the problem of partial functions is to make values as types. A range type from X to Y, for example, can only statically accept a value that is within the range; at run time, if we have a value that may be out of range, we statically promote the value to the X..Y if the value is inside the range, and we declare an alternative action when the value is outside of the range. For example (in C++ parlance):


int main() {
int i;

//input of arbitrary value
cin >> i;

//new construct: match i within a range;
match (i => range<10, 20>) {
//from now on, the type of i is 'range<10, 20>', not 'int'.

//we can access an array's members without bounds checking.
array<int, 10, 20> data;

data[i] = 5;
}
otherwise {
//value out of range.
}

}


Incidentally, using values as types allows for a lot of optimizations; for example, in the above, bounds checking is redundant.

I apologize for the long reply, but some things need to be said, in my opinion. It ticks me off when I see people can't recognize the real nature of the problem in programming :-).

Chas Emerick

Posts: 9
Nickname: cemerick
Registered: Jun, 2004

Re: Time is the New Memory Posted: Sep 22, 2009 4:47 AM
Reply to this message Reply
> I apologize for the long reply, but some things need to be
> said, in my opinion. It ticks me off when I see people
> can't recognize the real nature of the problem in
> programming :-).

I'm not sure using examples in C++ to illustrate one's argument is particularly persuasive. ;-)

Besides that, there's a lot of unsubstantiated assertions there, and a lot of misunderstanding of how things work in many FP languages.

Some thoughts in no particular order:

- I don't think anyone has any problem with 'state'. Rather, the issue is with statefulness with undefined or poorly-defined semantics. Monads and STM and CAS and, and, and, are all ways of defining the semantics of how state changes.

- Some flavor(s) of Haskell emit C, and are as fast as C for many tasks. Users of other languages are happy to trade some performance for better semantics and development processes. Different strokes, and all.

- For tree manipulations, including maintaining references to parents from child nodes in languages with persistent data structures, see Huet's zippers and their descendants (pun intended! :-P)

- Not all FP languages have strong+static type systems (e.g. clojure doesn't)

- "A graph of mutable objects is hard to understand" because of the undefined or poorly-defined semantics of those objects' state. Programs consisting of functions and values are likely just as complicated (in some formal sense of numbers of relationships between entities, etc), but more understandable because of the well-defined semantics.

Finally, I'm baffled that you appear to be a proponent of very aggressive strong+static typing, given your discussion of "values as types", but are simultaneously unimpressed with FP languages that take those ideas the furthest (Haskell and the ML family, to my understanding).

Cheers,

- Chas

Fred Finkelstein

Posts: 48
Nickname: marsilya
Registered: Jun, 2008

Re: Time is the New Memory Posted: Sep 22, 2009 5:35 AM
Reply to this message Reply
> won't make this code safe:
> if(date.getDay().equals(3)) date.setDay(4)
> ... because the synchronisation of the date object
> doesn't ensure that another thread can't change it
> between the get and the set method. This is one of
> the problems that Clojure is trying to solve.

It is obvious how to prevent this problem. Just expose following methods:
synchronized void setNewDate(Date d);
synchronized void setNewDate(int year, int month, int day);

That's it. No magic needed.

Rob Lally

Posts: 7
Nickname: roblally
Registered: Dec, 2007

Re: Time is the New Memory Posted: Sep 22, 2009 6:13 AM
Reply to this message Reply
> It is obvious how to prevent this problem. Just expose following methods:
> synchronized void setNewDate(Date d);
> synchronized void setNewDate(int year, int month, int day);

> That's it. No magic needed.


That doesn't solve anything, since you need to expose a getDate method and, although you can synchronise this method too it doesn't provide the atomic check and set behaviour that's needed in this case.

You are right though, no magic is needed. Relational databases solved this problem decades ago by using transactions. Which is exactly what Clojure does...

Rich Hickey

Posts: 1
Nickname: richhickey
Registered: Dec, 2007

Re: Time is the New Memory Posted: Sep 22, 2009 6:22 AM
Reply to this message Reply
> > won't make this code safe:
> > if(date.getDay().equals(3)) date.setDay(4)
> > ... because the synchronisation of the date object
> > doesn't ensure that another thread can't change it
> > between the get and the set method. This is one of
> > the problems that Clojure is trying to solve.
>
> It is obvious how to prevent this problem. Just expose
> following methods:
> synchronized void setNewDate(Date d);
> synchronized void setNewDate(int year, int month,
> int day);

>
> That's it. No magic needed.

Imagine a class with mutable members A, B, C, and D. Would you have:

synchronized void setA(Object a);
synchronized void setB(Object b);
synchronized void setC(Object c);
synchronized void setD(Object d);
synchronized void setAB(Object a, Object b);
synchronized void setAC(Object a, Object c);
synchronized void setAD(Object a, Object d);
synchronized void setBC(Object b, Object c);
...

?

Providing a synchronized method for every composite operation simply doesn't scale. And

adate.setNewDate(anotherDate);

makes as much sense as:

42.setNewValue(43);

were that possible.

No one is advocating any 'magic'. Just programming with values, and functions that create new values. By comparison it is mutable objects that are magical.

Rich

Achilleas Margaritis

Posts: 674
Nickname: achilleas
Registered: Feb, 2005

Re: Time is the New Memory Posted: Sep 22, 2009 7:10 AM
Reply to this message Reply
> I'm not sure using examples in C++ to illustrate one's
> argument is particularly persuasive. ;-)

The number of people that will understand a C++ example is greater than the number of people that will understand Haskell, for example. It's also easier for me as well.

>
> Besides that, there's a lot of unsubstantiated assertions
> there, and a lot of misunderstanding of how things work in
> many FP languages.
>
> Some thoughts in no particular order:
>
> - I don't think anyone has any problem with 'state'.
> Rather, the issue is with statefulness with undefined or
> poorly-defined semantics. Monads and STM and CAS and,
> and, and, are all ways of defining the semantics of how
> state changes.

I suppose you do not read LtU frequently then :-).

>
> - Some flavor(s) of Haskell emit C, and are as fast as C
> for many tasks.

Undoubtedly. But my point is that C (and its derivatives) can not be abandoned, because there are things that pure FP languages can not do (like in-place quicksort).

> Users of other languages are happy to
> trade some performance for better semantics and
> development processes. Different strokes, and all.

And that leads to unresponsive, slow and bloated applications.

>
> - For tree manipulations, including maintaining references
> to parents from child nodes in languages with persistent
> data structures, see Huet's zippers and their descendants
> (pun intended! :-P)

Yes, that's what I was talking about, the zipper structure. Thanks but no thanks, I'd like my code simple.

>
> - Not all FP languages have strong+static type systems
> (e.g. clojure doesn't)

I never said that all do, but the main focus these days is on Haskell.

>
> - "A graph of mutable objects is hard to understand"
> because of the undefined or poorly-defined semantics of
> those objects' state. Programs consisting of functions
> and values are likely just as complicated (in some formal
> sense of numbers of relationships between entities, etc),
> but more understandable because of the well-defined
> semantics.

The same well defined semantics can be used on objects.

>
> Finally, I'm baffled that you appear to be a proponent of
> very aggressive strong+static typing, given your
> discussion of "values as types", but are simultaneously
> unimpressed with FP languages that take those ideas the
> furthest (Haskell and the ML family, to my
> understanding).

That's because strong+static typing is good, lack of updates is not.

In my opinion, that is.

Chas Emerick

Posts: 9
Nickname: cemerick
Registered: Jun, 2004

Re: Time is the New Memory Posted: Sep 22, 2009 7:47 AM
Reply to this message Reply
> >
> > - Some flavor(s) of Haskell emit C, and are as fast as
> C
> > for many tasks.
>
> Undoubtedly. But my point is that C (and its derivatives)
> can not be abandoned, because there are things that pure
> FP languages can not do (like in-place quicksort).

We're definitely talking past each other because of our (likely very different) use cases and specialties.

No one said that they should be abandoned, but the same tactics that are relied upon in systems programming simply do not scale to solving different classes of problems. The fact that many environments are happy enough to get the performance benefits of lower-level languages when necessary (e.g. [almost] no one writes sort routines in clojure, you just "shell out" to Java, and wrap the result in an immutable wrapper in O(1)) while working with higher-level primitives the rest of the time.

I promise you that the bottlenecks of most programs have nothing to do with the speed of sorting routines.

> > Users of other languages are happy to
> > trade some performance for better semantics and
> > development processes. Different strokes, and all.
>
> And that leads to unresponsive, slow and bloated
> applications.

Per the above, in many fields, that leads to applications that *work*. If I had to contemplate building my current projects in C++, Java, et al., I simply would not have bothered -- the amount of manual bookkeeping would have drowned us for years.

> > - "A graph of mutable objects is hard to understand"
> > because of the undefined or poorly-defined semantics of
> > those objects' state. Programs consisting of functions
> > and values are likely just as complicated (in some
> formal
> > sense of numbers of relationships between entities,
> etc),
> > but more understandable because of the well-defined
> > semantics.
>
> The same well defined semantics can be used on objects.

But where? If there's an approach that provides similar sorts of guarantees around mutable objects, I'd be happy to educate myself.

- Chas

Vinícius Godoy de Mendonça

Posts: 1
Nickname: vinigodoy
Registered: Sep, 2009

Re: Time is the New Memory Posted: Sep 22, 2009 8:05 AM
Reply to this message Reply
> if you make every public method in class date synchronized
> + if you allow access to attribute only via methods, than
> I strongly assume that there cannot occur any concurrency
> problems.


But that's not true. You you'll end up with two mutually exclusive methods, but there's no guarantee of synchronization between two calls.

For example, if Date class has all it's methods synchronized it's still possible that a thread read the date in between of line 1 and 2:
1. date.setMonth(february);
2. date.setDay(10);

And that's a concurrency problem, even 1 and 2 being synchronized.

You should place the monitor in the class that manipulates the entire date object. And, every time this manipulation occur, it should be using this same monitor. And that's very hard to achieve, if you are sharing this object between lots of classes. For this situation, the better whould be making this classe immutable (as suggested) or creating a setTime() method, that forces the programmer to chance all or nothing. That solves the problem of threating the class in pieces, also described in the article.


Despite this fact, the "non concurrency" sample of the article is still a concurrency problem. Since there's resource sharing amoung different pieces of the code, it's still concurrency, no matter if the memory is a volatile or a phisical one.

Of course, the concurrency definition is intrisincally related to time.

Carson Gross

Posts: 153
Nickname: cgross
Registered: Oct, 2006

Re: Time is the New Memory Posted: Sep 22, 2009 11:19 AM
Reply to this message Reply
Until I see an incremental proposal that doesn't force everyone to change their day-to-day coding style, I'm not convinced. It needs to be something even simpler than synchronized, for example.

Garbage collection succeeded because memory management was hard and, when GC came along, we got to keep programming in the same old way that made sense to us. It was almost wholly subtractive: we just had to do less stuff. Lazy, stupid developers got more productive, since they weren't managing memory well anyway.

Academics and language guys are usually shooting for some platonic ideal and, in the mean time, practical, unsexy tools (web servers splitting requests across cores, java.util.concurrent.* when you have a specific use case) will continue to be where progress is made. Just look at the historical evidence.

And 20 years from now, someone advocating functional programming will be giving a talk that starts "Are We There Yet?"

Cheers,
Carson

Flat View: This topic has 46 replies on 4 pages [ 1  2  3  4 | » ]
Topic: From JavaOne 2009: On Trust and Types Previous Topic   Next Topic Topic: Scala's Selfless Trait Pattern

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use