7

I'm trying to figure out if Haskell uses dynamic or static scoping. I realize that, for example, if you define:

let x = 10

then define the function

let square x = x*x

You have 2 different "x's", and does that mean it is dynamically scoped? If not, what scoping does it use, and why?

Also, can Haskell variables have aliases (a different name for the same memory location/value)?

Thanks.

Sev
  • 15,401
  • 9
  • 56
  • 75
  • 2
    BTW, Sev, you might want to reconsider whether you still want to keep igorgue's answer as the accepted one for this question, given that it's been proven wrong on the aliasing point (see the answer below) and, while there's argument about it, he can't come up with any argument that he's not wrong on the variables point. – cjs Jun 15 '09 at 08:11

9 Answers9

17

Haskell use (broadly speaking) exactly the same lexical scoping as most other languages.

eg.

x = 10

Results in a value referenced through x in the global scope, whereas

square x = x * x

will result in x being lexically scoped to the function square. It may help if you think of the above form being a syntactic nicety for:

square = \ x -> x * x

As to your other question i'm not sure what you mean by aliasing

olliej
  • 35,755
  • 9
  • 58
  • 55
7

Answering only the second part of the question:

You can have several aliases for the same "memory location", but since they are all immutable, it does not matter most of the time.

Dumb example:

foo x y = x * y
bar z = foo z z

When within foo called from bar, both x and y are clearly the same value. But since you cannot modify either x or y, you will not even notice.

CesarB
  • 43,947
  • 7
  • 63
  • 86
6

There are some things wrong in your statements...

  • There are no mutable variables in Haskell just definitions (or immutable variables)
  • A variable memory location is a concept that do not exist in Haskell

In your example, x is not 10 in the function is just a argument to square, that can take any value (you can specify the type later) in this case 10 but just in this case.

Here is an example of aliases provided by Curt Sampson:

import Data.IORef

main :: IO ()
main = do x <- newIORef 0         -- write 0 into x
          readIORef x >>= print   -- x contains 0
          let y = x
          readIORef y >>= print   -- y contains 0
          writeIORef x 42         -- write 42 into x
          readIORef y >>= print   -- y contains 42
Community
  • 1
  • 1
igorgue
  • 17,884
  • 13
  • 37
  • 54
  • 6
    Certainly Haskell has variables. See http://stackoverflow.com/questions/993124/does-haskell-have-variables/993126 – cjs Jun 14 '09 at 16:17
  • 3
    no, it doesn't have variables!, "definitions" is the right term, or if you like calling them variables, then are immutable variables just like in Erlang. Still this is very different from the imperative concept of "variables". – igorgue Jun 14 '09 at 21:29
  • 3
    igorgue, if you believe that Haskell doesn't have variables, please post an answer to the question linked above telling us why it doesn't. Do include the "definition" of `x` in `f x = x * 2`. – cjs Jun 15 '09 at 01:31
  • As far as aliases go, I have provided a new answer to this question demonstrating aliasing in Haskell. – cjs Jun 15 '09 at 01:44
  • 1
    I'm not sure what you mean by "variable memory location." If you're talking about mutable memory locations, you go on to give an example of exactly that in Haskell. If you're talking about "variables," that's a binding of a name to a value that varies over a range; memory locations are irrelevant. (You'll note that mathematical equations have variables, but no memory locations.) – cjs Jun 17 '09 at 03:52
  • Additionally, I don't the the question ever claimed that there are mutable variables in Haskell. – cjs Jun 17 '09 at 03:57
  • I meant that you don't think of a variable's memory location – igorgue Jun 17 '09 at 18:57
  • 1
    "A variable memory location is a concept that does not exist in Haskell"... uh, I don't see why variables in Haskell cannot live in a memory location. They simply are read-only. Now if you mean that memory locations are themselves variable, and Haskell does not support that, okay, but I don't know of ANY language that supports that. And I think your term of "definition" is bad. Are function parameters definitions? I think not. They are variables. They /vary/ between calls. Bone up on some math: http://en.wikipedia.org/wiki/Variable_%28mathematics%29 – Thomas Eding Sep 23 '10 at 17:49
  • 1
    Variables vary by the value with which they are instantiated. – Christopher Done Mar 21 '13 at 22:15
  • @ThomasEding C variables have a pointer which refers to the memory location, you can change this to point to somewhere else. The question implies that the author believes that 'x' is a variable that is to say it has a memory address which can be changed. This is not the case in Haskell for regular definitions. They do not vary between calls, a new instance is created in a new scope. You are clearly coming from a mathematics background, which is cool, but unimportant with respect to the vernacular of software development. – VoronoiPotato Oct 24 '13 at 20:52
3

As the first part of the question is already answered by others, here is the second part:

I assume by aliasing you mean one name for another. As haskell is a functional language, and functions behave as normal identifiers in any case, you can do that like this:

y = x

which would define an alias y for the function x. Note that everything is a function. Even if it looks like a "variable", it's just a nullary function taking no arguments. Aliases for types look like this:

type Function = Double -> Double

which would define an alias Function for the type Double -> Double

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
  • 1
    "a nullary function taking no arguments" — I'd just point out that these comments don't hold true in the case of unlifted values. – porges Jun 14 '09 at 13:15
2

In your example, the global definition of x is shadowed by the local definition of x. In Haskell, a variable's scope is determined by a static reading of the source code - this is called lexical scope, but can get something similar to dynamic scoping with implicit parameters (but that can lead to some unexpected behavior (I've read; never tried 'em myself)).

cjs
  • 25,752
  • 9
  • 89
  • 101
ja.
  • 4,245
  • 20
  • 22
2

Haskell uses static nested scopes. What is a bit confusing compared with other languages that have static nested scopes is that the scope of a name is a block which includes tests preceding its definition. For example

evens = 0 : map (+1) odds
odds  = map : (+1) evens

here the name 'odds' is in scope in the definition of 'evens', despite the surprising fact that 'odds' has not yet been defined. (The example defines two infinite lists of even and odd numbers.)

A dead language with a similar scoping rule was Modula-3. But Haskell is a bit trickier in that you can attempt to 'redefine' a variable within the same scope but instead you just introduce another recursion equation. This is a pitfall for people who learned ML or Scheme first:

let x = 2 * n
    x = x + 1   -- watch out!

This is perfectly good ML or Scheme let*, but Haskel has scheme letrec semantics, without the restriction to lambda values. No wonder this is tricky stuff!

Norman Ramsey
  • 198,648
  • 61
  • 360
  • 533
  • Err...I think you mean that the scope "includes other definitions following the definition," or something like that, don't you? – cjs Jun 17 '09 at 03:59
  • @Curt: I interpret that he means the scope of the "odds" definition includes the preceding part of the block, where you're interpreting the other way, with the *use* of "odds" is looked up including later definitions. – Fred Nurk Dec 03 '10 at 10:38
  • Is it possible to access local variables outside of the scope where they are declared? – Anderson Green Jan 01 '15 at 20:49
1

To sum up the other answers concisely:

  1. lexical scope
  2. aliasing is as easy as x = 1; y = x but doesn't usually matter because things are immutable.

The let syntax you use in your example looks like it's at the interactive ghci> prompt. Everything in interactive mode occurs within the IO monad so things may appear more mutable there than normal.

Nathan Shively-Sanders
  • 18,329
  • 4
  • 46
  • 56
0

Well, as I think people have said already, Haskell doesn't have any variables as found in most other languages, it only has expressions. In your example let x = 10 x is an expression that always evaluates to 10. You can't actually change the value of x later on, though you can use the scoping rules to hide it by defining x to be another expression.

Magnus
  • 4,644
  • 1
  • 33
  • 49
  • I've tried them, and the behaviour is actually fairly clear, because you need to declare dynamically scoped variables explicitly in the type definition if you use them. – cjs Jun 17 '09 at 04:00
0

Yes, Haskell has aliases. Try out this little program:

import Data.IORef

main :: IO ()
main = do x <- newIORef 0         -- write 0 into x
          readIORef x >>= print   -- x contains 0
          let y = x
          readIORef y >>= print   -- y contains 0
          writeIORef x 42         -- write 42 into x
          readIORef y >>= print   -- y contains 42
cjs
  • 25,752
  • 9
  • 89
  • 101