Let us consider the following haskell program :
g::Int
g = 300
func::Int->Int
func arg = arg + g
main = do
print (func 4)
I don't particularly like this program because "func" is using the global variable g in its computation, and I would like to aim that all functions written in my program specify as arguments all the elements needed to perform the necessary computations (i.e. nothing outside the function is used).
My question is this : is there any way to get ghc to reject functions which use variables not defined in the argument list? (rather than having to rely on pure discipline)...
[EDIT] : Also consider the following :
main.hs :
import MyMod
func::Int->Int
func arg = arg + g
main = do
print (func 4)
MyMod.hs
module MyMod where
g::Int
g = 300
[EDIT2] : I guess that if functions could only use variables defined in the argument list then one would have to make exceptions (?) for things like :
g::Int
g = 300
h::Int
h = 400
i::Int
i = g + h
[EDIT3] : For n.m. in response to "Try writing a complete program with these restrictions that has more than one function" (the restriction being that functions can only use variables declared in their argument list). Ofcourse there has to be exceptions and in this case the main is the exception. This example was adapted from Comparing speed of Haskell and C for the computation of primes
divisibleRec :: Int -> Int -> Bool
divisibleRec i j
| j == 1 = False
| i `rem` j == 0 = True
| otherwise = divisibleRec i (j-1)
divisible::Int->(Int -> Int -> Bool)-> Bool
divisible i fn= (fn i (i-1))
main :: IO()
main = print(length([ x | x <- [2..1000], (divisible x divisibleRec) == False]))
[EDIT 4] : In regards to the program in EDIT3, recursive usage as in divisibleRec would also have to be an exception, since the inside "divisibleRec" is not fed as an argument to the function.
Also this rule becomes unmaintainable when we chain many functions together. In the program above it was not too bad, we just had "divisible x divisibleRec", but as we have bigger programs the scheme above become unmaintainable since we effectively have to chain all the functions in one place....
[EDIT 5] : When I originally posted this question, I was viewing functions and variables on a different level. However when you treat functions on the same level as variables, so that the restriction "all functions written in my program specify as arguments all the elements needed to perform the necessary computations (i.e. nothing outside the function is used)" means that functions which use other functions must be passed these other functions as arguments, then the whole approach becomes unmaintainable for the reasons mentioned in Edit4.