Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Purpose of {-# #-} in Haskell

Tags:

haskell

I am going through Haskell code to see how I could write similar stream fusion functions and I noticed a funny syntax construct, {-# ... #-}, that I've not come across; so I would like to know what it is and how I can find out how it works:

-- | /O(n)/ Drop elements that do not satisfy the predicate
filter :: Vector v a => (a -> Bool) -> v a -> v a
{-# INLINE filter #-}
filter f = unstream . inplace (MStream.filter f) . stream

More specifically, what does particular line do?

{-# INLINE filter #-}
like image 307
user3199023 Avatar asked Mar 31 '14 22:03

user3199023


People also ask

What are the 4 types of functions?

The types of functions can be broadly classified into four types. Based on Element: One to one Function, many to one function, onto function, one to one and onto function, into function.

What is Euler's constant used for?

An irrational number represented by the letter e, Euler's number is 2.71828..., where the digits go on forever in a series that never ends or repeats (similar to pi). Euler's number is used in everything from explaining exponential growth to radioactive decay.

What does ∘ mean in math?

The ∘ symbol denotes a composite function - it looks similar to the multiplication symbol, ⋅, but does not mean the same thing. (f ∘ g)(x) is the same thing as f(g(x)).

What is function Short answer?

A function is defined as a relation between a set of inputs having one output each. In simple words, a function is a relationship between inputs where each input is related to exactly one output. Every function has a domain and codomain or range. A function is generally denoted by f(x) where x is the input.


2 Answers

GHC has a "pragma" system which allows you to specify extra-linguistic information to GHC. In particular, they look like

{-# <NAME> <ARGS...> #-}

The most common you will see are the language extension pragmas which must go at the top of a file and affect the language extensions in effect for the remainder of the file.

{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Example where

Normally it ought to be that ignoring a pragma does not affect the meaning of the program. This is broadly true for pragmas like INLINE as they are merely hints to the compiler that this function's body should be inlined wherever it is called in order to open up new optimization opportunities. Haskell semantics gives us guarantees about when such inlining transformations do not change the meaning of the program, thus the choice the compiler makes about whether or not to inline has no effect on the meaning of the program (so long as it doesn't violate the assumptions of those guarantees).

The LANGUAGE pragmas are a bit different in that they specify exactly what language is being written in for the rest of the file. For instance, we typically assume the base language is Haskell98 or Haskell2010 and the LANGUAGE pragmas add extensions such that the language of the file with the headed exemplified earlier is

Haskell2010 + RankNTypes + FlexibleInstances + ScopedTypeVariables

but beyond hinting to the compiler which language is being written these pragma have no further meaning.


The full set of allowable pragma depend upon the compiler being used. GHC's pragmas are listed here (note that this link is for version 7.6.3 while the link in the comments is for 7.0.3). Use of pragmas other than LANGUAGE may be sketchy and platform specific, so learn their use and meaning carefully.

For instance, there's a big debate about whether or not library authors should use INLINE as it tends to suggest a lack of faith in GHC's own inlining heuristics and thus that we should spend more effort tightening those up rather than littering code with manual INLINEs. But that said, INLINE and INLINABLE can have profound impact on tight inner loops if used judiciously.

like image 139
J. Abrahamson Avatar answered Sep 27 '22 17:09

J. Abrahamson


It's a pragma. It's basically something not expressible in the language standard itself, but still saying something relevant to the compiler.

Some of these pragmas are essentially optional, just e.g. improve performance, hence the comment-like look. In your example, INLINE means the compiler should try hard to not just link to the function in question, but actually "hard-code" it anywhere it's called. This does not in principle change program semantics, but can have quite an impact on performance and memory usage (in particular if combined with extra stream fusion etc. techniques).

like image 32
leftaroundabout Avatar answered Sep 27 '22 19:09

leftaroundabout