Talk:Haskell/Variables and functions

#haskell brainstorming notes 2006-07-08
DH: Firstly I think we should rip out that stuff about tail recursion. It's much to in-depth for that level.

DH: A better introduction wouldn't spend so much time talking about how to emulate other languages.

DH: I know newcomers struggle with the lack of loops -- I did -- but I don't think that's sufficient reason to dedicate the entire 'Basic concepts' chapter to overcoming it.

EYK: i think it would be fair to write this book as if the reader has never programmed before


 * Yes, thank you so much for making this not dependent on learning other programming! It is not great to force everyone to learn a different technique just to unlearn it when then doing functional. Backfromquadrangle (discuss • contribs) 09:39, 15 November 2013 (UTC)

DH: And I think we should have a whole chapter on types.

DH: I think the main faults of that page are: A better introduction wouldn't spend so much time talking about how to emulate other languages.
 * 1) Bad focus on what Haskell's about
 * 2) Assumes too much of the reader (recursion, types).

DH: Perhaps we could change this into a brief chapter explaining the _very_ basics -- arithmetic and so forth, before outlining the rest of the book, or at least the rest of the first section of the book

EYK: a brief romp through the interpreter? try this! now see what happens what you try that?

Functions with functions
SH: I hope it wasn't out of place but in reading through this introductory chapter I decided to add an example of calling a functionwithin another function (assuming this was the intended meaning of the section. I'm by no means a haskell programmer so if something was amiss please change it and let me know.


 * Most excellent! You read our minds exactly -- Kowey 09:44, 11 July 2006 (UTC)


 * I've added an exercise for various-parameter functions and also an exercise for reusing a previously written function, both related. Is that ok ? -- Pupeno 16:23, 4 November 2006 (UTC)


 * Thanks for that. Looks good to me.  There might be some stuff from Haskell/YAHT we should steal as well -- Kowey 17:54, 4 November 2006 (UTC)

Bug in "area" exercise
The code doesn't work as stated... since "area 5" multiplies a real and integer. One could use "area 5.0" or amend the discussion to include this problem. (Since it was discussed above)


 * Hi, could you please clarify that with an example? I have tested the code... but I could always be mistaken -- Kowey 16:40, 27 May 2007 (UTC)
 * I am wondering if perhaps he just assumed it? I thought the same thing, wondering why, for example, pi * 5^2 worked.  I did :t r and :t 5^2 to learn that one was an Integer and one a Num, which made me feel a little better.  But it might be worth pointing out.  Perhaps if I was bolder, like you're supposed to be with wiki, I would just do it, but I'm a total haskell newbie. -- Msouth 03:53, 15 July 2007 (UTC)
 * I added a note. I am a newbie, so someone please clarify/correct. -- Msouth 04:30, 15 July 2007 (UTC)


 * Ack! Now I see the problem (thanks). It looks like I've accidentally stumbled across the dreaded Monomorhpism restriction (sort of your explanation).  It means my initial explanation of (pi * r) isn't quite right.  But then again, I don't think I want to get into that restriction right now because it's scary sounding. Will have to think about this -- Kowey 04:50, 15 July 2007 (UTC)
 * (by the way, I've just posted an article about this on my blog) -- Kowey 06:26, 15 July 2007 (UTC)


 * Hi Msouth, I have added an improved explanation in the Types section just above this "area" exercise. It has not been vetted by the Haskell community yet, but maybe you should have a look and see what you think -- Kowey 12:00, 19 July 2007 (UTC)

What does this sentence mean?
"Informally, the r in let r = 0 is true when you are in the top level of the interpreter". It's "true"? Like a true boolean? I don't understand this sentence, what it's telling me, what the top level of the interpreter is, etc.-- Msouth 04:37, 15 July 2007 (UTC)


 * I have removed the offending text. I don't know what it means either.  Definitely not true like true boolean, though.  Thanks! -- Kowey 06:33, 15 July 2007 (UTC)

Solutions to problems
Where are the answers for these supposed to be? For example, I'm pretty sure "cylinder b h = (pi * (b ^ 2)) * h" is a valid answer, but how do I check?


 * Yeah, that's an anonying part of this book; we haven't worked out all the solutions yet. I think it would be fair to put them all in a subpage; e.g. Haskell/Solutions/Variables and functions -- Kowey 07:29, 7 February 2007 (UTC)

Beginner Insight
This may be beginner's insight, or it may just be that I'm an idiot but:

Prelude> let pi = 3.14159265358979323846264338327950 Prelude> let area r = pi * r ^ 2 Prelude> area 5

...wait a sec- I thought we weren't allowed to multiply an integer by a double? The area function does though?

- Elin


 * Thanks for that. There's a somewhat tricky technical explanation behind this that I had tried to make clearer (see the discussion above).  Well, I've had another go at it (in the paragraph above).  Hopefully it is a little better.  The basic idea is that numbers like   can actually be either integers, doubles or something else.  Usually, the type is inferred from the context, but in some situations, for example, when you just say something like , there is no context.  Haskell has to assign a type to it, so it defaults to  .  However, in  , we know that   expects a double as input, so Haskell can infer that the   should be treated as a double.  Hope that helps.  -- Kowey 17:30, 28 July 2007 (UTC)

Truncation
"Don't worry about all those missing digits; they're just skipped when displaying the value. All the digits will be used in any future calculations."

Prelude> let pi = 3.14159265358979323846264338327950 Prelude> pi - 3.141592653589793238462643 0.0

كсηפ Cyp 20:00, 1 September 2007 (UTC)

Hum ... I get Prelude> pi - 3.141592653589793 0.0 Prelude> pi - 3.14159265358979 3.1086244689504383e-15 Prelude> (pi - 3.141592653589793)*1000000000000000 0.0 The middle output showed me that a lot of digits were still there, so perhaps the first output was just being, y'know, truncated. So I tried to get these digits with the last output, but that failed. Then I noticed one other thing: most of the digits in the middle output are simply wrong!

Actually, since Haskell is a lazy language, I (a mathematician, not a computer programmer) don't understand why we need to bother with all this Float nonsense (where we pretend that a real number has only finitely many digits, and we just try to make sure that we have more digits than anybody will really need). Shouldn't a lazy language simply calculate the digits we need when we want them?

—Toby Bartels (talk) 18:08, 16 November 2008 (UTC)


 * There are of course ways to do arbitrary precision calculations, but the  and   types are the standard IEEE floating point numbers. Execution speed and all that.
 * -- apfe&lambda;mus 10:14, 17 November 2008 (UTC)

"let" syntax in Hugs?
"If this command does not work, you are probably using hugs instead of GHCi, which expects a slightly different syntax."

I don't suppose anyone would like to tell readers just what the Hugs syntax is, would they? A quick search did not turn up anything. --75.15.138.149 15:39, 16 September 2007 (UTC)

Hugs can only evaluate expression, which means that you cannot bind variable across multiple prompt lines. Other than that, normal let expression work, of course. > let x = (1+2) in x*x 9 But you can't use this x in the next line. I filed a feature request for Hugs. -- apfe&lambda;mus 06:55, 17 September 2007 (UTC)

variables that don't change
I know that programmers are used to variables for names that are assigned to numbers, strings, and other data structures. But if I understand correctly so far, Haskell variables are not allowed to vary, which makes for a rather odd use of the term. I think it was probably better off to stick with the term symbol.


 * Well, the standard term is variable, we can't just change it to symbol I'm afraid.
 * Also note that the mutable variables (imperative) programmers are used are much younger than the variables that have been used in mathematics for centuries and which work just like the Haskell ones. They still "vary" in the sense that they are a placeholder for a variety of values, it's just that they don't change once they are in scope.
 * -- apfe&lambda;mus 08:57, 7 December 2008 (UTC)


 * Can't agree. Even imperative programmers see 'symbol' every day in the compiler errors. I'd be very surprised to see the word 'variable' in any Haskell book/article/post. Don't see any point to give the beginners this misconception.
 * It is not a misconception. The Haskell Report uses "variable" in this sense. A variable is a named location in memory. Variables need not be changeable; "constant variable" is not an oxymoron. (That being so, I have reverted your edit regarding .) --Duplode (discuss • contribs) 17:20, 20 November 2018 (UTC)
 * I think there is a piece of Murphy's Law about programming that says something like "Constants aren't; variables won't". Haskell solved this problem by making the "variables" becoming constants :-) I wonder if there is a way to insert Murphy's Law into this book :-))))))))) Albmont (talk) 17:52, 31 December 2009 (UTC)


 * Go ahead! :D This particular variations "Variables won't; constants aren't." seems to be called "Osborn's law".
 * -- apfe&lambda;mus 10:16, 1 January 2010 (UTC)

I think that "areaRect l w = l * w" and "areaSquare s = areaRect s s" is a good place to explain that we aren't setting s or l or w as some permanent variable to be used again, it's just placeholders for that precise function definition, hence why s can be substituted for l and w. Does that make sense? Backfromquadrangle (discuss • contribs) 09:39, 15 November 2013 (UTC)


 * That does make sense, though the chapter already covers that point from a different angle with the section on scope. (By the waythanks for merging the parallel paragraphs there!)--Duplode (discuss • contribs) 21:30, 16 November 2013 (UTC)

Couldn't match expected type
I am using GHCi 6.10.4 from the Hackage Haskell Platform distribution.

When I try:

let r = 25 :: Num a => a 2 * pi * r

From the box on monomorphism restriction, I get:

against inferred type `Integer' In the second argument of `(*)', namely `r' In the expression: 2 * pi * r    In the definition of `it': it = 2 * pi * r

And doing:

let r = 25 :: Num a => a :type r

Gives:

r :: Integer

I'm still trying to figure out why - if it's something I've done wrong then I apologise for this, otherwise you may want to look into it for your book.

Y Less (talk) 12:11, 9 December 2009 (UTC)


 * You have to write the type signature above (before) the binding if you want to a polymorphic value:
 * -- apfe&lambda;mus 11:56, 13 December 2009 (UTC)
 * -- apfe&lambda;mus 11:56, 13 December 2009 (UTC)

Rewrite 2010 May
Rewriting to adhere to new structure. Old text here:. -- apfe&lambda;mus 19:46, 15 May 2010 (UTC)

Allowed variable names
"Variables must begin with a lowercase letter, but for the rest, any string consisting of letter, numbers, underscore (_) or tick (') is allowed." Actually, the allowed names of variables are both more and less restrictive than described. Perhaps this link should be provided? http://www.haskell.org/onlinereport/haskell2010/haskellch2.html#x7-180002.4 --M0davis (discuss • contribs) 03:05, 28 October 2012 (UTC)

Pyramids of Giza problem
Why is it even here? It makes use of both conditions and recursivity, none of which have been introduced yet. It also makes a poor effort explaining what the input and output are supposed to be (pyramid volume? base size? brick size?).


 * The proposed recursive solution was a bad fit, indeed; I replaced it with something more appropriate for the context. The lack of guidance about initial assumptions is something to consider, too --Duplode (discuss • contribs) 21:17, 16 November 2013 (UTC)

meaning of "local and top-level definitions"
in this section, it's fairly unclear to me what a top-level definition is. (my prior programming experience tells me a local definition would be those under the 'where' statement.) my only guess is that a tld refers to the first line of a definition of a funtion which is anything other than the value of a local variable, i.e. some expression. unfortunately, that isn't very clear without trying to eliminate possibilities of meaning, and i'm still not certain i got it right. it would be great if those definitions were explicit. thanks! Sudozero (discuss • contribs) 04:47, 27 June 2014 (UTC)

argument vs. parameter clarity
starting in this section, arguments and parameters are not destinguished, however they are not the same. often people use them interchaneably without much trouble. i'm not sure if the two words are commonly blended in the haskell community, but i've found use of the word 'parameter' in other haskell contexts by using a search engine.

in the following sections i've read, the word 'argument' tends to be used for both meanings. this could lead to some confusion or false statements. it may be a good idea to distinguish them briefly in this section, then go through the book to replace occurences of 'argument' with 'parameter' wherever it's technically correct.

-- Sudozero (discuss • contribs) 14:52, 5 July 2014 (UTC)

Problem in "subtract" example on Multiple parameters section
Dear all,

I would like to warn that the subtract example in the "Multiple parameters" section is problematic since the reader might try defining the function and running it in GHCi to obtain a warning:

*Main&gt; subtract 10 5 &lt;interactive&gt;:22:1: Ambiguous occurrence ‘subtract’ It could refer to either ‘Main.subtract’, defined at Varfun.hs:9:1 or ‘Prelude.subtract’, imported from ‘Prelude’ at Varfun.hs:1:1 (and originally defined in ‘GHC.Num’)

Maybe the book should change the subtract function name to mysubtract?

Fooliu (discuss • contribs) 14:39, 25 December 2014 (UTC)