Wondering about c type in haskell.

Hi, There are times, when we need to make some system calls, or call C library. So we have to deal with C data types. For example, CPid, which is an integer, actually. So we can do "fromIntegral pid". Then why do not we define "type CPid = Integer", and convert Haskell Integer with C Int internally. So the "user" does not have to care about the type convert (everywhere, which is ugly). And, specially, when doing something like serialisation, for Haskell Integer, the user does not have to do things with precision. But for CPid, without the fromIntegral, we have to specify its precision, well, on different machine/OS, the precision may not be the same. -- 竹密岂妨流水过 山高哪阻野云飞

Magicloud Magiclouds 쓴 글:
Hi, There are times, when we need to make some system calls, or call C library. So we have to deal with C data types. For example, CPid, which is an integer, actually. So we can do "fromIntegral pid". Then why do not we define "type CPid = Integer", and convert Haskell Integer with C Int internally. So the "user" does not have to care about the type convert (everywhere, which is ugly). And, specially, when doing something like serialisation, for Haskell Integer, the user does not have to do things with precision. But for CPid, without the fromIntegral, we have to specify its precision, well, on different machine/OS, the precision may not be the same.
Integer is not a fixed length chunk of bits. It can be arbitrarily large as long as there is memory left in the system. It's theoretically more clean being close to a mathematical definition of integers, but internally a complicated beast. So defining CPid as Integer is just not sane. In addition, we cannot use Int either. Int is not a 32 bit or 64 bit word. The Haskell 98 standard does not require that, and in most implementations it is 2^31 singed bits using one bit as a mark to distinguish pointers from values for garbage collection purposes. (OCaml int types are like that too.) I hope this gives enough explanation. -- Ahn, Ki Yung

Ahn, Ki Yung 쓴 글:
Magicloud Magiclouds 쓴 글:
Hi, There are times, when we need to make some system calls, or call C library. So we have to deal with C data types. For example, CPid, which is an integer, actually. So we can do "fromIntegral pid". Then why do not we define "type CPid = Integer", and convert Haskell Integer with C Int internally. So the "user" does not have to care about the type convert (everywhere, which is ugly). And, specially, when doing something like serialisation, for Haskell Integer, the user does not have to do things with precision. But for CPid, without the fromIntegral, we have to specify its precision, well, on different machine/OS, the precision may not be the same.
Integer is not a fixed length chunk of bits. It can be arbitrarily large as long as there is memory left in the system. It's theoretically more clean being close to a mathematical definition of integers, but internally a complicated beast. So defining CPid as Integer is just not sane.
In addition, we cannot use Int either. Int is not a 32 bit or 64 bit word. The Haskell 98 standard does not require that, and in most implementations it is 2^31 singed bits using one bit as a mark to distinguish pointers from values for garbage collection purposes. (OCaml int types are like that too.)
I hope this gives enough explanation.
I wrote this and thought that you might already know this. For convenience of serialization, wouldn't defining Data.Binary instances for C types be enough in the library level? -- Ahn, Ki Yung

I think Integer is prefered in Haskell. I mean normally, I should use
it in my code. So following my example, why cannot CPid be treated as
Integer. Only when it needs to be transfered to C or whatsoever, we
convert it to Long or whatsoever. So we have a unified type system,
not a bunch of types I need to convert, convert, convert.
And, let say using Integer for pid is insane. Then if I do not convert
it into Integer, when serialised, I have to point out with
Word32/Word64, which is definitely bad.
On Tue, Jun 30, 2009 at 11:01 AM, Ahn, Ki Yung
Magicloud Magiclouds 쓴 글:
Hi, There are times, when we need to make some system calls, or call C library. So we have to deal with C data types. For example, CPid, which is an integer, actually. So we can do "fromIntegral pid". Then why do not we define "type CPid = Integer", and convert Haskell Integer with C Int internally. So the "user" does not have to care about the type convert (everywhere, which is ugly). And, specially, when doing something like serialisation, for Haskell Integer, the user does not have to do things with precision. But for CPid, without the fromIntegral, we have to specify its precision, well, on different machine/OS, the precision may not be the same.
Integer is not a fixed length chunk of bits. It can be arbitrarily large as long as there is memory left in the system. It's theoretically more clean being close to a mathematical definition of integers, but internally a complicated beast. So defining CPid as Integer is just not sane.
In addition, we cannot use Int either. Int is not a 32 bit or 64 bit word. The Haskell 98 standard does not require that, and in most implementations it is 2^31 singed bits using one bit as a mark to distinguish pointers from values for garbage collection purposes. (OCaml int types are like that too.)
I hope this gives enough explanation.
-- Ahn, Ki Yung
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- 竹密岂妨流水过 山高哪阻野云飞

On Mon, Jun 29, 2009 at 7:01 PM, Magicloud Magiclouds < magicloud.magiclouds@gmail.com> wrote:
Hi, There are times, when we need to make some system calls, or call C library. So we have to deal with C data types. For example, CPid, which is an integer, actually. So we can do "fromIntegral pid". Then why do not we define "type CPid = Integer", and convert Haskell Integer with C Int internally. So the "user" does not have to care about the type convert (everywhere, which is ugly). And, specially, when doing something like serialisation, for Haskell Integer, the user does not have to do things with precision. But for CPid, without the fromIntegral, we have to specify its precision, well, on different machine/OS, the precision may not be the same.
If you use Int, Integer, Word, etc to represent all your discrete values you can *accidentally* reuse the values for different purposes. So in Haskell we like to put a 'newtype' wrapper around the integral type so that it has a different identity to the type system even when the values are equal as numbers. C is notorious for allowing this type of value reuse and the way that it leads to buggy programs is pretty well document at this point, I believe (although, I take it for granted and I haven't checked for said documentation). Also, in Haskell we don't like implicit, or even ambiguous, type conversions and that's just a preference shared by the majority of Haskell programmers. We like to believe that it saves us from ourselves in a sense. So for these reasons, CPid isn't just an Int32 or Word32. We want to be type safe. The price we pay is that at key points in the program you have to explicitly state the transformation you want (fromIntegral). I hope that helps clarify the reasoning. Jason

That is true. But I think we could avoid (or resolve) the problem of
wrong type thing in other ways, or we just resolve one thing by typing
much more code.
On Tue, Jun 30, 2009 at 11:37 AM, Jason Dagit
On Mon, Jun 29, 2009 at 7:01 PM, Magicloud Magiclouds
wrote: Hi, There are times, when we need to make some system calls, or call C library. So we have to deal with C data types. For example, CPid, which is an integer, actually. So we can do "fromIntegral pid". Then why do not we define "type CPid = Integer", and convert Haskell Integer with C Int internally. So the "user" does not have to care about the type convert (everywhere, which is ugly). And, specially, when doing something like serialisation, for Haskell Integer, the user does not have to do things with precision. But for CPid, without the fromIntegral, we have to specify its precision, well, on different machine/OS, the precision may not be the same.
If you use Int, Integer, Word, etc to represent all your discrete values you can *accidentally* reuse the values for different purposes. So in Haskell we like to put a 'newtype' wrapper around the integral type so that it has a different identity to the type system even when the values are equal as numbers. C is notorious for allowing this type of value reuse and the way that it leads to buggy programs is pretty well document at this point, I believe (although, I take it for granted and I haven't checked for said documentation).
Also, in Haskell we don't like implicit, or even ambiguous, type conversions and that's just a preference shared by the majority of Haskell programmers. We like to believe that it saves us from ourselves in a sense. So for these reasons, CPid isn't just an Int32 or Word32. We want to be type safe. The price we pay is that at key points in the program you have to explicitly state the transformation you want (fromIntegral).
I hope that helps clarify the reasoning. Jason
-- 竹密岂妨流水过 山高哪阻野云飞

On Tue, Jun 30, 2009 at 10:01:48AM +0800, Magicloud Magiclouds wrote:
Hi, There are times, when we need to make some system calls, or call C library. So we have to deal with C data types. For example, CPid, which is an integer, actually. So we can do "fromIntegral pid". Then why do not we define "type CPid = Integer", and convert Haskell Integer with C Int internally. So the "user" does not have to care about the type convert (everywhere, which is ugly). And, specially, when doing something like serialisation, for Haskell Integer, the user does not have to do things with precision. But for CPid, without the fromIntegral, we have to specify its precision, well, on different machine/OS, the precision may not be the same.
Because we need to actually convey to the haskell implementation what the proper calling conventions for the function are, if we used type synonyms, we would have no way to know whether the type passed is a long, short, or whatever. We need to use real types to tell the FFI spec how to bind to the external function properly. John -- John Meacham - ⑆repetae.net⑆john⑈ - http://notanumber.net/
participants (4)
-
Ahn, Ki Yung
-
Jason Dagit
-
John Meacham
-
Magicloud Magiclouds