[Haskell-cafe] What is the role of $!?

Derek Elkins derek.a.elkins at gmail.com
Fri Nov 30 14:55:26 EST 2007

On Thu, 2007-11-29 at 07:29 +0000, Thomas Davie wrote:
> On 29 Nov 2007, at 06:32, PR Stanley wrote:
> > Hi
> > Thanks for the response.
> >
> > 	JCC: In most languages, if you have some expression E, and when the  
> > computer attempts to evaluate E it goes in to an infinite loop, then  
> > when the computer attempts to evaluate the expression f(E), it also
> > goes into an infinite loop, regardless of what f is.  That's the  
> > definition of a strict language.
> >
> > PRS: Does that mean that a strict language is also imperative?
> Nope, not at all.  Just a strict language has slightly fewer programs  
> it can evaluate correctly, as more will loop infinitely.

A -pure- strict language.

> $ does not mean "do lazy evaluation" it means "apply".  It's a  
> function, like any other:
> f ($) x = f x

The syntax for defining an infix operator is:
f $ x = f x -- or
($) f x = f x

The latter form more clearly illustrates something that drives home the
fact that ($) is completely trivial, namely, a third definition for ($)
($) = id

> $! is the special case, which means strictly apply.  It evaluates its  
> argument first, *then* does the application.  This may or may not be  
> faster (and usually isn't, due to evaluating more of the argument):
> f ($!) x = seq x (f x)

Again, f $! x = seq x (f x) -- or x `seq` f x
This is the definition according to the Report.

> seq is a special function that says "first fully evaluate my first  
> argument, then return my second argument", it breaks non-strict  
> semantics.  Personally, my only use for such functions is a little bit  
> of debugging work [...]

seq, or something that forces evaluation, is more important than that
(though I wouldn't mind it being put back in a class.)  E.g. (assuming
no strictness analysis which can't be relied upon to -always- work),
both sum = foldr (+) 0 and sum = foldl (+) 0 will stack overflow on a
large enough input list, while sum = foldl' (+) 0 will not.  The
difference between foldl and foldl' is that, via seq, foldl' is a bit
more strict.

More information about the Haskell-Cafe mailing list