What does the "!n" mean?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
5 messages Options
Reply | Threaded
Open this post in threaded view
|

What does the "!n" mean?

John M. Dlugosz
I'm reading http://www.haskell.org/haskellwiki/IO_inside#inlinePerformIO and it shows a
passage of code:

write :: Int -> (Ptr Word8 -> IO ()) -> Put ()
write !n body = Put $ \c buf@(Buffer fp o u l) ->
   if n <= l
     then write' c fp o u l
     else write' (flushOld c n fp o u) (newBuffer c n) 0 0 0

   where {-# NOINLINE write' #-}
         write' c !fp !o !u !l =
           -- warning: this is a tad hardcore
           inlinePerformIO
             (withForeignPtr fp
               (\p -> body $! (p `plusPtr` (o+u))))
           `seq` c () (Buffer fp o (u+n) (l-n))

I got as far as the second line, looking things up in this index
<http://hackage.haskell.org/package/base-4.6.0.1/docs/doc-index.html>

But ?write !n body = ??
I understand write is defined to be a function taking an Int and another function,
but what does !n mean?  I went through the 2010 Report (BTW, the PDF is useless for
searching for the ! character so I used the HTML version page-by-page) and found it used
as a modifier for named record fields (it says "strict" but I think it's describing
non-optional).
Then I went through the GHC users guide for language extensions, and found a reference in
?7.2.1 without explanation but as an example where the difference between
        f x = let (Foo a b, w) = ..rhs.. in ..body..
and f x = let !(Foo a b, w) = ..rhs.. in ..body..
is "you must make any such pattern-match strict".
Strict pattern matching is not mentioned elsewhere nor is it in the Haskell Report, so
what am I missing?  I suspect that the usage I'm asking about is related.

The GHC users guide also mentions it again in ?7.4.6 which I think is a reference to the
same feature, ?You can use strictness annotations, in the obvious places in the
constructor type? but that's for use with a completely different extension (GADT types)

I also recognize the ?@? mark as naming the entire variable rather than just the parts of
the pattern matched, but ?buf? is not actually used anywhere, so does it mean something
different, or has other effects, or what?

Thanks in advance,
?John


Reply | Threaded
Open this post in threaded view
|

What does the "!n" mean?

Mateusz Kowalczyk
On 27/03/14 01:15, John M. Dlugosz wrote:

> I'm reading http://www.haskell.org/haskellwiki/IO_inside#inlinePerformIO and it shows a
> passage of code:
>
> write :: Int -> (Ptr Word8 -> IO ()) -> Put ()
> write !n body = Put $ \c buf@(Buffer fp o u l) ->
>    if n <= l
>      then write' c fp o u l
>      else write' (flushOld c n fp o u) (newBuffer c n) 0 0 0
>
>    where {-# NOINLINE write' #-}
>          write' c !fp !o !u !l =
>            -- warning: this is a tad hardcore
>            inlinePerformIO
>              (withForeignPtr fp
>                (\p -> body $! (p `plusPtr` (o+u))))
>            `seq` c () (Buffer fp o (u+n) (l-n))
>
> I got as far as the second line, looking things up in this index
> <http://hackage.haskell.org/package/base-4.6.0.1/docs/doc-index.html>
>
> But ?write !n body = ??
> I understand write is defined to be a function taking an Int and another function,
> but what does !n mean?  I went through the 2010 Report (BTW, the PDF is useless for
> searching for the ! character so I used the HTML version page-by-page) and found it used
> as a modifier for named record fields (it says "strict" but I think it's describing
> non-optional).
> Then I went through the GHC users guide for language extensions, and found a reference in
> ?7.2.1 without explanation but as an example where the difference between
> f x = let (Foo a b, w) = ..rhs.. in ..body..
> and f x = let !(Foo a b, w) = ..rhs.. in ..body..
> is "you must make any such pattern-match strict".
> Strict pattern matching is not mentioned elsewhere nor is it in the Haskell Report, so
> what am I missing?  I suspect that the usage I'm asking about is related.
>
> The GHC users guide also mentions it again in ?7.4.6 which I think is a reference to the
> same feature, ?You can use strictness annotations, in the obvious places in the
> constructor type? but that's for use with a completely different extension (GADT types)

It is in fact a strictness annotation which forces ?n? when matching on
it. It is an optimisation technique and if you're just starting out, I
would not worry about it too much. I would advise against putting those
on if you're not sure about the implications as they can make your
performance worse. GHC can in fact often add those itself.

I don't have any official reading for you but if you simply search for
?Haskell strictness? online, you should get quite a few links to Haskell
wiki, the Wikibook, Stack Overflow and some blogs.

> I also recognize the ?@? mark as naming the entire variable rather than just the parts of
> the pattern matched, but ?buf? is not actually used anywhere, so does it mean something
> different, or has other effects, or what?

It just seems that someone gave it a name and then didn't use it. It
does not have any extra meaning.

>
> Thanks in advance,
> ?John
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>


--
Mateusz K.

Reply | Threaded
Open this post in threaded view
|

What does the "!n" mean?

Brent Yorgey-2
In reply to this post by John M. Dlugosz
On Wed, Mar 26, 2014 at 08:15:07PM -0500, John M. Dlugosz wrote:

> I'm reading
> http://www.haskell.org/haskellwiki/IO_inside#inlinePerformIO and it
> shows a passage of code:
>
> write :: Int -> (Ptr Word8 -> IO ()) -> Put ()
> write !n body = Put $ \c buf@(Buffer fp o u l) ->
>   if n <= l
>     then write' c fp o u l
>     else write' (flushOld c n fp o u) (newBuffer c n) 0 0 0
>
>   where {-# NOINLINE write' #-}
>         write' c !fp !o !u !l =
>           -- warning: this is a tad hardcore
>           inlinePerformIO
>             (withForeignPtr fp
>               (\p -> body $! (p `plusPtr` (o+u))))
>           `seq` c () (Buffer fp o (u+n) (l-n))
>
> I got as far as the second line, looking things up in this index
> <http://hackage.haskell.org/package/base-4.6.0.1/docs/doc-index.html>
>
> But ?write !n body = ??
> I understand write is defined to be a function taking an Int and another function,
> but what does !n mean?  I went through the 2010 Report (BTW, the PDF
> is useless for searching for the ! character so I used the HTML
> version page-by-page) and found it used as a modifier for named
> record fields (it says "strict" but I think it's describing
> non-optional).

No, strict does not mean optional vs. non-optional.  It has to do with
lazy evaluation.  In Haskell, by default, expressions are not
evaluated until their value is actually needed. Making something
strict means (to a first approximation) forcing it to be evaluated
right away, whether its value will be needed or not.  That is what all
the exclamation points mean, both in the code you cited above and the
examples you found; they can be used in a bunch of different contexts
but they always have to do with strictness.

Incidentally, that "IO inside" page is not particularly what I would
recommend for beginners to read!  It's like learning about spark plugs
and oil filters on your first day of driving school.

> I also recognize the ?@? mark as naming the entire variable rather
> than just the parts of the pattern matched, but ?buf? is not actually
> used anywhere, so does it mean something different, or has other
> effects, or what?

Nope, you're right, it's simply not used.  Probably just an oversight
on the part of whoever wrote the code.  the buf@ could be deleted and
it wouldn't change anything.

-Brent

Reply | Threaded
Open this post in threaded view
|

What does the "!n" mean?

yi lu
In reply to this post by John M. Dlugosz
http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/bang-patterns.html

Do you mean this?


On Thu, Mar 27, 2014 at 9:15 AM, John M. Dlugosz
<ngnr63q02 at sneakemail.com>wrote:

> I'm reading http://www.haskell.org/haskellwiki/IO_inside#inlinePerformIOand it shows a passage of code:
>
> write :: Int -> (Ptr Word8 -> IO ()) -> Put ()
> write !n body = Put $ \c buf@(Buffer fp o u l) ->
>   if n <= l
>     then write' c fp o u l
>     else write' (flushOld c n fp o u) (newBuffer c n) 0 0 0
>
>   where {-# NOINLINE write' #-}
>         write' c !fp !o !u !l =
>           -- warning: this is a tad hardcore
>           inlinePerformIO
>             (withForeignPtr fp
>               (\p -> body $! (p `plusPtr` (o+u))))
>           `seq` c () (Buffer fp o (u+n) (l-n))
>
> I got as far as the second line, looking things up in this index <
> http://hackage.haskell.org/package/base-4.6.0.1/docs/doc-index.html>
>
> But ?write !n body = ??
> I understand write is defined to be a function taking an Int and another
> function,
> but what does !n mean?  I went through the 2010 Report (BTW, the PDF is
> useless for searching for the ! character so I used the HTML version
> page-by-page) and found it used as a modifier for named record fields (it
> says "strict" but I think it's describing non-optional).
> Then I went through the GHC users guide for language extensions, and found
> a reference in ?7.2.1 without explanation but as an example where the
> difference between
>         f x = let (Foo a b, w) = ..rhs.. in ..body..
> and     f x = let !(Foo a b, w) = ..rhs.. in ..body..
> is "you must make any such pattern-match strict".
> Strict pattern matching is not mentioned elsewhere nor is it in the
> Haskell Report, so what am I missing?  I suspect that the usage I'm asking
> about is related.
>
> The GHC users guide also mentions it again in ?7.4.6 which I think is a
> reference to the same feature, ?You can use strictness annotations, in the
> obvious places in the constructor type? but that's for use with a
> completely different extension (GADT types)
>
> I also recognize the ?@? mark as naming the entire variable rather than
> just the parts of the pattern matched, but ?buf? is not actually used
> anywhere, so does it mean something different, or has other effects, or
> what?
>
> Thanks in advance,
> ?John
>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.haskell.org/pipermail/beginners/attachments/20140327/726c267d/attachment.html>

Reply | Threaded
Open this post in threaded view
|

What does the "!n" mean?

John M. Dlugosz
On 3/26/2014 8:26 PM, yi lu wrote:
> http://www.haskell.org/ghc/docs/7.6.3/html/users_guide/bang-patterns.html
>
> Do you mean this?

Thanks!  I missed it when scanning through the GHC docs.