Idris Programming Language

Purely Functional Programming

C. L. Beard
OpenSourceScribes
5 min readNov 11, 2023

--

Midjourney prompt >> Idris programming language

Idris is a purely-functional programming language with dependent types, optional lazy evaluation, and features such as a totality checker. It is designed to be a general-purpose programming language similar to Haskell, but it may also be used as a proof assistant. In Idris, types are first-class constructs in the language, which means they can be passed as arguments to functions and returned from functions just like any other value, such as numbers, strings, or lists. This enables relationships to be expressed between values, assumptions to be made explicit and checked by the compiler, and properties of program behavior to be formally stated and proven.

Idris is named after a singing dragon from the 1970s UK children’s television program Ivor the Engine. It is influenced by Agda, Clean, Coq, Epigram, F#, Haskell, ML, and Rust. The syntax of Idris shows many similarities with that of Haskell.

Idris 2 is a core language based on “Quantitative Type Theory” which allows explicit annotation of erased types and linear types. It is mostly backward compatible with Idris 1, with some minor exceptions.

There are several resources available for learning and using Idris, including the official website, mailing list, GitHub repository, and Discord and IRC channels. However, it is unclear whether Idris is used for any production-grade software.

Idris has several advantages for programming, including:

1. Type-driven development: Idris is designed to encourage type-driven development, where types are tools for constructing programs. In Idris, types are first-class constructs in the language, which means they can be passed as arguments to functions and returned from functions just like any other value. This enables relationships to be expressed between values, assumptions to be made explicit and checked by the compiler, and properties of program behavior to be formally stated and proven.

2. Dependent types: Idris has dependent types, which allow types to depend on values. This means that types can be more precise and expressive, and the compiler can catch more errors at compile-time.

3. Purely-functional: Idris is a purely-functional programming language, which means that it avoids side effects and mutable state[1][5]. This makes it easier to reason about programs and to write correct and maintainable code.

4. Optional lazy evaluation: Idris has optional lazy evaluation, which means that expressions are only evaluated when they are needed. This can improve performance and enable more expressive programming styles.

5. Totality checker: Idris has a totality checker, which can verify that functions terminate for all possible inputs. This can help prevent infinite loops and other runtime errors.

6. Proof assistant: Idris can also be used as a proof assistant, which means that it can be used to prove mathematical theorems and verify the correctness of programs.

7. Program search capabilities: Idris 2 has excellent program search capabilities, and using linear annotations makes this even better.

Overall, Idris is a powerful and expressive programming language that can help developers write more correct and maintainable code, and can also be used as a proof assistant for mathematical proofs and program verification.

What is the Difference Between Type Interface and Type Annotation

In Idris, type inference is the process of automatically determining the type of an expression based on its context, while type annotation is the process of explicitly specifying the type of a variable or function. Idris requires type declarations for all functions, using a single colon : (rather than Haskell’s double colon :: ). While Idris does not have full type inference, it does infer types within the body of functions. However, all types must be annotated explicitly in source code.

A limited form of type inference is possible in practice using Idris’s interactive tools. For the parts of the program that do not have type annotations, they can be type inferred with a Hindley-Milner (HM) inference algorithm, and if it succeeds, great, but if it fails, a type error is signaled. Doing type inference for non-HM-typeable parts of programs is theoretically simple, but it has not been done likely due to a combination of reasons such as not being publishable, being a lot of work, and type inference not being that important, especially if it is only done for the HM-typeable fragment.

What are Dependent Types in Idris

Dependent types in Idris are types that can depend on values. In conventional programming languages, there is a clear distinction between types and values, but in a language with dependent types, the distinction is less clear. Dependent types allow types to be a first-class language construct and to be manipulated like any other value.

The standard example of dependent types is the type of lists of a given length, Vect n a, where n is a natural number and a is the type of the elements in the list. Dependent types can be used to express more precise and expressive types, and the compiler can catch more errors at compile-time. Dependent types can also be used to write proof-carrying code and to ensure program correctness. In Idris, types are first-class constructs in the language, which means they can be passed as arguments to functions and returned from functions just like any other value.

For more on this you can check out the book Introduction to Dependent Types with Idris.

I read the book Gentle Introduction to Dependent Types with Idris which is now out of print.

Some examples of dependent types in Idris include:

1. Vect: Vect is a type of lists of a given length, where the length is a natural number and the type of the elements in the list is specified. For example, Vect 3 Int is a type of lists of length 3, where each element is an integer.

2. Dependent pairs: Dependent pairs are pairs of values where the type of the second value depends on the value of the first. Dependent pairs can be used to construct other dependent types. For example, DPair a P is a dependent pair where a is a value of type a and P is a function that takes a value of type a and returns a type.

3. Sized types: Sized types are types that depend on a size parameter, which can be used to ensure that certain operations are well-defined. For example, a sized type for matrices could ensure that matrix multiplication is only performed on matrices of compatible sizes.

4. Type-level programming: Idris allows for type-level programming, where types can be manipulated like values. This can be used to define complex dependent types and to write proof-carrying code.

Overall, dependent types in Idris allow for more precise and expressive types, and can be used to catch more errors at compile-time and to ensure program correctness.

--

--

C. L. Beard
OpenSourceScribes

I am a writer living on the Salish Sea. I also publish my own AI newsletter https://brainscriblr.beehiiv.com/, come check it out.