Functional Programming

Programming, for all ages and all languages.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

Yes, pretty much. Except, you can do operations on that array like any normal array. Most of the functions in the Haskell Prelude are designed so that they work just fine on infinite arrays.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

The example of an infinite list of 1s is pretty boring one, since one can implement it in any language like this:

Code: Select all


struct list_of_int { int x; list_of_int * rest; }

list_of_int ones;

ones.x = 1;
ones.rest = &ones;
Because Haskell is pure (that is, no mutations) there is no way to tell the difference.

More interesting stuff can be done. Suppose you want an infinite list of squares (my syntax might be off since I don't know Haskell for real):

Code: Select all

square x = x * x

ints = [1, 2, 3 .. ]

map fn [] = []
map fn [x:xs] = [fn x : map fn xs]

squares = map square ints

Now map is AFAIK defined in prelude so I just included it for the fun of it.

Now, squares is an infinite list of squares, that is [1, 4, 9, 16 ... ] continuing as far as you care to look at it. :)

Also notice how it is possible to avoid explicit conditionals in many cases by relying on pattern matching instead. That is, the version of "map" is selected automatically based on whether second argument is empty or non-empty list.

Ofcourse there's easier way to write that in Haskell, because (AFAIK) you can just as well use so called list-comprehensions:

Code: Select all

squares = [ x * x | x <- [1, 2, 3 ..]]
That basicly says, "let squares be a list of those numbers which you get when you evaluate x*x drawing x from the list of [1, 2, 3 ..]"


Anyway.. the really interesting part of Haskell isn't really that it's lazy or allows list comprehensions, because both of those are pretty easy to implement:
- for lazy evaluation use promises and force them as required, caching values
- for comprehensions, just rewrite then in terms of map and filter (map defined above, filter looking something like:

Code: Select all

filter fn [] = []
filter fn [x:xs] = if fn x
                     then [x : filter fn xs]
                     else filter fn xs
The really interesting part of Haskell instead, is what the type system does for you....
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

Also, [..] is a syntax error:

Code: Select all

<ehird> > [1, 2, 3 .. ]
<lambdabot> Parse error
<ehird> > [1]
<lambdabot> [1]
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

ehird wrote:Also, [..] is a syntax error:

Code: Select all

<ehird> > [1, 2, 3 .. ]
<lambdabot> Parse error
<ehird> > [1]
<lambdabot> [1]
Would it work if one dropped the space? :D

Oh well, I warned about possibly having issues with syntax....
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

[1, 2, 3..] still gives a parse error. :P
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Oh ok, I guess [1..] then, that should work, though I'd have preferred something more verbose for readability. Must have confused with some other similar language.

Haskell grammar is evil anyway... one of the things I dislike about the language.
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

Code: Select all

[19:43] ehird: > [1..]
[19:43] lambdabot: [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,
[19:43] lambdabot: 69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
[19:43] lambdabot: 126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,
[19:43] lambdabot: 175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
[19:43] lambdabot: 224,225,226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,258,259,260,261,262,263,264,265,266,267,268,269,270,271,272,
[19:43] lambdabot: [6 @more lines]
So it does something quite different ;)
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Isn't that exactly what we wanted?
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

[1,2,3,4,succ ad-infinitum] != [1,1,1,1 ad-infinitum] :)
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

fnord
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

the main difference between languages is that some provide features by default that others dont. Lazy evaluation is haskell's feature. Any turing-complete language can be used to build programs with the same behaviour as one haskell program, but it would be tedious. Which is why people use haskell instead :wink:

as for actual code:

list_of_ones = repeat 1
list_of_ones = 1:list_of_ones
list_of_ones = f where f = 1 : f
all_ints = [1]++[2]++[3..]
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

1:2:[3..] is more haskell-y
Post Reply