Proposal: Move primitive-Data.Primitive.Addr API into base

Daniel Cartwright chessai1996 at gmail.com
Tue Oct 30 13:33:37 UTC 2018


[19:26:50] <chessai_> hPutBuf :: Handle -> Ptr a -> Int -> IO ()
[19:26:50] <chessai_> hPutBuf :: Handle -> Addr -> Int -> IO ()
[19:26:55] <carter> ok
[19:27:15] <carter> maybe i wrote the buffer with bytes
[19:27:18] <carter> or maybe i did words?
[19:27:32] <carter> hputbuff dont care
[19:27:45] <hvr> the problem I see is rather that hPutBuf is a sub-optimal
type-sig
[19:28:04] <hvr> it could refer to Storable
[19:28:19] <chessai_> Storable's Ptr usage is another example
[19:28:23] <hvr> but it doesn't, hence why it seems to be a bit awkward
[19:28:35] <carter> chessai_:  whats better there?
[19:28:36] <hvr> so I'd rather blame that it isn't aware of Storable
[19:28:45] <chessai_> hvr: makes sense
[19:28:51] <chessai_> carter: what's better where?
[19:29:27] <carter> what would you feel a better wrapper around storable
would be?
[19:29:36] <carter> addr ruins having good type inference there afaict
[19:30:02] <chessai_> peekByteOff :: Ptr b -> Int -> IO a
[19:30:09] <chessai_> peekByteOff :: Addr -> Int -> IO a
[19:30:26] <chessai_> what is 'b' doing there? it's not used in any
meaningful way by peekByteOff
[19:30:29] <chessai_> it's free
[19:30:39] <hvr> chessai_: so, another option besides making hGetBuf
'Storable'-aware would be to use 'Ptr Word8' imho
[19:31:00] <hvr> as that would imho be more in line with low-levelness of
that operation which is clearly about 8-bit addressable mem
[19:31:10] <hvr> (it even says so in the haddocks)
[19:31:24] <carter> chessai_:  ok, thats definitely a bad api in storable
[19:31:32] <carter> seems liek that should have b and a the same in a
higher level wrapper
[19:31:43] <chessai_> or no b at all
[19:32:03] <chessai_> hvr: i think i like both of those options
[19:32:22] <carter> pokeElemOff :: Ptr a -> Int -> a -> IO () --- way
better than peak
[19:32:23] <chessai_> hvr: not sure about how i weigh them
[19:32:34] <carter> peak should be Ptr a -> Int -> IO a
[19:32:35] <hvr> and yes, peekByteOff had a weird type-sig which nobody
dared to fix probably out of fear of breakage
[19:33:12] <carter> hvr: lets add safePeekByteOff :: Ptr a -> Int -> IO a ?
[19:33:15] <carter> or sane
[19:33:23] <hvr> chessai_: but do take into account that if you want to use
'Addr' there, you're going to have a lot more of justification to do, as
this is Haskell2010 territory
[19:33:46] <chessai_> hvr: true. a lot of 'Ptr' usage seems to be part of
the report
[19:34:20] <carter> chessai_:  you're giving good examples of apis that are
currently bad
[19:34:28] <carter> but it seems like they're ones we can work together to
make better
[19:34:44] <carter> and Addr vs Ptr a is your way of articulating "this API
smells bad"
[19:35:15] <carter> so i agree with the smell, just not with the cure :)
[19:35:20] <carter> at least atm
[19:35:31] <chessai_> carter: i am glad we agree on the smell

On Mon, Oct 29, 2018 at 7:31 PM Carter Schonwald <carter.schonwald at gmail.com>
wrote:

> the parametricity isn't for when you know things, its for saying "these
> are possibly different or possibly the same, dont let me mix them up
> though, cause I dont know yet"
>
>
> On Mon, Oct 29, 2018 at 7:03 PM Daniel Cartwright <chessai1996 at gmail.com>
> wrote:
>
>> I'm not sure that argument applies at all, when talking about _incorrect_
>> usages of Ptr. Sure, Addr probably shouldn't be used when there is
>> meaningful type information/value to recover, but neither should Ptr be
>> used when there is none.
>>
>> The argument being made is not to make 'better', per se, and there
>> definitely won't be a 'mathematical statement' about this, but it certainly
>> may be made clearer - in my opinion, the usages of 'Ptr' that i've already
>> brought up are inherently unclear because of the bogus phantom type
>> associated with 'Ptr'. The illustration of this begs no code that doesn't
>> already exist in corelibs.
>>
>>
>> On Mon, Oct 29, 2018 at 6:19 PM Carter Schonwald <
>> carter.schonwald at gmail.com> wrote:
>>
>>> to zoom out: what code is improved? what code is made better/clearer? No
>>> one has articulated this clearly.
>>>
>>> The one example of Addr being used in Vector.Storable.Mutable is not an
>>> argument in favor of using Addr. Its an argument against it existing.
>>>
>>> i'm looking for evidence, in the form of code i can look at then say
>>> "yes, this is better code" when comparing the two. Or a mathematical
>>> statement of "what is made better"
>>>
>>> @David Feuer <david.feuer at gmail.com> , @Daniel , do you have one?
>>>
>>> when i'm writing complicated code, MORE polymorphism helps me usually.
>>>
>>> I can write some code like the following and even though I'm using it
>>> with Int at argument,
>>> I *Know* that i'm not mixing up arguments/values that i write as
>>> different types. I cannot do this with Address!
>>> (the type / function below can be found at
>>> https://github.com/wellposed/numerical/blob/3a0bbf50bc6ce0b710aee755f5a4bfce08af4201/src/Numerical/Array/Layout/Builder.hs#L294
>>> )
>>>
>>> {-# SPECIALIZE INLINE computeStarts :: [(Int,Int)]->Int->Int
>>> ->[(Int,Int)] #-}
>>> computeStarts:: (Enum a, Ord a, Num b )=>[(a,b)]-> a -> a -> [(a,b)]
>>>
>>> parametricity (even when constrained by type classes) is a powerful and
>>> foundational tool for good programming in haskell and similar languages
>>>
>>> there has been nothing stated here that successfully articulates a good
>>> reason to forgo/discourage parametricity as an engineering tool. for thats
>>> what Addr is.
>>> A datatype thats never safe in isolation, and discourages using
>>> parametricity to write correct software.
>>>
>>> a very strong case is needed to forgo parametricity.
>>>
>>>
>>>
>>>
>>> On Mon, Oct 29, 2018 at 5:33 PM David Feuer <david.feuer at gmail.com>
>>> wrote:
>>>
>>>> Good point! Call it nominal then.
>>>>
>>>> On Mon, Oct 29, 2018, 5:24 PM Carter Schonwald <
>>>> carter.schonwald at gmail.com> wrote:
>>>>
>>>>> absolutely false, represeentational equality of the  type a in `Ptr a`
>>>>> does not mean the memory representation at the corresponding address is the
>>>>> same.
>>>>> (it sometimes is true, but memory packing/alignment details in structs
>>>>> in C  for otherwise equivlanet structs should rule this out)
>>>>>
>>>>> aka, `a` being representationally equal to `b` via haskell newtypes
>>>>> does not mean the memory representation at `Ptr a`, and `Ptr b` are the
>>>>> same. a trivial example is when
>>>>> host and network byte order aren't the same (eg big vs little endian
>>>>> memory encodings)
>>>>>
>>>>> On Mon, Oct 29, 2018 at 12:28 PM David Feuer <david.feuer at gmail.com>
>>>>> wrote:
>>>>>
>>>>>> What? Of course you can dereference it. You dereference it, getting a
>>>>>> value of type `Void`,
>>>>>> and apply absurd to get whatever you want in the world. This, of
>>>>>> course, is utter nonsense,
>>>>>> unless *having* the Ptr Void means that something has already gone
>>>>>> wrong. It's pretty
>>>>>> hard for me to imagine a situation where this is actually what you
>>>>>> want. A Ptr () isn't nonsense.
>>>>>> It is not terrible to use Ptr () to represent an Addr, but I wonder if
>>>>>> it sends the wrong message.
>>>>>> By the way: there's another argument for having Addr in base for now.
>>>>>> We would really
>>>>>> *like* for Ptr's parameter to have a *representational* role, but we
>>>>>> *don't* want to require
>>>>>> unsafeCoerce to cast Ptrs. The solution to that in the current role
>>>>>> system:
>>>>>>
>>>>>>     data Addr = Addr Addr#
>>>>>>
>>>>>>     newtype Ptr a = Ptr_ Addr
>>>>>>     type role Ptr representational
>>>>>>
>>>>>>     pattern Ptr :: Addr# -> Ptr a
>>>>>>     pattern Ptr addr# = Ptr_ (Addr addr#)
>>>>>>
>>>>>>     -- Allow users to reveal coercibility of pointer types locally
>>>>>>     ptrCoercion :: Coercion (Ptr a) (Ptr b)
>>>>>>     ptrCoercion = Coercion
>>>>>>
>>>>>>     castPtr :: Ptr a -> Ptr b
>>>>>>     castPtr = coerceWith ptrCoercion -- (or the now-free unwrap-rewrap
>>>>>> definition)
>>>>>>
>>>>>>
>>>>>> So even if we don't *expose* Addr in base, we should almost certainly
>>>>>> *define*
>>>>>> it there.
>>>>>> On Mon, Oct 29, 2018 at 12:11 PM Carter Schonwald
>>>>>> <carter.schonwald at gmail.com> wrote:
>>>>>> >
>>>>>> > The point , hahah, of a Ptr void is that you can’t dereference it.
>>>>>> But you certainly can cast it and do address arithmetic on it!!
>>>>>> >
>>>>>> >
>>>>>> >
>>>>>> > On Mon, Oct 29, 2018 at 10:10 AM David Feuer <david.feuer at gmail.com>
>>>>>> wrote:
>>>>>> >>
>>>>>> >> On Mon, Oct 29, 2018, 10:05 AM Sven Panne <svenpanne at gmail.com>
>>>>>> wrote:
>>>>>> >>>
>>>>>> >>> Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <
>>>>>> chessai1996 at gmail.com>:
>>>>>> >>>>
>>>>>> >>>> 'Ptr Void' is not a pointer to a value of type 'Void'; there are
>>>>>> no values of type 'Void': this type is nonsensical.
>>>>>> >>>
>>>>>> >>>
>>>>>> >>> That's the whole point, and it actually makes sense: If you see
>>>>>> "Ptr Void", you can't do much with it, apart from passing it around or
>>>>>> using castPtr on it. This is exactly what should be achieved by using "Ptr
>>>>>> Void" in an API. This is basically the same as "void *" in C/C++.
>>>>>> >>
>>>>>> >>
>>>>>> >> No, it does not make sense. The approximate equivalent of C's
>>>>>> void* is Ptr Any. Ptr Void promises to give you anything you want on
>>>>>> dereference, which is nonsense.
>>>>>> >>
>>>>>> >>>
>>>>>> >>> You can't store or read "()", so the same holds as for Void
>>>>>> (which didn't exist when the FFI was created IIRC).
>>>>>> >>
>>>>>> >>
>>>>>> >> Sure you can. Storing () does nothing and reading it gives (). Our
>>>>>> () is somewhat similar to C's void return type.
>>>>>> >> _______________________________________________
>>>>>> >> Libraries mailing list
>>>>>> >> Libraries at haskell.org
>>>>>> >> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>>>>
>>>>> _______________________________________________
>>> Libraries mailing list
>>> Libraries at haskell.org
>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
>>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/libraries/attachments/20181030/97d3875a/attachment.html>


More information about the Libraries mailing list