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

Dannyu NDos ndospark320 at gmail.com
Tue Oct 30 00:31:16 UTC 2018


It is Storable that makes Ptr operate as typed pointers. I also think Ptr
on its own doesn't have that much about its argument type, so I'm +1 on the
proposal.

Btw, shouldn't every type be storable? In current Haskell, Maybes or (->)s
aren't Storable, yet in C++, arrays of std::optionals or std::functions are
well-defined.

As an exception, for Void, I agree that they must remain not Storable since
it has no values.

2018년 10월 30일 (화) 08:31, Carter Schonwald <carter.schonwald at gmail.com>님이 작성:

> 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
>>>
>> _______________________________________________
> 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/af8c8977/attachment.html>


More information about the Libraries mailing list