# [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 (\$)
is:
(\$) = 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