|
Dear all,
there is a question I have been thinking about a bit. In short, we could simply formulate it like this: Are there any problems which cannot be solved a side effect-free language (such as Haskell)? In other words, are there problems that would explicitly demand semantics that can only be provided by a language allowing direct modification of external state variables, such as Java and C++?
If not, are there problems which are simply infeasible to solve with a side effect-free language? I realize this question is very broad, and I am not expecting an exact answer by any means. I am asking since I am curious about the relation between functional and imperative/procedural languages in general. I primarily come from a Java background, but I can program Haskell and Erlang, and have recently started exploring Scala, so this would be interesting to know.
Best, Christopher Svanefalk Student, Department of Computer Science and Engineering University of Gothenburg / Chalmers University of Technology
_______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Christopher,
On 16/03/2012, at 11:23 PM, Christopher Svanefalk wrote: > there is a question I have been thinking about a bit. In short, we could simply formulate it like this: > > Are there any problems which cannot be solved a side effect-free language (such as Haskell)? In other words, are there problems that would explicitly demand semantics that can only be provided by a language allowing direct modification of external state variables, such as Java and C++? > > If not, are there problems which are simply infeasible to solve with a side effect-free language? Start here: http://www.cs.ox.ac.uk/people/geraint.jones/morehaste.html and dig through their references. I don't think "a logarithmic factor" is ever going to make the difference between feasible and infeasible. :-) cheers peter -- http://peteg.org/ _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Christopher Svanefalk
On Fri, Mar 16, 2012 at 9:23 AM, Christopher Svanefalk
<[hidden email]> wrote: > Are there any problems which cannot be solved a side effect-free language > (such as Haskell)? In other words, are there problems that would explicitly > demand semantics that can only be provided by a language allowing direct > modification of external state variables, such as Java and C++? Haskell, Java, C++ and most other languages out there are Turing-complete. That means that all of them are able to compute the same things. Assuming that the Church-Turing hypothesis is true, all algorithms may be coded in all of them. > If not, are there problems which are simply infeasible to solve with a side > effect-free language? If you're asking about performance, as in "is there a problem that can be solved in O(f(n)) time in Java but not in Haskell-sans-IO-and-ST?", then it becomes a harder question. I'm not sure what the answer is. Cheers, -- Felipe. _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Christopher Svanefalk
Hi there,
Christopher Svanefalk <[hidden email]> wrote: > there is a question I have been thinking about a bit. In short, we > could simply formulate it like this: > > Are there any problems which *cannot *be solved a side effect-free > language (such as Haskell)? In other words, are there problems that > would explicitly demand semantics that can only be provided by a > language allowing direct modification of external state variables, > such as Java and C++? > > If not, are there problems which are simply *infeasible *to solve with > a side effect-free language? > > I realize this question is very broad, and I am not expecting an exact > answer by any means. I am asking since I am curious about the relation > between functional and imperative/procedural languages in general. I > primarily come from a Java background, but I can program Haskell and > Erlang, and have recently started exploring Scala, so this would be > interesting to know. you are more interested in the fundamentals. There is a proof that lambda calculus (which is the smallest common denominator of all purely functional languages) is equivalent to the model of Turing machines. That basically means that any computer program can be written in both. Adding types changes the whole picture. In the typed lambda calculus not every program can be expressed. Particularly every program in this model must terminate. To get back the full expressivity you need to add an (opaque) general recursion operator, and most languages do that by allowing a definition to refer to any other, including itself. Many of them (F#, OCaml) have an explicit "let rec"-style construct, others (Haskell, Clean) allow recursion everywhere. Functional languages with a more powerful type system (like Agda) even refrain from adding general recursion. These are in fact not Turing-complete. Without general recursion you can use a language for proofs, whether you prove theorems or program behavior. Still you can express infinite recursion using coinduction. About feasibility: For both models there is a set of problems which are hard to express, and they are fairly disjoint. Usually a hard to express problem in one is easy to express in the other. To add more expressivity imperative languages add language constructs (loops, OO, exceptions, etc.), while functional languages add combinators and composition patterns (monads, higher order functions, etc.). I think if a problem is infeasible to express in one model, it will be infeasible in the other as well. Greets, Ertugrul -- nightmare = unsafePerformIO (getWrongWife >>= sex) http://ertes.de/ _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Christopher Svanefalk
Hi,
Christopher Svanefalk wrote: > Are there any problems which *cannot* be solved a side effect-free language > (such as Haskell)? No. Haskell is expressive enough. One way to prove that is to implement an interpreter for a language with side effects in Haskell. Now if there's a program P to solve a problem in the language-with-side-effects, we can run that interpreter on P to solve the same problem in Haskell. The interpreter could use a Data.Map to associate variable names with values. That would probably not be the fastest or the most memory efficient implementation of the language-with-side-effects, but it would work. The same trick of implementing one language in the other can be done for almost every pair of "reasonably expressive languages", so they are all equally expressive in a sense. It is even widely believed that no even more expressive language can exist. That means that if a problem can be solved by a computer at all, it can also be solved using any of these "reasonably expressive languages". That is the Church-Turing-Hypothesis. (And the other way around: if the hypothesis is true, and a problem can not be solved in one of these languages, that problem cannot be solved with a computer at all. Unfortunately, many interesting problems are like that). Tillmann _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Christopher Svanefalk
Many thanks for the replies and references all of you! I will continue to read up on this from here, and you have all boosted my interest in investigating how complex systems could be developed using functional languages.
On Fri, Mar 16, 2012 at 1:46 PM, Dimitri Scheftelowitsch <[hidden email]> wrote: Hi, Best, Christopher Svanefalk _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Felipe Almeida Lessa
On Fri, Mar 16, 2012 at 8:35 AM, Felipe Almeida Lessa <[hidden email]> wrote:
</lurk> an interesting question emerges: even though i may be able to implement an algorithm with O(f(n)) in Haskell, and write a program that is O(g(n)) < O(f(n)) in C++ or Java... could Haskell be said to be more efficient if time spent programming / maintaining Haskell is << C++ or Java?? i'm still trying to learn Haskell, but it seems to me to be *much* less verbose than C and it's derivatives, and while jumping through monads just to print to a screen or write a file seems a small expence to pay to be able to express what you want easier...
justin <lurk> * The wise man said: "Never argue with an idiot. They bring you down to their level and beat you with experience." * As a programmer, it is your job to put yourself out of business. What you do today can be automated tomorrow. ~Doug McIlroy No snowflake in an avalanche ever feels responsible. --- CFO: “What happens if we train people and they leave?” CTO: “What if we don’t and they stay?” _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
On Fri, Mar 16, 2012 at 3:43 PM, serialhex <[hidden email]> wrote:
> an interesting question emerges: even though i may be able to implement an > algorithm with O(f(n)) in Haskell, and write a program that is O(g(n)) < > O(f(n)) in C++ or Java... could Haskell be said to be more efficient if > time spent programming / maintaining Haskell is << C++ or Java?? There are two unrelated issues: (a) the efficiency of algorithms implementable in Haskell, and (b) the efficiency of programmers working in Haskell. It makes no sense to ask a question that conflates the two. If you're unsure which definition of "efficient" you meant to ask about, then first you should stop to define the words you're using, and then ask a well-defined question. That being said, this question is even more moot given that real Haskell, which involves the IO and ST monads, is certainly no different from any other language in its optimal asymptotics. Even if you discount IO and ST, lazy evaluation alone *may* recover optimal asymptotics in all cases... it's known that a pure *eager* language can add a log factor to the best case sometimes, but my understanding is that for all known examples where that happens, lazy evaluation (which can be seen as a controlled benign mutation) is enough to recover the optimal asymptotics. -- Chris Smith _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
If the question is "when can I have my output", then both are equally
relevant and can be safely conflated. That said, while some programming problems *are* of this type, I think most aren't, and your points certainly stand. On Fri, Mar 16, 2012 at 3:31 PM, Chris Smith <[hidden email]> wrote: > On Fri, Mar 16, 2012 at 3:43 PM, serialhex <[hidden email]> wrote: >> an interesting question emerges: even though i may be able to implement an >> algorithm with O(f(n)) in Haskell, and write a program that is O(g(n)) < >> O(f(n)) in C++ or Java... could Haskell be said to be more efficient if >> time spent programming / maintaining Haskell is << C++ or Java?? > > There are two unrelated issues: (a) the efficiency of algorithms > implementable in Haskell, and (b) the efficiency of programmers > working in Haskell. It makes no sense to ask a question that > conflates the two. If you're unsure which definition of "efficient" > you meant to ask about, then first you should stop to define the words > you're using, and then ask a well-defined question. > > That being said, this question is even more moot given that real > Haskell, which involves the IO and ST monads, is certainly no > different from any other language in its optimal asymptotics. Even if > you discount IO and ST, lazy evaluation alone *may* recover optimal > asymptotics in all cases... it's known that a pure *eager* language > can add a log factor to the best case sometimes, but my understanding > is that for all known examples where that happens, lazy evaluation > (which can be seen as a controlled benign mutation) is enough to > recover the optimal asymptotics. > > -- > Chris Smith > > _______________________________________________ > Haskell-Cafe mailing list > [hidden email] > http://www.haskell.org/mailman/listinfo/haskell-cafe _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Christopher Svanefalk
You can emulate mutation with at most O(log(n)) penalty using a map. Given that memory is of fixed size, log2(n) <= 64, so for "real-world" programs this becomes O(1). So any program you can implement using mutation can be implemented in a pure language with the same big-O running time (but much much worse constant factors, given this naive translation).
Other external state is harder to emulate. For example, communication over a network most definitely requires some concept of a 'computation with side effects' since the network's response could change from request to request. In GHC, even IO objects are pure, but they conceptually represent functions that modify the state of reality. -- ryan On Fri, Mar 16, 2012 at 5:23 AM, Christopher Svanefalk <[hidden email]> wrote: Dear all, _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Ryan Ingram:
> Other external state is harder to emulate. For example, communication > over a network most definitely requires some concept of a 'computation > with side effects' since the network's response could change from > request to request. > > In GHC, even IO objects are pure, but they conceptually represent > functions that modify the state of reality. I believe I begin to become a sectarian, with some idées fixes not so well shared... It is the third or the fourth time that somebody recently puts the equivalence between the communication with the outer world, and "side effects". I contest that very strongly, perhaps a TRUE guru might instruct me. What a computer and the program it runs do to its hard environment has NOTHING to do with side-effects. Even a completely angelic, pure as a Cherub (but real) program will consume some electricity. And so what?! Of course, in classical physics the state of the world changes constantly (in a quantum world it is extremely ambiguous...), but the question of purity of a program - in my opinion - concerns the program, and nothing else. The networking is not expected to break the referential transparency, or does it? Jerzy Karczmarczuk _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
On Fri, Mar 16, 2012 at 7:44 PM, Jerzy Karczmarczuk
<[hidden email]> wrote: >... but the question of purity of a program - in my opinion - concerns the program, and nothing else. You might be thinking of software engineering purity. >The networking is not expected to break the referential transparency, or does it? > > > Jerzy Karczmarczuk > What does referential transparency mean to you? -- -- Regards, KC _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
Quoth KC <[hidden email]>,
> On Fri, Mar 16, 2012 at 7:44 PM, Jerzy Karczmarczuk > <[hidden email]> wrote: > >> ... but the question of purity of a program - in my opinion - concerns >> the program, and nothing else. > > You might be thinking of software engineering purity. Or software engineers might be thinking of purity in the same way. I personally hope I think of purity in a way that's of some practical use in terms of Haskell programs, and I would hope software engineers in general would do likewise. From that perspective, it seems to me that M. Karczmarczuk is on pretty solid ground. Donn _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Jerzy Karczmarczuk
It is the third or the fourth time that somebody recently puts the equivalence between the communication with the outer world, and "side effects". I contest that very strongly, perhaps a TRUE guru might instruct me. I think there are three key concepts rumbling around in this discussion that are related, but distinct: determinism, purity, and side effects. An easy trap to fall into is the idea that determinism = purity, when really they are not the same. There is a set of functions that are deterministic, but not pure. An example is putMVar: putMVar :: MVar a -> a -> IO () On the other hand, there are functions that are non-deterministic, but pure: nondeterministicAndPure :: () -> MonadState Int Int nondeterministicAndPure () = do x <- get return x Then, there are functions that are both deterministic and pure, like lookup, and functions that are neither deterministic, nor pure, like takeMVar. I'm thinking that side effects are really only necessary because Haskell programs expect to mutate the state of a computer outside of the haskell program. Perhaps if we had Haskell OS, everything could live in some giant MonadState, and IO could be disposed of entirely. Jeff _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Ryan Ingram
Ryan Ingram <[hidden email]> writes:
> You can emulate mutation with at most O(log(n)) penalty using a map. Given > that memory is of fixed size, log2(n) <= 64, so for "real-world" programs > this becomes O(1). I'm not sure assuming fixed size memory is a good idea for a theoretical discussion - your computer is no longer Turing complete, and one type of implementation will likely be able to fit a different set of programs in the given memory than the oher. Another nit: this is O(log(n)) of working set, not input/problem size. But I guess any algorithm must be at least O(working set size), so it's still a log factor (or less) of the algorithmic complexity. -k -- If I haven't seen further, it is by standing in the footprints of giants _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Jeff Shaw
Quoth Jeff Shaw <[hidden email]>,
... > I'm thinking that side effects are really only necessary because Haskell > programs expect to mutate the state of a computer outside of the haskell > program. I'm not a computer scientist, but in English, "side effect" is an effect that accompanies some other effect. E.g., you may take an antihistamine to relieve hay fever, and experience a side effect of drowsiness. Let's call the first an `intended effect'? Then in the matter of the computer outside the Haskell program - which is intended effect, and which is side effect? I'd have said, side effects would be like memory paging, deferred resource access for other processes, etc.? Some programs might leave behind temporary files ... I hope the answer is not that in computer science we regard all effects as side effects because the ideal computer program simply exists without consequence. Donn _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
On Sat, Mar 17, 2012 at 5:41 AM, Donn Cave <[hidden email]> wrote:
> I hope the answer is not that in computer science we regard all > effects as side effects because the ideal computer program simply > exists without consequence. The answer is that side effects has become something of a figure of speech, and now has a specialized meaning in programming languages. When we're talking about different uses of the word "function" in programming languages, side effects refer to any effect other than evaluating to some result when applied to some argument. For example, in languages like C, printf takes some arguments, and returns an int. When viewed as just a function, that's all there is to it; functions exist to take arguments and produce return values. But C extends the definition of a function to include additional effects, like making "Hello world" appear on a nearby computer screen. Because those effects are "aside from" the taking of arguments and returning of values that functions exist to do, they are "side effects"... even though in the specific case of printf, the effect is the main goal and everyone ignores the return value, still for functions in general, any effects outside of producing a resulting value from its arguments are "side effects". I suppose Haskell doesn't have "side effects" in that sense, since its effectful actions aren't confused with functions. (Well, except from silly examples like "the CPU gives off heat" or FFI/unsafe stuff like unsafePerformIO.) So maybe we should ideally call them just "effects". But since so many other languages use functions to describe effectful actions, the term has stuck. So pretty much when someone talks about side effects, even in Haskell, they means stateful interaction with the world. -- Chris Smith _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Donn Cave-4
Apparently on such solid ground that you hinder their critical thinking skills by answering for them.
On Fri, Mar 16, 2012 at 9:24 PM, Donn Cave <[hidden email]> wrote: > Quoth KC <[hidden email]>, > >> On Fri, Mar 16, 2012 at 7:44 PM, Jerzy Karczmarczuk >> <[hidden email]> wrote: >> >>> ... but the question of purity of a program - in my opinion - concerns >>> the program, and nothing else. >> >> You might be thinking of software engineering purity. > > Or software engineers might be thinking of purity in the same way. > I personally hope I think of purity in a way that's of some practical > use in terms of Haskell programs, and I would hope software engineers > in general would do likewise. From that perspective, it seems to me > that M. Karczmarczuk is on pretty solid ground. > > Donn > -- -- Regards, KC _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
KC comments the posting of Donn Cave referring to the soundness of
some potential approach of software engineers:
Apparently on such solid ground that you hinder their critical thinking skills by answering for them Monsieur KC, do you want to discuss, or just to be cute? In both cases, begin by signing your posts. I will not discuss with an anonymous, and concerning your question about referential transparency, I permit myself to send you to some standard literature. Over. == Chris Smith: ... And here I disagree. If printf, or whatever explodes an atomic bomb, this is not a "side effect". If a procedure executes such a statement: "x = x+1", or "a[1]=a[2]", it IS.When we're talking about different uses of the word "function" in programming languages, side effects refer to any effect other than evaluating to some result when applied to some argument. For example, in languages like C, printf takes some arguments, and returns an int. When viewed as just a function, that's all there is to it; functions exist to take arguments and produce return values. But C extends the definition of a function to include additional effects, like making "Hello world" appear on a nearby computer screen. And even that, not always ! In Clean, which is as pure as Haskell, there are "unique access" variables, and it is possible to write (+/-...) # myFile = write myFile "Hello World" And the point is that WHATEVER happens to the outer world, and the computer file system in particular, there are no side effects within the program. The "#" construction is a "temporal", sequential part of a purely functional expression, exactly as a monadic chain in Haskell, disguised as a do block. There are two "distinct" file objects, the "previous", and the "next" one, which happen to share the same name, because *the type system* prevents that a computing block refers to both. Either the old, or the new. This is my philosophy. If somebody disagrees, that's alright. Jerzy Karczmarczuk _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
|
In reply to this post by Chris Smith-31
Quoth Chris Smith <[hidden email]>,
... > The answer is that side effects has become something of a figure of > speech, and now has a specialized meaning in programming languages. > > When we're talking about different uses of the word "function" in > programming languages, side effects refer to any effect other than > evaluating to some result when applied to some argument. For example, > in languages like C, printf takes some arguments, and returns an int. > When viewed as just a function, that's all there is to it; functions > exist to take arguments and produce return values. I'm surprised by the use of "function" as a unit. I would have expected "expression" or something, but maybe that isn't semantically interesting as long as one can't exist independent of the other. > ... But C extends the > definition of a function to include additional effects, like making > "Hello world" appear on a nearby computer screen. Because those > effects are "aside from" the taking of arguments and returning of > values that functions exist to do, they are "side effects"... even > though in the specific case of printf, the effect is the main goal and > everyone ignores the return value, still for functions in general, any > effects outside of producing a resulting value from its arguments are > "side effects". If that's so, it's unfortunate. It would have been more profitable to confine the application of this term (side effect) to the context of the program, where it 1) makes sense in English, and 2) applies to a programming device that has always been of some interest. I have a little trouble defending this point of view because there's some overlap, inasmuch as the program may also retrieve values via external I/O. And Haskell provides writeIORef/readIORef as a convenient way to demonstrate that as a technical side effect without resorting to actual I/O. Still, the use of I/O and similar techniques to create a side effect are interesting as such, and my point is that if we call every I/O a side effect, the term loses its value as a way to describe this programming feature. Donn _______________________________________________ Haskell-Cafe mailing list [hidden email] http://www.haskell.org/mailman/listinfo/haskell-cafe |
| Powered by Nabble | Edit this page |
