digitalmars.D - Learning Haskell makes you a better programmer?
- Walter Bright (4/4) Dec 25 2012 I've often heard that claim, but here's an article with what the substan...
- Jakob Bornecrantz (12/18) Dec 25 2012 I think you missed a big part here, the by default of purity. It
- Walter Bright (4/15) Dec 25 2012 I think optional purity is pretty powerful. You can have the advantages ...
- Joseph Rushton Wakeling (3/5) Dec 25 2012 True, but there's a difference between what's useful when building an
- Simen Kjaeraas (7/16) Dec 26 2012 Absolutely. But whether purity should be the default or not is orthogona...
- bearophile (6/10) Dec 26 2012 The colourful Erik Meijer says that specifying what functions are
- Jonathan M Davis (5/16) Dec 26 2012 It probably would be better for stuff like @safe and pure to be the defa...
- so (18/24) Dec 25 2012 Same is often said for lisp for (IMO) far far better reasons, but
- SomeDude (14/22) Dec 25 2012 SICP also leads the student from the very basics all the way to
- so (14/21) Dec 25 2012 I didn't know "set -o vi" until a few weeks ago, learning it made
- Russel Winder (20/27) Dec 26 2012 The experimental evidence from psychology of programming research is
- Mehrdad (3/5) Dec 25 2012 I've written Python code like that, which was also unreadable to
- Russel Winder (19/27) Dec 26 2012 Code using map/filter/reduce requires a specific reading strategy, which
- Jonathan M Davis (12/19) Dec 25 2012 I totally agree that learning a functional language makes you a better
- bearophile (219/225) Dec 25 2012 (In the end this answer has become a little article.)
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (3/4) Dec 25 2012 I think I am being a troll but that page is dark white on white!
- Iain Buclaw (6/11) Dec 26 2012 It's called grey. Or gray if you speak american. :o)
- renoX (4/10) Dec 26 2012 Bleah, one good practice that I like to follow is to (optionaly)
- Andrei Alexandrescu (3/14) Dec 26 2012 debug statements to the rescue!
- renoX (7/28) Dec 26 2012 Yes of course, but what I was objecting is the article's take
- Russel Winder (23/29) Dec 26 2012 1
- Andrei Alexandrescu (4/14) Dec 26 2012 Only for immutable data.
- Russel Winder (23/31) Dec 26 2012 I'll have to admit confusion from the above statement: tail calls are a
- Andrei Alexandrescu (13/34) Dec 26 2012 A few rough definitions:
- Walter Bright (8/11) Dec 26 2012 In D, you can declare immutable data and immutable data structures. This...
- Thiez (7/14) Dec 26 2012 Rust can also do this. Apparently there were (are?) plans to
- Timon Gehr (5/17) Dec 26 2012 immutable and const are incompatible with lazy evaluation. Lazy
- Andrei Alexandrescu (3/11) Dec 26 2012 This would necessitate a bit of qualification :o).
- Timon Gehr (2/14) Dec 26 2012 http://www.haskell.org/haskellwiki/Monad/ST
- Andrei Alexandrescu (3/19) Dec 26 2012 That's not the same!
- Timon Gehr (4/29) Dec 26 2012 It is isolated state mutation inside a pure function, which is
- Andrei Alexandrescu (3/5) Dec 26 2012 Point taken, but claiming it's the same thing is a bit of a stretch.
- bearophile (5/6) Dec 26 2012 Many things I read in blogs and Reddit about Clojure are wrong,
- Russel Winder (21/27) Dec 27 2012 Reddit appears to be full of bluster, bullshit and rubbish which is why
- bearophile (9/12) Dec 27 2012 In my very limited Clojure experience I've seen that it uses a
- Russel Winder (19/25) Dec 28 2012 I have yet to find any JVM that doesn't require >120MB to start, then
- Chris (24/37) Dec 27 2012 It all depends on who you are catering for and what you are
- Red (4/4) Dec 28 2012 Why is immutable data considered necessary for functional
- evilrat (7/11) Dec 28 2012 well one of the points of immutable data is safely sharing across
- Russel Winder (25/31) Dec 28 2012 Functional programming languages providing parallelism "for free" is a
- Walter Bright (24/27) Dec 28 2012 People who say that C++ supports functional programming make exactly tha...
- deadalnix (11/15) Dec 28 2012 It depends what you mean by functional. It seems to me that
- Russel Winder (17/27) Dec 28 2012 In the most recent "Open Source Journal", Uncle Bob has stated that all
- deadalnix (22/42) Dec 28 2012 That is true. But is also quite reductive. If functional
- Russel Winder (28/46) Dec 28 2012 I am not sure I would relate this issue to abstraction per se, though it
- bearophile (6/9) Dec 28 2012 Near the end of this interview, Erik Meijer shows why removing
- Russel Winder (28/32) Dec 28 2012 Because immutable state is a concept entirely missing from functional
- Aquiles (46/46) Dec 26 2012 I will humbly offer my opinion as a guy who is learning both D
- bearophile (13/18) Dec 26 2012 A solution here is to think about loop pre-condition, invariant
- Phil Lavoie (47/47) Dec 26 2012 I have learned Haskell during my bachelor's degree and I cannot
- deadalnix (3/9) Dec 26 2012 That is exactly my methodology to find ICE. The problem is that
I've often heard that claim, but here's an article with what the substance is: http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1 Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.
Dec 25 2012
On Tuesday, 25 December 2012 at 19:37:42 UTC, Walter Bright wrote:I've often heard that claim, but here's an article with what the substance is: http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1 Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.I think you missed a big part here, the by default of purity. It is in D more work to enforce purity of functions then not. The other part he talked about is countered in the language (as well to a worrying degree in Phobos) with function returns of type auto. Taking his example: foo :: Map Integer String -> String -> auto Even if the function always returns integer it only requires one function to not do that and you would start second guessing every function returning auto. Cheers, Jakob.
Dec 25 2012
On 12/25/2012 11:57 AM, Jakob Bornecrantz wrote:On Tuesday, 25 December 2012 at 19:37:42 UTC, Walter Bright wrote:I think optional purity is pretty powerful. You can have the advantages of either, at your choice.Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.I think you missed a big part here, the by default of purity. It is in D more work to enforce purity of functions then not.The other part he talked about is countered in the language (as well to a worrying degree in Phobos) with function returns of type auto. Taking his example: foo :: Map Integer String -> String -> auto Even if the function always returns integer it only requires one function to not do that and you would start second guessing every function returning auto.Nobody makes you use auto, either.
Dec 25 2012
On 12/26/2012 12:11 AM, Walter Bright wrote:I think optional purity is pretty powerful. You can have the advantages of either, at your choice.True, but there's a difference between what's useful when building an application, and what's useful as a learning exercise.
Dec 25 2012
On 2012-11-26 00:12, Walter Bright <newshound2 digitalmars.com> wrote:On 12/25/2012 11:57 AM, Jakob Bornecrantz wrote:Absolutely. But whether purity should be the default or not is orthogonal to this. I would have preferred opt-out purity to opt-in, but it's not exactly make or break. -- SimenOn Tuesday, 25 December 2012 at 19:37:42 UTC, Walter Bright wrote:I think optional purity is pretty powerful. You can have the advantages of either, at your choice.Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.I think you missed a big part here, the by default of purity. It is in D more work to enforce purity of functions then not.
Dec 26 2012
Simen Kjaeraas:Absolutely. But whether purity should be the default or not is orthogonal to this. I would have preferred opt-out purity to opt-in, but it's not exactly make or break.The colourful Erik Meijer says that specifying what functions are not pure is better than specifying what functions are pure: http://www.youtube.com/watch?v=z0N1aZ6SnBk#t=54m53s Bye, bearophile
Dec 26 2012
On Thursday, December 27, 2012 02:22:44 bearophile wrote:Simen Kjaeraas:It probably would be better for stuff like safe and pure to be the default, but it's far too late for that now, regardless of how good an idea it would have been. Live and learn. - Jonathan M DavisAbsolutely. But whether purity should be the default or not is orthogonal to this. I would have preferred opt-out purity to opt-in, but it's not exactly make or break.The colourful Erik Meijer says that specifying what functions are not pure is better than specifying what functions are pure: http://www.youtube.com/watch?v=z0N1aZ6SnBk#t=54m53s
Dec 26 2012
On Tuesday, 25 December 2012 at 19:37:42 UTC, Walter Bright wrote:I've often heard that claim, but here's an article with what the substance is: http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1 Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.Same is often said for lisp for (IMO) far far better reasons, but it is still pure nonsense. In my case, the more i learn lisp more i hate c++, and since i have to use it, i become frustrated and unproductive. C++ made me develop a hatred to the languages that get in your way for absolutely no reason (example: lack of static if) or locks you to certain paradigms (single for Haskell?). I am reading the book "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp", and i have to say it was somewhat a shocking experience. The fact that in a popular book about the highest level language which includes chapters for writing interpreters, compilers, yet i haven't met a c/c++ book including such things, it is said these languages are one of the low level languages. I know it is much easier to write those for lisp than C, yet try to understand my point. Sorry for being a lisp advocate in D forum, but you know i am on your side, we all are (i hope) trying to find the best tool for the job.
Dec 25 2012
On Tuesday, 25 December 2012 at 20:29:54 UTC, so wrote:I am reading the book "Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp", and i have to say it was somewhat a shocking experience. The fact that in a popular book about the highest level language which includes chapters for writing interpreters, compilers, yet i haven't met a c/c++ book including such things, it is said these languages are one of the low level languages. I know it is much easier to write those for lisp than C, yet try to understand my point.SICP also leads the student from the very basics all the way to the writing of a Scheme interpreter and a compiler in Scheme. That would probably not be possible in a reasonable number of pages for a language with a more complex syntax. Anyway, that doesn't mean that it's not possible, it's just take a whole lot more effort to do the same in C++ or in D. As for being a better programmer after having used some advanced concepts, I don't know. I think every feature of a language must be used where appropriate. I've seen some Python code using heavily map/filter/etc that was simply unreadable to me. In some places, I find it easier to understand for loops, while in other cases, using functional style programming conveys the intent better. But maybe that's just me.
Dec 25 2012
On Tuesday, 25 December 2012 at 20:50:35 UTC, SomeDude wrote:As for being a better programmer after having used some advanced concepts, I don't know. I think every feature of a language must be used where appropriate. I've seen some Python code using heavily map/filter/etc that was simply unreadable to me. In some places, I find it easier to understand for loops, while in other cases, using functional style programming conveys the intent better. But maybe that's just me.I didn't know "set -o vi" until a few weeks ago, learning it made me a better linux user as i knew both vi and terminal. but it didn't make me a better pc user generally. If my environment doesn't evolve with me or lack tools to combine to make something new (probably i'm repeating myself) than i gain nothing from learning a feature of another language. IMO, learning programming language X doesn't make you a better programmer. Learning X make you better X programmer. But if your existing environment/language is extremely flexible, takes code generation *very* seriously, you have a case. You gain something from learning a new feature or a paradigm. That is why lisp fascinates me, as i believe code generation is one of the most important (if not the most important) thing in a PL.
Dec 25 2012
On Wed, 2012-12-26 at 01:45 +0100, so wrote: [=E2=80=A6]IMO, learning programming language X doesn't make you a better=20 programmer. Learning X make you better X programmer. But if your=20 existing environment/language is extremely flexible, takes code=20 generation *very* seriously, you have a case. You gain something=20 from learning a new feature or a paradigm. That is why lisp=20 fascinates me, as i believe code generation is one of the most=20 important (if not the most important) thing in a PL.The experimental evidence from psychology of programming research is exactly that the more distinct computational models that a programmer is able to use reasonably well then the better programmer the person is in any specific programming language. Groovy has abstract syntax transforms, Scala has followed Lisp and introduced macros =E2=80=93 not to be confused with the C pre-processor thi= ngs of similar name. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Dec 26 2012
On Tuesday, 25 December 2012 at 20:50:35 UTC, SomeDude wrote:I've seen some Python code using heavily map/filter/etc that was simply unreadable to me.I've written Python code like that, which was also unreadable to me. 8-)
Dec 25 2012
On Tue, 2012-12-25 at 21:50 +0100, SomeDude wrote: [=E2=80=A6]=20 As for being a better programmer after having used some advanced=20 concepts, I don't know. I think every feature of a language must=20 be used where appropriate. I've seen some Python code using=20 heavily map/filter/etc that was simply unreadable to me. In some=20 places, I find it easier to understand for loops, while in other=20 cases, using functional style programming conveys the intent=20 better. But maybe that's just me.Code using map/filter/reduce requires a specific reading strategy, which is fine for people coming from Lisp/Clojure/Haskell/OCaml/Groovy/Ruby but difficult for people coming from C, assembly language, Java, etc. C ++ and D are treading a middle ground. BDFL has stated that list/dictionary/set comprehensions are to be preferred over functional chaining constructs. In general this is good advice, even for languages other than Python. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Dec 26 2012
On Tuesday, December 25, 2012 11:37:42 Walter Bright wrote:I've often heard that claim, but here's an article with what the substance is: http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1 Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.I totally agree that learning a functional language makes you a better programmer, and I think that it's awesome that we can program that way in D. However, to actually really gain the benefit in terms of learning, you probably have to actually program in a functional language, because you're _forced_ to learn how to program in a functional paradigm, whereas in D it's only an option for when you want to do so. And Haskell is a particularly good language for it, because its laziness forces it to be pretty much purely functional whereas a number of other functional languages have more back doors to imperative programming and mutation. Either way, it's great that D allows us to program in such paradigms. - Jonathan M Davis
Dec 25 2012
(In the end this answer has become a little article.) Walter: Being a "good programmer" means having a quite long list of different skills and qualities. I think that learning Haskell helps you improve, but only in a small percentage of those skills. So I think overall Haskell doesn't make a large difference (despite since many months I have started to study Haskell). Regarding D, it's very different from Haskell, and I think it's very hard to learn from D what you can learn from Haskell. Haskell is single-paradigm and almost forces you to program in certain different ways. From that little blog post:It forced me to think of every such problem as a chain of the primitive list operations, maps, folds, filters and scans. Now I always think in these terms. I "see" the transformation of a container as a simple sequence of these operations.<Decomposing part of the code in terms of such higher order functions is sometimes a good idea that makes the code cleaner and frees the mind to think at a higher level. Python goes one step further with its list comps that make the code even more readable, removing map and filters (list comps are available in Haskell too, but the syntax is a little worse, and probably for cultural reasons it's used less than in Python): foos = (x * x for x in items if x % 2) In D you have to use map and filter to do the same thing, and it's more noisy, less readable and longer: auto foos = items.filter!(x => x % 2)().map!(x => x * x)(); In Haskell sometimes you define an inner recursive function (sometimes named "go") where in D/Python you just use a loop. The loop doesn't risk blowing the stack (especially in Python), is often equally shorter to write, and in many situations I keep finding loops more readable and cleaner than recursion. So on one hand you have C code that contains lot of hairy nested loops with twiddly pointer arithmetic, that shows you the details of how something is done, but it doesn't tell you why. To understand such C code you have to make a summary of the code in your head, and build a bit higher view of what is done (from an older version of http://rosettacode.org/wiki/Topswops ): #include <stdio.h> #include <string.h> typedef struct { char v[16]; } deck; int n, d, best[16]; void tryswaps(deck *a, int f, int s) { int i, j, k; deck b = *a; if (d > best[n]) best[n] = d; for (i = 0, k = 1 << s; k >>= 1, --s; ) { if (a->v[s] == -1 || a->v[s] == s) break; i |= k; if ((i & f) == i && d + best[s] < best[n]) return; } s++, d++; for (i = 1, k = 2; i < s; i++, k <<= 1) { if (b.v[i] == -1) { if (f & k) continue; } else if (b.v[i] != i) continue; b.v[0] = j = i; while (j--) b.v[i-j] = a->v[j]; tryswaps(&b, f|k, s); } d--; } int main(void) { deck x; memset(&x, -1, sizeof(x)); x.v[0] = 0; for (n = 1; n <= 12; n++) { best[n] = d = 0; tryswaps(&x, 1, n); printf("%2d: %d\n", n, best[n]); } return 0; } A short Haskell solution is shorter, and much cleaner/nicer if you know a little of Haskell (but also much slower, possibly ten times slower or more): import Data.List (permutations) topswops :: Int -> Int topswops n = foldl max 0 $ map topswops' $ permutations [1..n] topswops' :: [Int] -> Int topswops' xa (1:_) = 0 topswops' xa (x:_) = 1 + topswops' reordered where reordered = reverse (take x xa) ++ drop x xa main = mapM_ (\x -> putStrLn $ show x ++ ":\t" ++ show (topswops x)) [1..10] On the other hand Haskell code sometimes contains tens of tiny functions that requires you a elephant-grade long term memory (even if you are using an Haskell IDE) to remember the meaning of all those functions and several 3-4-symbol-long operators, plus it asks you a large medium-term memory to keep in mind how those numerous little functions are plugged together in complex ways to produce the results. So while I've seen both very good C and good Haskell code, in both languages it's possible to write code that requires lot of brainpower to be understood. I have found that good D code is a good middle point between those kinds of C and Haskell coding: it calls and uses a moderate amount of functions, it often uses a very limited amount of pointers, its loops usually are clean and at worst use slices instead of pointer arithmetic. And micropatterns like map and filter are available in D, but also normal loops are available to avoid recursion. Immutability is available. The end result is a kind of D code that for me avoids the problems visible in both that C and Haskell code. This is why I often use D instead of Haskell or C. (I have not yet studied Scala, maybe it offers similar qualities as D or maybe even better, despite on the JavaVM it often doesn't allow you to specify with enough precision the layout of the data structures in memory). This is a modified D version of the C code (it's not exactly equal), and for me it's significantly more clean than that C code: import std.algorithm, std.range; uint topswops(in uint n) nothrow in { assert(n > 0 && n < 32); } body { static uint[32] best; alias T = byte; alias Deck = T[best.length]; void trySwaps(in ref Deck deck, in uint f, in uint d) nothrow { if (d > best[n]) best[n] = d; foreach_reverse (i; 0 .. n) { if (deck[i] == -1 || deck[i] == i) break; if (d + best[i] <= best[n]) return; } Deck deck2 = deck; foreach (i; 1 .. n) { immutable uint k = 1U << i; if (deck2[i] == -1) { if (f & k) continue; } else if (deck2[i] != i) continue; deck2[0] = cast(T)i; foreach_reverse (j; 0 .. i) deck2[i - j] = deck[j]; // Reverse copy. trySwaps(deck2, f | k, d + 1); } } best[n] = 0; Deck deck0 = -1; deck0[0] = 0; trySwaps(deck0, 1, 0); return best[n]; } void main() { import std.stdio; foreach (i; 1 .. 12) writefln("%2d: %d", i, topswops(i)); } Using templates you can make that D code about twice faster. That D code is still low-level, it contains a static variable, but still that code is much simpler to understand compared to that C code. In that D code this is an alternative way to write the reverse copy, but unfortunately here you have to pay some abstraction penalty, because using DMD this makes the code significantly slower (in Phobos "copyTo" is named "copy" but I prefer "copyTo" to remind me what the source and destination are!): deck[0 .. i].copyTo(deck2[1 .. i + 1].retro()); That D code is quite "algorithmic" and designed for speed. If you care less for performance it's easy to write higher level D code that's shorter and easy to understand: import std.stdio, std.algorithm, std.range, permutations2; uint topswops(in uint n) in { assert (n > 0 && n < 32); } body { static uint flip(uint[] deck) pure nothrow { uint[32] temp = void; temp[0 .. deck.length] = deck[]; uint count = 0; for (auto t0 = temp[0]; t0; t0 = temp[0]) { temp[0 .. t0 + 1].reverse(); // Slow with DMD. count++; } return count; } return iota(n).array().permutations!0().map!flip().reduce!max(); } void main() { foreach (i; 1 .. 11) writefln("%2d: %d", i, topswops(i)); } There are ways to write this D code in an even a little simpler way to understand, producing a little longer (less packed) code. On the other hand D is not perfect, and there are always bad parts or things to improve in everything. The lack of a "yield" as in Python makes many D coding patterns less handy (and the lack of list comps makes the D code a little less readable, but this is less important). The lazy lists of Haskell (also present in some form in Perl6 and Scala) offer some handy coding patterns, that are rather harder to use in D. The lack of good subtyping makes D code less strong (I have discussed it some times, like here http://forum.dlang.org/thread/pxnyniryvdwpdxoymuau forum.dlang.org ). In D sometimes the creation of immutable data structures is not handy. I have discussed this in two or more past posts. If you compare Haskell with D, the use and management of the Maybe Haskell type is much better than the Nullable of Phobos, because of D lack of both pattern matching and of a bit of typestate (that should allow D to know that in the "else" branch of a not-null test of a Nullable with isNull, the type is not null, it can't throw an exception and it can be used safely). Some of such things should be improved in D language and Phobos, where possible. -------------------- SomeDude:I've seen some Python code using heavily map/filter/etc that was simply unreadable to me.<Pythonic code does not contain many map/filter (Pythonic code uses lazy or eager list comps). So probably that was bad Python code, or at least not pythonic. Bye, bearophile
Dec 25 2012
On 12/25/2012 11:37 AM, Walter Bright wrote:http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1I think I am being a troll but that page is dark white on white! Ali
Dec 25 2012
On 26 December 2012 00:54, Ali =C7ehreli <acehreli yahoo.com> wrote:On 12/25/2012 11:37 AM, Walter Bright wrote:g-haskell.html?m=3D1>http://dubhrosa.blogspot.co.**uk/2012/12/lessons-learning-**haskell.html?m=3D1<http://dubhrosa.blogspot.co.uk/2012/12/lessons-learnin=I think I am being a troll but that page is dark white on white! AliIt's called grey. Or gray if you speak american. :o) --=20 Iain Buclaw *(p < e ? p++ : p) =3D (c & 0x0f) + '0';
Dec 26 2012
On Tuesday, 25 December 2012 at 19:37:42 UTC, Walter Bright wrote:I've often heard that claim, but here's an article with what the substance is: http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1 Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.Bleah, one good practice that I like to follow is to (optionaly) log what my functions do, so it doesn't match well with "IO change the type of your function"..
Dec 26 2012
On 12/26/12 9:11 AM, renoX wrote:On Tuesday, 25 December 2012 at 19:37:42 UTC, Walter Bright wrote:debug statements to the rescue! AndreiI've often heard that claim, but here's an article with what the substance is: http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1 Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.Bleah, one good practice that I like to follow is to (optionaly) log what my functions do, so it doesn't match well with "IO change the type of your function"..
Dec 26 2012
On Wednesday, 26 December 2012 at 16:01:27 UTC, Andrei Alexandrescu wrote:On 12/26/12 9:11 AM, renoX wrote:Yes of course, but what I was objecting is the article's take that IO should change the type of the function: that's an oversimplification.. This is not true for debug/logging statements. renoXOn Tuesday, 25 December 2012 at 19:37:42 UTC, Walter Bright wrote:debug statements to the rescue! AndreiI've often heard that claim, but here's an article with what the substance is: http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1 Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.Bleah, one good practice that I like to follow is to (optionaly) log what my functions do, so it doesn't match well with "IO change the type of your function"..
Dec 26 2012
On Tue, 2012-12-25 at 11:37 -0800, Walter Bright wrote:I've often heard that claim, but here's an article with what the substanc=e is:=20 http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=3D=1=20 Note that D offers this style of programming, with checkable purity,=20 immutability and ranges. I think it is a very important paradigm.Does D do tail recursion optimisation? Can the D compiler check to enforce *NO* (or at the worst single) assignment to a variable? I am guessing that the D compilers can enforce referential transparency and zero side-effects. Functional programming is a good influence, but in it's Haskell form is liable a minority language. Clojure could make Lisp a mainstream language, but.. In the end the move to declarative expression and internal rather than external iteration is a move all languages are taking: C++, Python, D, Go, Java,.. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Dec 26 2012
On 12/26/12 9:42 AM, Russel Winder wrote:On Tue, 2012-12-25 at 11:37 -0800, Walter Bright wrote:Yah, but not tail calls. (That should be on the list...)I've often heard that claim, but here's an article with what the substance is: http://dubhrosa.blogspot.co.uk/2012/12/lessons-learning-haskell.html?m=1 Note that D offers this style of programming, with checkable purity, immutability and ranges. I think it is a very important paradigm.Does D do tail recursion optimisation?Can the D compiler check to enforce *NO* (or at the worst single) assignment to a variable?Only for immutable data. Andrei
Dec 26 2012
On Wed, 2012-12-26 at 11:03 -0500, Andrei Alexandrescu wrote:On 12/26/12 9:42 AM, Russel Winder wrote:[=E2=80=A6]I'll have to admit confusion from the above statement: tail calls are a programmer technique, tail call optimization is a compiler / run time technique. If a programmer uses tail calls and the compiler realizes tail call optimization then the result is equivalent to iteration.Does D do tail recursion optimisation?=20 Yah, but not tail calls. (That should be on the list...)But isn't that the whole point, in functional programming there is only immutable data. Thus a programming language that allows mutable data cannot really be said to be usable for functional programming style. On the other hand it is 2012-12-26T16:32 and nearly time for fireworks, and drinkies. Hopefully everyone is having a peaceful and happy Solstice/Xmas/New Year/Hogmanay/<insert your personal choice of excuse for celebration>. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winderCan the D compiler check to enforce *NO* (or at the worst single) assignment to a variable?=20 Only for immutable data.
Dec 26 2012
On 12/26/12 11:34 AM, Russel Winder wrote:On Wed, 2012-12-26 at 11:03 -0500, Andrei Alexandrescu wrote:A few rough definitions: Tail recursion: the last evaluation performed in a branch of a function is a call to itself. Tail recursion optimization: replace tail recursion with a GOTO the entry point of the function. Tail call: the last evaluation performed in a branch of a function is a call to another function. Tail call optimization: replace tail call with a GOTO the entry point of the called function.On 12/26/12 9:42 AM, Russel Winder wrote:[…]I'll have to admit confusion from the above statement: tail calls are a programmer technique, tail call optimization is a compiler / run time technique. If a programmer uses tail calls and the compiler realizes tail call optimization then the result is equivalent to iteration.Does D do tail recursion optimisation?Yah, but not tail calls. (That should be on the list...)Yah, that's the whole point so we're in good shape there.But isn't that the whole point, in functional programming there is only immutable data. Thus a programming language that allows mutable data cannot really be said to be usable for functional programming style.Can the D compiler check to enforce *NO* (or at the worst single) assignment to a variable?Only for immutable data.On the other hand it is 2012-12-26T16:32 and nearly time for fireworks, and drinkies. Hopefully everyone is having a peaceful and happy Solstice/Xmas/New Year/Hogmanay/<insert your personal choice of excuse for celebration>.Same to all from yours truly! Andrei
Dec 26 2012
On 12/26/2012 8:34 AM, Russel Winder wrote:But isn't that the whole point, in functional programming there is only immutable data. Thus a programming language that allows mutable data cannot really be said to be usable for functional programming style.In D, you can declare immutable data and immutable data structures. This makes it usable for FP style (along with checkable function purity). But D also does something I think is fairly unique. A function can be pure, but inside that function, mutation is allowed as long as that mutation does not "leak" outside of the function. A pure function with immutable parameters does completely specify the function in its signature. What happens inside the function is not relevant, it is not necessary that locals be immutable.
Dec 26 2012
On Wednesday, 26 December 2012 at 22:09:26 UTC, Walter Bright wrote:But D also does something I think is fairly unique. A function can be pure, but inside that function, mutation is allowed as long as that mutation does not "leak" outside of the function. A pure function with immutable parameters does completely specify the function in its signature. What happens inside the function is not relevant, it is not necessary that locals be immutable.Rust can also do this. Apparently there were (are?) plans to allow pure functions that call impure delegates, as long as the delegate has been provided by the caller, but I'm not sure if they implemented that yet (or perhaps they've ditched the idea entirely).
Dec 26 2012
On 12/26/2012 11:09 PM, Walter Bright wrote:On 12/26/2012 8:34 AM, Russel Winder wrote:immutable and const are incompatible with lazy evaluation. Lazy evaluation is not strictly necessary for FP, but it makes code a lot more expressive. (D ranges are lazy.)But isn't that the whole point, in functional programming there is only immutable data. Thus a programming language that allows mutable data cannot really be said to be usable for functional programming style.In D, you can declare immutable data and immutable data structures. This makes it usable for FP style (along with checkable function purity).But D also does something I think is fairly unique. A function can be pure, but inside that function, mutation is allowed as long as that mutation does not "leak" outside of the function. A pure function with immutable parameters does completely specify the function in its signature. What happens inside the function is not relevant, it is not necessary that locals be immutable.Haskell has this.
Dec 26 2012
On 12/26/12 6:13 PM, Timon Gehr wrote:This would necessitate a bit of qualification :o). AndreiBut D also does something I think is fairly unique. A function can be pure, but inside that function, mutation is allowed as long as that mutation does not "leak" outside of the function. A pure function with immutable parameters does completely specify the function in its signature. What happens inside the function is not relevant, it is not necessary that locals be immutable.Haskell has this.
Dec 26 2012
On 12/27/2012 12:53 AM, Andrei Alexandrescu wrote:On 12/26/12 6:13 PM, Timon Gehr wrote:http://www.haskell.org/haskellwiki/Monad/STThis would necessitate a bit of qualification :o). AndreiBut D also does something I think is fairly unique. A function can be pure, but inside that function, mutation is allowed as long as that mutation does not "leak" outside of the function. A pure function with immutable parameters does completely specify the function in its signature. What happens inside the function is not relevant, it is not necessary that locals be immutable.Haskell has this.
Dec 26 2012
On 12/26/12 7:11 PM, Timon Gehr wrote:On 12/27/2012 12:53 AM, Andrei Alexandrescu wrote:That's not the same! AndreiOn 12/26/12 6:13 PM, Timon Gehr wrote:http://www.haskell.org/haskellwiki/Monad/STThis would necessitate a bit of qualification :o). AndreiBut D also does something I think is fairly unique. A function can be pure, but inside that function, mutation is allowed as long as that mutation does not "leak" outside of the function. A pure function with immutable parameters does completely specify the function in its signature. What happens inside the function is not relevant, it is not necessary that locals be immutable.Haskell has this.
Dec 26 2012
On Thursday, 27 December 2012 at 00:56:02 UTC, Andrei Alexandrescu wrote:On 12/26/12 7:11 PM, Timon Gehr wrote:It is isolated state mutation inside a pure function, which is what Walter emphasized on.On 12/27/2012 12:53 AM, Andrei Alexandrescu wrote:That's not the same! AndreiOn 12/26/12 6:13 PM, Timon Gehr wrote:http://www.haskell.org/haskellwiki/Monad/STThis would necessitate a bit of qualification :o). AndreiBut D also does something I think is fairly unique. A function can be pure, but inside that function, mutation is allowed as long as that mutation does not "leak" outside of the function. A pure function with immutable parameters does completely specify the function in its signature. What happens inside the function is not relevant, it is not necessary that locals be immutable.Haskell has this.
Dec 26 2012
On 12/26/12 8:43 PM, Timon Gehr wrote:It is isolated state mutation inside a pure function, which is what Walter emphasized on.Point taken, but claiming it's the same thing is a bit of a stretch. Andrei
Dec 26 2012
Russel Winder:Clojure could make Lisp a mainstream language,Many things I read in blogs and Reddit about Clojure are wrong, or nearly wrong. Bye, bearophile
Dec 26 2012
On Wed, 2012-12-26 at 22:48 +0100, bearophile wrote:Russel Winder: =20Reddit appears to be full of bluster, bullshit and rubbish which is why it is entirely ignorable. =20 Practical experience, i.e. actually using it for real on real projects, indicates that Clojure is an excellent language and very usable. Moreover many people (*) building systems are actually working with Clojure and finding it a huge boon. Also Uncle Bob tells us it is the final programming language ;-) The JVM language set is definitely now Java, Scala, Groovy, Clojure. (*) OK mostly young entrepreneurial types doing start-ups. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winderClojure could make Lisp a mainstream language,=20 Many things I read in blogs and Reddit about Clojure are wrong,=20 or nearly wrong.
Dec 27 2012
Russel Winder:Practical experience, i.e. actually using it for real on real projects, indicates that Clojure is an excellent language and very usable.In my very limited Clojure experience I've seen that it uses a LOT of memory even for my small programs, sometimes almost ten times more than equivalent Python programs (like 120 MB for a small program that processes small genomic text files). And I've seen to write fast Clojure programs I have to add a ton of annotations to the code. So I have not used it further. Bye, bearophile
Dec 27 2012
On Thu, 2012-12-27 at 12:59 +0100, bearophile wrote: [=E2=80=A6]In my very limited Clojure experience I've seen that it uses a=20 LOT of memory even for my small programs, sometimes almost ten=20 times more than equivalent Python programs (like 120 MB for a=20 small program that processes small genomic text files). And I've=20 seen to write fast Clojure programs I have to add a ton of=20 annotations to the code. So I have not used it further.I have yet to find any JVM that doesn't require >120MB to start, then there is the Clojure system and your program, so that figure doesn't surprise me. In any C/C++/Fortran context Python is the dynamic programming language if choice, but there is also Lua. Clojure programs are not good for computational efficiency on the JVM, so if that is what you are after Clojure is the wrong tool. Groovy, Scala, Java, Kotlin, Ceylon form the choice set in that context. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Dec 28 2012
On Thursday, 27 December 2012 at 11:45:45 UTC, Russel Winder wrote:On Wed, 2012-12-26 at 22:48 +0100, bearophile wrote:It all depends on who you are catering for and what you are developing. If you have to develop cross-platform applications with (possibly) graphical user interfaces any Java based technology (ironically enough!) can quickly turn into a nightmare. There's always at least one serious pitfall and I have learned that you cannot pass the burden of dealing with things like JVMs on to the user. Also, over the years I have taken a dislike to "ideological" languages that dictate a certain paradigm or coding style (Python). What attracted me to D was the lack of "ideology" (multi-paradigm) and its natively-compiled cross-platform approach with easy C/C++-integration. Before I discovered D I was at a loss trying to find a modern language (= concise and productive) that would work natively on different platforms, because I am working in a small team and "write once run everywhere" is really important. All other features like pure and safe programming, unit tests, contract programming etc. are nice and helpful (_optional_) features but were not a top priority. From my point of view the only really important issue is concurrency programming, multithreading and everything related to it. One of the biggest strengths of D is the philosophy "Well, you needn't...but you can of course"Russel Winder:Practical experience, i.e. actually using it for real on real projects, indicates that Clojure is an excellent language and very usable. Moreover many people (*) building systems are actually working with Clojure and finding it a huge boon. Also Uncle Bob tells us it is the final programming language ;-) The JVM language set is definitely now Java, Scala, Groovy, Clojure. (*) OK mostly young entrepreneurial types doing start-ups.
Dec 27 2012
Why is immutable data considered necessary for functional programming style? Can't a a programmer or programmer just do the same thing with mutable data, but not mutate it? That is, couldn't Python be used for functional programming?
Dec 28 2012
On Friday, 28 December 2012 at 08:13:05 UTC, Red wrote:Why is immutable data considered necessary for functional programming style? Can't a a programmer or programmer just do the same thing with mutable data, but not mutate it? That is, couldn't Python be used for functional programming?well one of the points of immutable data is safely sharing across threads(the point there is that data once allocated doesn't changes so no need to sync it), functional languages also claims that they provides easy concurrency(if not "automagically"), but i can't say how it's really "easy" since i mostly do imperative and object programming.
Dec 28 2012
On Fri, 2012-12-28 at 09:37 +0100, evilrat wrote: [=E2=80=A6]well one of the points of immutable data is safely sharing across=20 threads(the point there is that data once allocated doesn't=20 changes so no need to sync it), functional languages also claims=20 that they provides easy concurrency(if not "automagically"), but=20 i can't say how it's really "easy" since i mostly do imperative=20 and object programming.Functional programming languages providing parallelism "for free" is a deep issue. Given the computational model of graph reduction, the whole concept of parallelism is different from that of JVM-based and native languages. OCaml has a GIL and so cannot handle single process multi-threaded parallelism. Haskell has real problems with parallelism because it is lazy: without manually structuring the sparks, you get all the computation on the master thread no mater what. Simon Peyton Jones and Simon Marlow have created "Data Parallel Haskell" which makes data parallel computations in Haskell very parallel and very fast. Actor, dataflow, CSP, fork-join style parallelism is difficult in pure functional languages. Clojure has made best inroads on this by employing the features of the JVM in a Lisp context. =20 --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Dec 28 2012
On 12/28/2012 12:13 AM, Red wrote:Why is immutable data considered necessary for functional programming style? Can't a a programmer or programmer just do the same thing with mutable data, but not mutate it?People who say that C++ supports functional programming make exactly that argument. The problem, though, is this: T func(U u); // this is a pure function What does that tell you about func? It takes a U as one of its inputs, and returns an instance of T. The comment, of course, means nothing. func may read or write mutable global state, it may mutate whatever u references. How would you know? If you wrote all the code yourself, and you didn't make any mistakes, perhaps you would know. But if you are handed this code, or you work on a team, you would have no idea. There is no tool to check it, so you'd be reduced to manually going through every line of it and every line of every function that func() calls, etc. Then when a member of your team checks in code, you're back to square one, and have to start over with the manual verification, and hope you didn't make a mistake with that. Of course, nobody does something that tedious, and defaults back to trusting the comment, which is what I'd call "faith-based programming". I don't believe that faith-based programming scales well at all. Programs are getting bigger and bigger all the time, and the growth of static analysis tools suggests that we *need* mechanical verification of properties. Faith-based programming is going to wind up on the ash heap of history. The bottom line is that a language that does not support mechanical verification of functional programming, does not support functional programming.
Dec 28 2012
On Friday, 28 December 2012 at 08:13:05 UTC, Red wrote:Why is immutable data considered necessary for functional programming style? Can't a a programmer or programmer just do the same thing with mutable data, but not mutate it? That is, couldn't Python be used for functional programming?It depends what you mean by functional. It seems to me that you'll find 2 major things that are usually understood as functionnal : - abstraction based on first class function. javascript is the perfect example here, and is functional. - purity and immutability. If you have no tools to enforce immutability, you need to completely break abstraction to get the benefit. This is bug prone and will not scale (without abstraction nothing big is achievable).
Dec 28 2012
On Fri, 2012-12-28 at 10:53 +0100, deadalnix wrote: [=E2=80=A6]It depends what you mean by functional. It seems to me that=20 you'll find 2 major things that are usually understood as=20 functionnal : - abstraction based on first class function. javascript is the=20 perfect example here, and is functional. - purity and immutability.In the most recent "Open Source Journal", Uncle Bob has stated that all you need to say is "no assignment" and you end up having to invent functional programming.If you have no tools to enforce immutability, you need to=20 completely break abstraction to get the benefit. This is bug=20 prone and will not scale (without abstraction nothing big is=20 achievable).I am not sure what you mean by "break abstraction" here. Nor how you get to "will not scale". Can you elaborate? Thanks. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Dec 28 2012
On Friday, 28 December 2012 at 13:03:11 UTC, Russel Winder wrote:On Fri, 2012-12-28 at 10:53 +0100, deadalnix wrote: […]That is true. But is also quite reductive. If functional programming can solve that problem, it is also very suited for many other things, for instance event programming (where concept like immutability and purity are not that useful).It depends what you mean by functional. It seems to me that you'll find 2 major things that are usually understood as functionnal : - abstraction based on first class function. javascript is the perfect example here, and is functional. - purity and immutability.In the most recent "Open Source Journal", Uncle Bob has stated that all you need to say is "no assignment" and you end up having to invent functional programming.Sure. To make that clear I have to reintroduce the context : I was answering to a post that stated that even if the language don't support immutability, you can have immutability simply by not mutate data. To benefit from immutability, you have to be 100% sure that no piece of code will mutate the data ever. If you have no support for that, you break abstraction, because you have to know the internal of every piece of code you use, in order to know if the data are modified or not. If you have to know the internal of each piece of code you use, then abstraction is broken. If abstraction is broken, then the ability to code will be reduced as the codebase grow, to a point where nothing is maintainable anymore. When I say that it will not not scale, I'm talking about scaling the technique to a bigger codebase, not actually scaling the resulting program to bigger workload. The subject is quite big, and I have proposed a talk about it in DConf 2013 (I'm waiting for Walter to accept or reject).If you have no tools to enforce immutability, you need to completely break abstraction to get the benefit. This is bug prone and will not scale (without abstraction nothing big is achievable).I am not sure what you mean by "break abstraction" here. Nor how you get to "will not scale". Can you elaborate? Thanks.
Dec 28 2012
On Fri, 2012-12-28 at 16:38 +0100, deadalnix wrote: [=E2=80=A6]Sure. To make that clear I have to reintroduce the context : I=20 was answering to a post that stated that even if the language=20 don't support immutability, you can have immutability simply by=20 not mutate data. =20 To benefit from immutability, you have to be 100% sure that no=20 piece of code will mutate the data ever. If you have no support=20 for that, you break abstraction, because you have to know the=20 internal of every piece of code you use, in order to know if the=20 data are modified or not. If you have to know the internal of=20 each piece of code you use, then abstraction is broken.I am not sure I would relate this issue to abstraction per se, though it is about preconditions, postconditions and assumptions that can, or cannot, be made. I think we agree on the substance just differ on the language used to describe the concepts. =20If abstraction is broken, then the ability to code will be=20 reduced as the codebase grow, to a point where nothing is=20 maintainable anymore. When I say that it will not not scale, I'm=20 talking about scaling the technique to a bigger codebase, not=20 actually scaling the resulting program to bigger workload.OK, I think we agree on substance just differ on the choice of language used to describe this situation. Here though "abstraction" and "broken abstraction" can work for me :-) This issue is one of the problems with very large Python codebases. They can be got round with functional tests, but strong discipline is needed. Ada and Modula-2 introduced a lot of good stuff! Thanks for taking the time to go into more depth.The subject is quite big, and I have proposed a talk about it in=20 DConf 2013 (I'm waiting for Walter to accept or reject).Sadly I won't be able to get to the conference: to travel on an aeroplane for longer than about 2 hours I have to lie flat for long periods. This generally means great cost, that is only affordable when someone else is paying, which usually means client-paid consultancy/training gigs. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Dec 28 2012
Russel Winder:In the most recent "Open Source Journal", Uncle Bob has stated that all you need to say is "no assignment" and you end up having to invent functional programming.Near the end of this interview, Erik Meijer shows why removing assignments is not enough if there is multi threading: http://www.youtube.com/watch?v=z0N1aZ6SnBk#t=60m0s Bye, bearophile
Dec 28 2012
On Fri, 2012-12-28 at 09:13 +0100, Red wrote:Why is immutable data considered necessary for functional=20 programming style? Can't a a programmer or programmer just do the=20 same thing with mutable data, but not mutate it? That is,=20 couldn't Python be used for functional programming?Because immutable state is a concept entirely missing from functional languages: functional languages have no tools for handling mutable state. OK Haskell has introduced arrays and indexing but it remains a dark corner for most use cases. Yes, but=E2=80=A6 if a language provide features you would be writing in a non-idiomatic way to simply ignore those features. The issue here is that a language will embody a computational model and an idiomatic mode of expression of algorithms. A language should always be used in as idiomatic way as possible. To use an imperative language in a purely functional way will lead to poor code. Conversely all use of mutable shared state is a code smell that should lead to a refactoring. Python cannot be used for functional programming in the purist sense due to lack of single assignment, presence of for and while loops, and lack of tail recursion optimization. However with higher order functional, list, set and dictionary comprehensions, many of the techniques and idioms of functional programming can, indeed should, be used when programming in Python. --=20 Russel. =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D Dr Russel Winder t: +44 20 7585 2200 voip: sip:russel.winder ekiga.n= et 41 Buckmaster Road m: +44 7770 465 077 xmpp: russel winder.org.uk London SW11 1EN, UK w: www.russel.org.uk skype: russel_winder
Dec 28 2012
I will humbly offer my opinion as a guy who is learning both D and Haskell. Here are some of the finer points of Haskell that has directly improved my programming: Referential Transparency takes away mutation and gives you reliable composition. To do anything useful in Haskell you have to at some point compose functions. To compose functions effectively you have to think about what your functions input/output are and how they relate. So instead of having a sink function that returns nothing and does magic inside you think in terms of testable individual components that focus only on one aspect of the computation. Recursion and Breaking apart tough problems. When you are forced to think recursively you have to think of your base cases, your invariants, your pre and post conditions, and how you get from x[k] -> x[k+1] without violating your contract. Again it encourages deliberate design as opposed to empirical exploration. Type Classes are an abstraction on types similar to those found in D and C++. It removes the idea that interfaces are an OOP construct instead shows you how you can design the basis of communication between data by supporting a set of functions. Lastly, I found GHC really helpful in its brutal nit-picking of types, inferences, etc. This helps in making the transition from writing code for the compiler, to writing code with the compiler. How this has benefited my view of D: Think about the overall system as a series of composable components that have predictable behaviour. Think about the details of each component and how you can verify the output. Think about the base-case and the special-case when creating a procedure. Use the syntax to help the compiler understand what your intent is. D helps with: * uniform function syntax * templates * guards * contracts: in, out, body * built in unittest * compile time assertions, conditionals, expressions In closing, I don't think Haskell is meant to make you a better programmer by flexing your higher-order function manipulation or using FP idioms in an OOP/imperative context. It's strength, at least for me, has been the thought process behind functional programming and how to apply its view of data to your programming language.
Dec 26 2012
Aquiles:When you are forced to think recursively you have to think of your base cases, your invariants, your pre and post conditions, and how you get from x[k] -> x[k+1] without violating your contract. Again it encourages deliberate design as opposed to empirical exploration.A solution here is to think about loop pre-condition, invariant and variant, instead of throwing all loops away to replace them with recursions. Time ago I have suggested to enhance D contract programming a bit, allowing the invariant {} statement in the middle of loops. Formally this adds nearly nothing over using a nested scope {... assert(...);} but it makes more explicit to the code reader what's in that part of the code, and it guides the mind of the code writer in thinking about invariants. So in the end it seems worth a little enhancement request. Bye, bearophile
Dec 26 2012
I have learned Haskell during my bachelor's degree and I cannot say it has made a big difference for me, although I do understand why people like the concepts of it. Recently, I was suggested by a professor to re-learn it. He suggested me so because I was making a presentation on how to extend the standard library of my university's pet language NIT, which is pure object oriented. Apparently, he thought that my additions were influenced by the functional paradigm. Therefore, following his suggestion, I re-learned Haskell and tried to implement my master's project in it, to sort of test it out. I was pleased because Haskell: -Emphasizes more on formalism than actual machine code algorithms -Abstract much of the machine oriented concepts in the favor of more mathemathical ones -The resulting code CAN BE much, much more lightweight I was displeased because: -When it comes to IO, you have to work harder, and IO it is for real world applications -IO and mutable states also include a whole bunch of complicated data structures /algorithms which are just a pain to implement in Haskell compared to machine oriented languages So I just abandoned the idea (I used complicated data structures). I think what Bearophile said sums it up the best: It's really a matter of what is the problem you and how you are planning to solve it. Sometimes a paradigm fits best, sometimes its a burden. Sometimes a language is better, sometimes it isn't. Most of the times, I find extensions of procedural languages to be the best answers. And this is why I love D. Power, flexibility, support for A LOT of paradigms with the right amount of compromises. Describing the language features and comparing it to others just don't show how great it is. D starts to shine when you actually program something complicated in it. Often, when using D, I found myself thinking: "Oh! I can do that, sweet!", rather than: "Oh! I can't do that, right... So how to I workaround it...". Some people think that the "working around it" is the true benefit of functional languages, and there are times when they are right, and there are times when they aren't. In conclusion I'd say that yeah, maybe Haskell can make you a better programmer, but maybe it won't change a thing. Incorporating many concepts and paradigms and knowing when which is best, that is the true challenge: not being forced to use one for everything. So maybe Haskell will help you understand functional paradigm, and that is what's great about it. But, IMHO, when you construct a huge software using multiple inputs/outputs/data structures/arcane algorithms/..., the functional paradigm might get in your way...
Dec 26 2012
On Wednesday, 26 December 2012 at 18:02:42 UTC, Phil Lavoie wrote:Often, when using D, I found myself thinking: "Oh! I can do that, sweet!", rather than: "Oh! I can't do that, right... So how to I workaround it...". Some people think that the "working around it" is the true benefit of functional languages, and there are times when they are right, and there are times when they aren't.That is exactly my methodology to find ICE. The problem is that usually try to accomplish something in the process.
Dec 26 2012