-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow choice between platform independent and platform dependent API #168
Comments
We are not really implementing (1). We hard code offsets and alignment for structs for example. For (1) one would really need to generate I don't think that (2) even makes sense for TH generation, TH is run on the target architecture anyway, so doing something else feels unnecessary. TH could assume
This doesn't feel right. I think that if we do (2) and For (1) we also need #134, if the header has #131 shows that just setting the target triple is not enough, there are some differences in standard headers. |
Yes, that's why I emphasize "API" (as opposed to implementation). Perhaps I should be clearer about that. My main thinking why this is OK is that if we say,
"TH is run on the target achitecture anyway" -- that would be nice, but not actually the case with current ghc is it?
Yes, that's fair enough, if we do do 2, then indeed, we should be explicit.
Yes, we should definitely not always look through |
I don't understand, so are you saing that data StructFoo = MkStructFoo
{ field1 :: CInt
, field2 :: CInt -- ^ system independent types
}
instance Storable StructFoo where
sizeOf _ = 64 -- 32 bit system specific value
... is fine? IMO it isn't. Either it's (1) data StructFoo = MkStructFoo
{ field1 :: CInt
, field2 :: CInt
}
instance Storable StructFoo where
sizeOf _ = #{sizeof struct foo} -- or some formula, like sizeof_ @CInt + sizeof_ @CInt -- but also taking alignment into account. or (2) data StructFoo = MkStructFoo
{ field1 :: Word32
, field2 :: Word32
}
instance Storable StructFoo where
sizeOf _ = 64
It is. TH is always run on the target, in a way or another (even GHCJS etc). The current multi-staged setup won't work otherwise. (TL;DR the |
Why isn't it fine? Option (1), generating esentially I don't understand re TH, but yes, we don't need to discuss this in this ticket. |
The data StructFoo = MkStructFoo
{ field1 :: CInt
, field2 :: CInt -- ^ system independent types
}
instance Storable StructFoo where
sizeOf _ = 64 -- 32 bit system specific value
... is still system specific. Then there is really no difference between (1) and (2) if (1) means doing the above. I couldn't do
and commit that file to repository (i.e. run I think I understand, the interface of the module will appear to be system-independent in (1), but the implementation will be always specific to the target, whether it's (1) or (2). In other words |
Yeah, I take your point. I think this needs some discussion with the client. |
So I guess we have three modes:
The mode that I had somewhat implicitly assumed we'd focus on first is (1), but indeed all three are valid. I thought from previous discussions with the client that (3) was not considered too desirable, but perhaps we should revisit this question. One difficulty with (3) is CPP: If the header uses CPP to make machine dependent choices, then it becomes unclear what we should do; in a way, option (3) implies #72, at least to some degree. |
So we had a long chat about this with the client. I will try to summarize our thoughts here, but I should note that the conclusions here are still tentative, and it's entirely possible that a strong argument in a different direction can change those conclusions again. The first -- relatively uncontested -- conclusion is that generating true system independent bindings (in the form of This still leaves a lot of room for different design decisions for the machine dependent case. Let's first consider the two opposite extremes of the spectrum:
The benefit of (2) is that the programmer can take advantage of machine specific features; if code written by programmer A on their machine doesn't work with different architectures, then programmer B will find out (hopefully) at compile time on their machine. The main problem with (2) is that we lose a lot of valuable type information:
The tentative conclusion therefore is, for now, to go with option (1) as enumerated in #168 (comment) , unless there are strong arguments against it. |
I would find it very confusing if |
I was not able to find an example of e.g. |
Closing; option (3) is out of the scope, and between (1) and (2) we decided that we want to preserve as much semantic type information as possible. |
For the record, as (3) System independent API, system independent implementation is out of scope, the |
Makes sense! Will close #80. |
Explained in this comment of
PrimType
:We are defaulting to option (1) currently, but as the comment says, we may wish to give users a choice.
The text was updated successfully, but these errors were encountered: