Null Pointer Pattern

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

Null Pointer Pattern

Andrew Martin
Foreign.Ptr provides nullPtr. It would make some of my code more terse if this was additionally provided as a pattern synonym. The pattern synonym can be defined as:

    {-# language ViewPatterns #-}
    {-# language PatternSynonyms #-}
    module NullPointerPattern
      ( pattern Null
      ) where
    import Foreign.Ptr (Ptr,nullPtr)
    pattern Null :: Ptr a
    pattern Null <- ((\x -> x == nullPtr) -> True)
      where Null = nullPtr

Any here is example of code that becomes more terse once this is available:

    foo :: IO (Either Error (Ptr Foo))
    foo = do
      p <- initialize mySettings
      if p == nullPtr
        then pure (Left InitializeFailure)
        else pure (Right p)

With the pattern synonym, we are able to take advantage of LambdaCase:

    foo :: IO (Either Error (Ptr Foo))
    foo = initialize mySettings >>= \case
      Null -> pure (Left InitializeFailure)
      p -> pure (Right p)

I'm curious what others think.

--
-Andrew Thaddeus Martin

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Null Pointer Pattern

David Feuer
In the context of GHC Haskell, that's definitely the Right Thing. I think what might concern some people is that pattern synonyms as we know them are a very GHC thing, while the Ptr business is pretty much Report Haskell. 

On Mon, Aug 17, 2020, 10:44 AM Andrew Martin <[hidden email]> wrote:
Foreign.Ptr provides nullPtr. It would make some of my code more terse if this was additionally provided as a pattern synonym. The pattern synonym can be defined as:

    {-# language ViewPatterns #-}
    {-# language PatternSynonyms #-}
    module NullPointerPattern
      ( pattern Null
      ) where
    import Foreign.Ptr (Ptr,nullPtr)
    pattern Null :: Ptr a
    pattern Null <- ((\x -> x == nullPtr) -> True)
      where Null = nullPtr

Any here is example of code that becomes more terse once this is available:

    foo :: IO (Either Error (Ptr Foo))
    foo = do
      p <- initialize mySettings
      if p == nullPtr
        then pure (Left InitializeFailure)
        else pure (Right p)

With the pattern synonym, we are able to take advantage of LambdaCase:

    foo :: IO (Either Error (Ptr Foo))
    foo = initialize mySettings >>= \case
      Null -> pure (Left InitializeFailure)
      p -> pure (Right p)

I'm curious what others think.

--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Null Pointer Pattern

Andrew Martin
There is always the possibility of using GHC.Ptr as a home for it instead of Foreign.Ptr. The main reason I would want this in base rather than just some library is that, as a library author, I would never pick up an extra dependency for something that trivial.

On Mon, Aug 17, 2020 at 10:52 AM David Feuer <[hidden email]> wrote:
In the context of GHC Haskell, that's definitely the Right Thing. I think what might concern some people is that pattern synonyms as we know them are a very GHC thing, while the Ptr business is pretty much Report Haskell. 

On Mon, Aug 17, 2020, 10:44 AM Andrew Martin <[hidden email]> wrote:
Foreign.Ptr provides nullPtr. It would make some of my code more terse if this was additionally provided as a pattern synonym. The pattern synonym can be defined as:

    {-# language ViewPatterns #-}
    {-# language PatternSynonyms #-}
    module NullPointerPattern
      ( pattern Null
      ) where
    import Foreign.Ptr (Ptr,nullPtr)
    pattern Null :: Ptr a
    pattern Null <- ((\x -> x == nullPtr) -> True)
      where Null = nullPtr

Any here is example of code that becomes more terse once this is available:

    foo :: IO (Either Error (Ptr Foo))
    foo = do
      p <- initialize mySettings
      if p == nullPtr
        then pure (Left InitializeFailure)
        else pure (Right p)

With the pattern synonym, we are able to take advantage of LambdaCase:

    foo :: IO (Either Error (Ptr Foo))
    foo = initialize mySettings >>= \case
      Null -> pure (Left InitializeFailure)
      p -> pure (Right p)

I'm curious what others think.

--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Null Pointer Pattern

David Feuer
GHC.Ptr feels like too low-level a zone for it. If the objections I predicted don't appear, Foreign.Ptr sure seems more logical.

On Mon, Aug 17, 2020, 11:07 AM Andrew Martin <[hidden email]> wrote:
There is always the possibility of using GHC.Ptr as a home for it instead of Foreign.Ptr. The main reason I would want this in base rather than just some library is that, as a library author, I would never pick up an extra dependency for something that trivial.

On Mon, Aug 17, 2020 at 10:52 AM David Feuer <[hidden email]> wrote:
In the context of GHC Haskell, that's definitely the Right Thing. I think what might concern some people is that pattern synonyms as we know them are a very GHC thing, while the Ptr business is pretty much Report Haskell. 

On Mon, Aug 17, 2020, 10:44 AM Andrew Martin <[hidden email]> wrote:
Foreign.Ptr provides nullPtr. It would make some of my code more terse if this was additionally provided as a pattern synonym. The pattern synonym can be defined as:

    {-# language ViewPatterns #-}
    {-# language PatternSynonyms #-}
    module NullPointerPattern
      ( pattern Null
      ) where
    import Foreign.Ptr (Ptr,nullPtr)
    pattern Null :: Ptr a
    pattern Null <- ((\x -> x == nullPtr) -> True)
      where Null = nullPtr

Any here is example of code that becomes more terse once this is available:

    foo :: IO (Either Error (Ptr Foo))
    foo = do
      p <- initialize mySettings
      if p == nullPtr
        then pure (Left InitializeFailure)
        else pure (Right p)

With the pattern synonym, we are able to take advantage of LambdaCase:

    foo :: IO (Either Error (Ptr Foo))
    foo = initialize mySettings >>= \case
      Null -> pure (Left InitializeFailure)
      p -> pure (Right p)

I'm curious what others think.

--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Null Pointer Pattern

Carter Schonwald
There’s an interesting idea or two in here.  Like, should we support having non-nullable pointers?

On Mon, Aug 17, 2020 at 11:13 AM David Feuer <[hidden email]> wrote:
GHC.Ptr feels like too low-level a zone for it. If the objections I predicted don't appear, Foreign.Ptr sure seems more logical.

On Mon, Aug 17, 2020, 11:07 AM Andrew Martin <[hidden email]> wrote:
There is always the possibility of using GHC.Ptr as a home for it instead of Foreign.Ptr. The main reason I would want this in base rather than just some library is that, as a library author, I would never pick up an extra dependency for something that trivial.

On Mon, Aug 17, 2020 at 10:52 AM David Feuer <[hidden email]> wrote:
In the context of GHC Haskell, that's definitely the Right Thing. I think what might concern some people is that pattern synonyms as we know them are a very GHC thing, while the Ptr business is pretty much Report Haskell. 

On Mon, Aug 17, 2020, 10:44 AM Andrew Martin <[hidden email]> wrote:
Foreign.Ptr provides nullPtr. It would make some of my code more terse if this was additionally provided as a pattern synonym. The pattern synonym can be defined as:

    {-# language ViewPatterns #-}
    {-# language PatternSynonyms #-}
    module NullPointerPattern
      ( pattern Null
      ) where
    import Foreign.Ptr (Ptr,nullPtr)
    pattern Null :: Ptr a
    pattern Null <- ((\x -> x == nullPtr) -> True)
      where Null = nullPtr

Any here is example of code that becomes more terse once this is available:

    foo :: IO (Either Error (Ptr Foo))
    foo = do
      p <- initialize mySettings
      if p == nullPtr
        then pure (Left InitializeFailure)
        else pure (Right p)

With the pattern synonym, we are able to take advantage of LambdaCase:

    foo :: IO (Either Error (Ptr Foo))
    foo = initialize mySettings >>= \case
      Null -> pure (Left InitializeFailure)
      p -> pure (Right p)

I'm curious what others think.

--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Null Pointer Pattern

David Feuer
Maybe, but not as part of this low-level API. We don't need *null* pointers to have *invalid* pointers, so that wouldn't give any safety benefit. Feel free to come up with a safe pointer API though; that could be interesting. You could even try using linear types to prevent deallocated memory from being used, though exceptions will probably be able to break that.

On Mon, Aug 17, 2020, 12:14 PM Carter Schonwald <[hidden email]> wrote:
There’s an interesting idea or two in here.  Like, should we support having non-nullable pointers?

On Mon, Aug 17, 2020 at 11:13 AM David Feuer <[hidden email]> wrote:
GHC.Ptr feels like too low-level a zone for it. If the objections I predicted don't appear, Foreign.Ptr sure seems more logical.

On Mon, Aug 17, 2020, 11:07 AM Andrew Martin <[hidden email]> wrote:
There is always the possibility of using GHC.Ptr as a home for it instead of Foreign.Ptr. The main reason I would want this in base rather than just some library is that, as a library author, I would never pick up an extra dependency for something that trivial.

On Mon, Aug 17, 2020 at 10:52 AM David Feuer <[hidden email]> wrote:
In the context of GHC Haskell, that's definitely the Right Thing. I think what might concern some people is that pattern synonyms as we know them are a very GHC thing, while the Ptr business is pretty much Report Haskell. 

On Mon, Aug 17, 2020, 10:44 AM Andrew Martin <[hidden email]> wrote:
Foreign.Ptr provides nullPtr. It would make some of my code more terse if this was additionally provided as a pattern synonym. The pattern synonym can be defined as:

    {-# language ViewPatterns #-}
    {-# language PatternSynonyms #-}
    module NullPointerPattern
      ( pattern Null
      ) where
    import Foreign.Ptr (Ptr,nullPtr)
    pattern Null :: Ptr a
    pattern Null <- ((\x -> x == nullPtr) -> True)
      where Null = nullPtr

Any here is example of code that becomes more terse once this is available:

    foo :: IO (Either Error (Ptr Foo))
    foo = do
      p <- initialize mySettings
      if p == nullPtr
        then pure (Left InitializeFailure)
        else pure (Right p)

With the pattern synonym, we are able to take advantage of LambdaCase:

    foo :: IO (Either Error (Ptr Foo))
    foo = initialize mySettings >>= \case
      Null -> pure (Left InitializeFailure)
      p -> pure (Right p)

I'm curious what others think.

--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries


--
-Andrew Thaddeus Martin
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Null Pointer Pattern

Henning Thielemann
In reply to this post by Carter Schonwald

On Mon, 17 Aug 2020, Carter Schonwald wrote:

> There’s an interesting idea or two in here.  Like, should we support
> having non-nullable pointers?

That was my first idea, too.

newtype NonNullPtr a = NonNullPtr (Ptr a)

maybeNonNull :: Ptr a -> Maybe (NonNullPtr a)

Using NonNullPtr in FFI declarations would make the interfaces safer.

E.g.
    dst <- mallocArray n
    for (maybeNonNull dst) $ \dstNonNull ->
       copyArray dstNonNull srcNonNull n

That seems better than testing for nullPtr and then forgeting this
information in the type, again.
_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

Re: Null Pointer Pattern

Carter Schonwald
That’s a really nice idea !

On Tue, Aug 18, 2020 at 2:54 AM Henning Thielemann <[hidden email]> wrote:


On Mon, 17 Aug 2020, Carter Schonwald wrote:



> There’s an interesting idea or two in here.  Like, should we support

> having non-nullable pointers?



That was my first idea, too.



newtype NonNullPtr a = NonNullPtr (Ptr a)



maybeNonNull :: Ptr a -> Maybe (NonNullPtr a)



Using NonNullPtr in FFI declarations would make the interfaces safer.



E.g.

    dst <- mallocArray n

    for (maybeNonNull dst) $ \dstNonNull ->

       copyArray dstNonNull srcNonNull n



That seems better than testing for nullPtr and then forgeting this

information in the type, again.

_______________________________________________
Libraries mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries