Pointers in Idris

Idris supports pointers, allowing you to pass references to values and records within your program. However, the implementation is different from traditional languages due to Idris’ strong type system and functional nature.

We’ll show how pointers work in contrast to values with two functions: zeroval and zeroptr. zeroval has an Int parameter, so arguments will be passed to it by value. zeroval will get a copy of ival distinct from the one in the calling function.

zeroval : Int -> IO ()
zeroval ival = putStrLn $ "Value inside zeroval: " ++ show ival

zeroptr in contrast has a Ptr Int parameter, which is Idris’ way of working with pointers. We use the poke function to modify the value at the memory address.

zeroptr : Ptr Int -> IO ()
zeroptr iptr = do
  poke iptr 0
  putStrLn "Value set to 0 via pointer"

Here’s how we use these functions:

import Data.IORef

main : IO ()
main = do
  i <- newIORef 1
  putStrLn $ "initial: " ++ show !(readIORef i)

  zeroval !(readIORef i)
  putStrLn $ "after zeroval: " ++ show !(readIORef i)

  zeroptr !(prim__readPtr i)
  putStrLn $ "after zeroptr: " ++ show !(readIORef i)

  putStrLn $ "pointer: " ++ show (prim__readPtr i)

In this example, we use IORef to create a mutable reference, which is Idris’ safer alternative to raw pointers. The ! operator is used for extracting values from IO actions.

When you run this program, you’ll see that zeroval doesn’t change the i in main, but zeroptr does because it has a reference to the memory address for that variable.

$ idris -o pointers pointers.idr
$ ./pointers
initial: 1
Value inside zeroval: 1
after zeroval: 1
Value set to 0 via pointer
after zeroptr: 0
pointer: 94046814777344

Note that the actual pointer value will be different on your machine.

In Idris, direct manipulation of pointers is discouraged due to safety concerns. The language provides safer abstractions like IORef for mutable state. However, when interfacing with low-level code or for performance-critical operations, Idris does provide mechanisms to work with raw pointers, as demonstrated in this example.