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

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

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

chessai .
There is no operational difference when using `Ptr a` vs `Addr` in such a case. The problem lies in the type variable `a`. Types are here to guide us - if I use `Ptr Word8`, and this Ptr is not a Ptr to Word8, there is not much enforcing this. In such cases, the type annotation is untruthful. We would like it more often than not to be truthful. Yes, in the underlying C, there exists suboptimal typing, but that is why we are not writing in C, and instead lifting the code to Haskell.

On Fri, Oct 26, 2018 at 4:38 PM Sven Panne <[hidden email]> wrote:
Am Fr., 26. Okt. 2018 um 22:31 Uhr schrieb Andrew Martin <[hidden email]>:
The better alternative suggested in this thread is to use Addr instead. That way, you don't have to lie about the type of the serialized data that the pointer is pointing to.

Even if I'm repeating myself: That is not lying, quite the opposite. If you e.g. use a C library with suboptimal typing (i.e. more often than not), you make the impedance matching explicit. How would you achieve that with Addr?

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

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

David Feuer
In reply to this post by Sven Panne-2
I think you're looking at this wrong. An Addr doesn't need to point to
anything corresponding to a Haskell value at all. It's perfectly
acceptable for an FFI call to return an Addr pointing to some C
structure somewhere that Haskell never touches at all. Instead,
Haskell code may use it only as an argument to some other FFI call.
The only real reason to *have* Addr# rather than just using Int# or
Word# is that there's no inherent guarantee that a long in C is the
same size as a pointer.
On Fri, Oct 26, 2018 at 4:38 PM Sven Panne <[hidden email]> wrote:

>
> Am Fr., 26. Okt. 2018 um 22:31 Uhr schrieb Andrew Martin <[hidden email]>:
>>
>> The better alternative suggested in this thread is to use Addr instead. That way, you don't have to lie about the type of the serialized data that the pointer is pointing to.
>
>
> Even if I'm repeating myself: That is not lying, quite the opposite. If you e.g. use a C library with suboptimal typing (i.e. more often than not), you make the impedance matching explicit. How would you achieve that with Addr?
>
> _______________________________________________
> 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: Proposal: Move primitive-Data.Primitive.Addr API into base

chessai .
Yeah, that's a good point, David.
Also, no one is talking about removing the existence of Ptr - just providing Addr and using it where appropriate.



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

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

Carter Schonwald
What’s a good use you have in mind?

On Fri, Oct 26, 2018 at 5:04 PM Daniel Cartwright <[hidden email]> wrote:
Yeah, that's a good point, David.
Also, no one is talking about removing the existence of Ptr - just providing Addr and using it where appropriate.


_______________________________________________
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: Proposal: Move primitive-Data.Primitive.Addr API into base

Haskell - Libraries mailing list
In reply to this post by chessai .
Daniel Cartwright wrote:
> There is no operational difference when using `Ptr a` vs `Addr` in such a
> case. The problem lies in the type variable `a`. Types are here to guide us
> - if I use `Ptr Word8`, and this Ptr is not a Ptr to Word8, there is not
> much enforcing this. In such cases, the type annotation is untruthful.

This is an argument against using a fully polymorphic `Ptr a` value as
an abstract pointer, but I don't see anything wrong with using `Ptr ()`
values or fully polymorphic `Ptr a` function arguments for that purpose.
With any such low-level code, you have to trust the programmer to get
things right anyway; replacing `Ptr ()` values by `Addr` values isn't
going to make a big difference.

> We
> would like it more often than not to be truthful. Yes, in the underlying C,
> there exists suboptimal typing, but that is why we are not writing in C,
> and instead lifting the code to Haskell.

We should also discuss the cost associated with mixing two functionally
equivalent types in the same library, which will make the API less
predictable, are likely to result in duplication in the APIs for Ptr and
Addr, and will lead to more explicit type conversions with little
benefit. And of course there is a risk of breaking existing code as
existing API is changed to use the new type. (The term "user-facing" has
popped up in this thread -- what does that mean in the case of such a
low-level API?)

Cheers,

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

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

Sven Panne-2
Am Sa., 27. Okt. 2018 um 11:07 Uhr schrieb Bertram Felgenhauer via Libraries <[hidden email]>:
[...] We should also discuss the cost associated with mixing two functionally
equivalent types in the same library, which will make the API less
predictable, are likely to result in duplication in the APIs for Ptr and
Addr, and will lead to more explicit type conversions with little
benefit. [...]

The more I think about it, the more serious I am about my "180 degree" proposal: Nuke Addr completely in favor of "Ptr a"/"Ptr ()". What can Addr do what a "Ptr a"/"Ptr ()" can't? Off the top of my head I would say "nothing". In most other circumstances we like generalizations, why not here? Having Addr just gives us a bigger API surface and is probably used mostly within GHC and its closely tied packages, not really "in the wild".

If "Ptr a" or "Ptr ()" or "Ptr Void" is the right thing to use in a specific place is always a tradeoff between ease of use, being explicit, readability, and perhaps what a corresponding C library uses. Type safety, as much as we like it, is just wishful thinking at that level, there's always castPtr (and of course the FunPtr counterparts).

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

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

Carter Schonwald
Addr only exists within the primitive package.  And it only seems to be used in one spot in all of the vector package. And it’s a very weird spot that I honestly  may wanna redesign/see about changing  given how strange it is.  Especially since it may be one of those things where the current code needs some benchmarks 


It’s the only instance in all of vector 



On Sat, Oct 27, 2018 at 6:05 AM Sven Panne <[hidden email]> wrote:
Am Sa., 27. Okt. 2018 um 11:07 Uhr schrieb Bertram Felgenhauer via Libraries <[hidden email]>:
[...] We should also discuss the cost associated with mixing two functionally
equivalent types in the same library, which will make the API less
predictable, are likely to result in duplication in the APIs for Ptr and
Addr, and will lead to more explicit type conversions with little
benefit. [...]

The more I think about it, the more serious I am about my "180 degree" proposal: Nuke Addr completely in favor of "Ptr a"/"Ptr ()". What can Addr do what a "Ptr a"/"Ptr ()" can't? Off the top of my head I would say "nothing". In most other circumstances we like generalizations, why not here? Having Addr just gives us a bigger API surface and is probably used mostly within GHC and its closely tied packages, not really "in the wild".

If "Ptr a" or "Ptr ()" or "Ptr Void" is the right thing to use in a specific place is always a tradeoff between ease of use, being explicit, readability, and perhaps what a corresponding C library uses. Type safety, as much as we like it, is just wishful thinking at that level, there's always castPtr (and of course the FunPtr counterparts).
_______________________________________________
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: Proposal: Move primitive-Data.Primitive.Addr API into base

Carter Schonwald
*only use i'm aware of

and its a pretty gross one.

are there any ACTUAL uses of Addr?  (granted, having a lifted / data'd version of unlifted types is general a useful thing)

Ptr Void having the byte address oriented interface for indexing arithmetic sounds good to me

On Sat, Oct 27, 2018 at 9:56 AM Carter Schonwald <[hidden email]> wrote:
Addr only exists within the primitive package.  And it only seems to be used in one spot in all of the vector package. And it’s a very weird spot that I honestly  may wanna redesign/see about changing  given how strange it is.  Especially since it may be one of those things where the current code needs some benchmarks 


It’s the only instance in all of vector 



On Sat, Oct 27, 2018 at 6:05 AM Sven Panne <[hidden email]> wrote:
Am Sa., 27. Okt. 2018 um 11:07 Uhr schrieb Bertram Felgenhauer via Libraries <[hidden email]>:
[...] We should also discuss the cost associated with mixing two functionally
equivalent types in the same library, which will make the API less
predictable, are likely to result in duplication in the APIs for Ptr and
Addr, and will lead to more explicit type conversions with little
benefit. [...]

The more I think about it, the more serious I am about my "180 degree" proposal: Nuke Addr completely in favor of "Ptr a"/"Ptr ()". What can Addr do what a "Ptr a"/"Ptr ()" can't? Off the top of my head I would say "nothing". In most other circumstances we like generalizations, why not here? Having Addr just gives us a bigger API surface and is probably used mostly within GHC and its closely tied packages, not really "in the wild".

If "Ptr a" or "Ptr ()" or "Ptr Void" is the right thing to use in a specific place is always a tradeoff between ease of use, being explicit, readability, and perhaps what a corresponding C library uses. Type safety, as much as we like it, is just wishful thinking at that level, there's always castPtr (and of course the FunPtr counterparts).
_______________________________________________
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: Proposal: Move primitive-Data.Primitive.Addr API into base

chessai .
'Ptr Void' is not a pointer to value of type 'Void'; there are no values of type 'Void'; this type is nonsensical.
'Ptr a' is not a pointer to a value of type a; what is 'a'?
'Ptr ()' could be a pointer to a value of type '()', and if so, then this is a correct usage of 'Ptr'. If not, it is an incorrect usage of 'Ptr'.

On Sat, Oct 27, 2018 at 2:43 PM Carter Schonwald <[hidden email]> wrote:
*only use i'm aware of

and its a pretty gross one.

are there any ACTUAL uses of Addr?  (granted, having a lifted / data'd version of unlifted types is general a useful thing)

Ptr Void having the byte address oriented interface for indexing arithmetic sounds good to me

On Sat, Oct 27, 2018 at 9:56 AM Carter Schonwald <[hidden email]> wrote:
Addr only exists within the primitive package.  And it only seems to be used in one spot in all of the vector package. And it’s a very weird spot that I honestly  may wanna redesign/see about changing  given how strange it is.  Especially since it may be one of those things where the current code needs some benchmarks 


It’s the only instance in all of vector 



On Sat, Oct 27, 2018 at 6:05 AM Sven Panne <[hidden email]> wrote:
Am Sa., 27. Okt. 2018 um 11:07 Uhr schrieb Bertram Felgenhauer via Libraries <[hidden email]>:
[...] We should also discuss the cost associated with mixing two functionally
equivalent types in the same library, which will make the API less
predictable, are likely to result in duplication in the APIs for Ptr and
Addr, and will lead to more explicit type conversions with little
benefit. [...]

The more I think about it, the more serious I am about my "180 degree" proposal: Nuke Addr completely in favor of "Ptr a"/"Ptr ()". What can Addr do what a "Ptr a"/"Ptr ()" can't? Off the top of my head I would say "nothing". In most other circumstances we like generalizations, why not here? Having Addr just gives us a bigger API surface and is probably used mostly within GHC and its closely tied packages, not really "in the wild".

If "Ptr a" or "Ptr ()" or "Ptr Void" is the right thing to use in a specific place is always a tradeoff between ease of use, being explicit, readability, and perhaps what a corresponding C library uses. Type safety, as much as we like it, is just wishful thinking at that level, there's always castPtr (and of course the FunPtr counterparts).
_______________________________________________
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

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

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

chessai .
In reply to this post by Carter Schonwald
'Ptr Void' is not a pointer to a value of type 'Void'; there are no values of type 'Void': this type is nonsensical.
'Ptr a' is not a pointer to a value of type a; what is 'a'?
'Ptr ()' could be a pointer to a value of type '()', and if so, then this is a correct usage of 'Ptr'. If not, it is an incorrect usage of 'Ptr'.

On Sat, Oct 27, 2018 at 2:43 PM Carter Schonwald <[hidden email]> wrote:
*only use i'm aware of

and its a pretty gross one.

are there any ACTUAL uses of Addr?  (granted, having a lifted / data'd version of unlifted types is general a useful thing)

Ptr Void having the byte address oriented interface for indexing arithmetic sounds good to me

On Sat, Oct 27, 2018 at 9:56 AM Carter Schonwald <[hidden email]> wrote:
Addr only exists within the primitive package.  And it only seems to be used in one spot in all of the vector package. And it’s a very weird spot that I honestly  may wanna redesign/see about changing  given how strange it is.  Especially since it may be one of those things where the current code needs some benchmarks 


It’s the only instance in all of vector 



On Sat, Oct 27, 2018 at 6:05 AM Sven Panne <[hidden email]> wrote:
Am Sa., 27. Okt. 2018 um 11:07 Uhr schrieb Bertram Felgenhauer via Libraries <[hidden email]>:
[...] We should also discuss the cost associated with mixing two functionally
equivalent types in the same library, which will make the API less
predictable, are likely to result in duplication in the APIs for Ptr and
Addr, and will lead to more explicit type conversions with little
benefit. [...]

The more I think about it, the more serious I am about my "180 degree" proposal: Nuke Addr completely in favor of "Ptr a"/"Ptr ()". What can Addr do what a "Ptr a"/"Ptr ()" can't? Off the top of my head I would say "nothing". In most other circumstances we like generalizations, why not here? Having Addr just gives us a bigger API surface and is probably used mostly within GHC and its closely tied packages, not really "in the wild".

If "Ptr a" or "Ptr ()" or "Ptr Void" is the right thing to use in a specific place is always a tradeoff between ease of use, being explicit, readability, and perhaps what a corresponding C library uses. Type safety, as much as we like it, is just wishful thinking at that level, there's always castPtr (and of course the FunPtr counterparts).
_______________________________________________
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

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

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

Sven Panne-2
Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
'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++.
 
'Ptr a' is not a pointer to a value of type a; what is 'a'?

As usual, it's the "I don't care about it" type. :) Take e.g. mallocBytes: It returns a "Ptr a" exactly because of the fact that it doesn't care about what will eventually be stored in the new area. Another API design option would have been returning "Ptr Void" or "Ptr ()" instead, but this would have forced API users to insert castPtr, which is only annoying there and wouldn't buy us a single bit of security in those circumstances.
 
'Ptr ()' could be a pointer to a value of type '()', and if so, then this is a correct usage of 'Ptr'. If not, it is an incorrect usage of 'Ptr'.

You can't store or read "()", so the same holds as for Void (which didn't exist when the FFI was created IIRC).

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

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

David Feuer
On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
'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
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/libraries
Reply | Threaded
Open this post in threaded view
|

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

Carter Schonwald
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 <[hidden email]> wrote:
On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
'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
[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: Proposal: Move primitive-Data.Primitive.Addr API into base

David Feuer
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
<[hidden email]> 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 <[hidden email]> wrote:
>>
>> On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
>>>
>>> Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
>>>>
>>>> '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
>> [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: Proposal: Move primitive-Data.Primitive.Addr API into base

Carter Schonwald
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 <[hidden email]> 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
<[hidden email]> 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 <[hidden email]> wrote:
>>
>> On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
>>>
>>> Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
>>>>
>>>> '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
>> [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: Proposal: Move primitive-Data.Primitive.Addr API into base

David Feuer
Good point! Call it nominal then.

On Mon, Oct 29, 2018, 5:24 PM Carter Schonwald <[hidden email]> 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 <[hidden email]> 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
<[hidden email]> 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 <[hidden email]> wrote:
>>
>> On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
>>>
>>> Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
>>>>
>>>> '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
>> [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: Proposal: Move primitive-Data.Primitive.Addr API into base

Carter Schonwald
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"

[hidden email] , @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!

{-# 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 <[hidden email]> wrote:
Good point! Call it nominal then.

On Mon, Oct 29, 2018, 5:24 PM Carter Schonwald <[hidden email]> 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 <[hidden email]> 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
<[hidden email]> 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 <[hidden email]> wrote:
>>
>> On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
>>>
>>> Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
>>>>
>>>> '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
>> [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: Proposal: Move primitive-Data.Primitive.Addr API into base

chessai .
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 <[hidden email]> 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"

[hidden email] , @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!

{-# 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 <[hidden email]> wrote:
Good point! Call it nominal then.

On Mon, Oct 29, 2018, 5:24 PM Carter Schonwald <[hidden email]> 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 <[hidden email]> 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
<[hidden email]> 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 <[hidden email]> wrote:
>>
>> On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
>>>
>>> Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
>>>>
>>>> '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
>> [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

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

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

Carter Schonwald
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 <[hidden email]> 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 <[hidden email]> 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"

[hidden email] , @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!

{-# 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 <[hidden email]> wrote:
Good point! Call it nominal then.

On Mon, Oct 29, 2018, 5:24 PM Carter Schonwald <[hidden email]> 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 <[hidden email]> 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
<[hidden email]> 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 <[hidden email]> wrote:
>>
>> On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
>>>
>>> Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
>>>>
>>>> '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
>> [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

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

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

Dannyu NDos
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 <[hidden email]>님이 작성:
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 <[hidden email]> 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 <[hidden email]> 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"

[hidden email] , @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!

{-# 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 <[hidden email]> wrote:
Good point! Call it nominal then.

On Mon, Oct 29, 2018, 5:24 PM Carter Schonwald <[hidden email]> 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 <[hidden email]> 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
<[hidden email]> 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 <[hidden email]> wrote:
>>
>> On Mon, Oct 29, 2018, 10:05 AM Sven Panne <[hidden email]> wrote:
>>>
>>> Am Mo., 29. Okt. 2018 um 14:27 Uhr schrieb Daniel Cartwright <[hidden email]>:
>>>>
>>>> '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
>> [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
_______________________________________________
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
12345