Skip to content
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

import Prelude by default #18

Closed
gelisam opened this issue Aug 23, 2013 · 8 comments
Closed

import Prelude by default #18

gelisam opened this issue Aug 23, 2013 · 8 comments
Assignees
Labels

Comments

@gelisam
Copy link
Owner

gelisam commented Aug 23, 2013

Continued from issue 50.

hint doesn't implicitly import Prelude even when NoImplicitPrelude is off, so we'll have to modify the source to add import Prelude if it isn't already present, but only if the user hasn't specified NoImplicitPrelude.

@ghost ghost assigned gelisam Aug 23, 2013
@gelisam
Copy link
Owner Author

gelisam commented Aug 29, 2013

I implemented this, but while testing the different cases I discovered that hint doesn't behave very well when the Prelude is not imported or imported qualified. The problem seems to be, once again, with the type of the evaluated expression, IO (), which should be P.IO () instead. But we are not actually passing the string IO () to hint at all, it is hint which incorrectly generates this text.

A simple solution would be to also import the Prelude unqualified, but then this would cause naming conflicts, i.e. if the user imports ByteString unqualified, reverse becomes ambiguous in the user expression even though it wasn't ambiguous in the user prelude.

Another workaround would be to return a built-in type, such as (), and use P.unsafePerformIO to hide the IO () operation from hint.

The hardest, but most correct fix would be to dig into the source of hint, fix their bug, and send a pull request. If I remember well, you said their code was easy to read?

@melrief
Copy link
Collaborator

melrief commented Aug 29, 2013

Wait but this is already implemented: in initInterpreter:

        let modulesWithPrelude = if "Prelude" `L.notElem` fmap P.fst modules
                                    then ("Prelude",Nothing):modules
                                    else modules

@gelisam
Copy link
Owner Author

gelisam commented Aug 29, 2013

That code imports the prelude, unqualified, if it isn't already imported. It doesn't add an implicit Prelude import to the user prelude, nor does it fix the subsequent issue with naming conflicts. The only situation in which it helps is with the P.IO () issue, and even then, only when the user prelude does not import the Prelude in a qualified manner.

– Samuel

On 2013-08-29, at 1:58 PM, Mario Pastorelli [email protected] wrote:

Wait but this is already implemented: in initInterpreter:

    let modulesWithPrelude = if "Prelude" `L.notElem` fmap P.fst modules
                                then ("Prelude",Nothing):modules
                                else modules


Reply to this email directly or view it on GitHub.

@gelisam
Copy link
Owner Author

gelisam commented Aug 30, 2013

I have implemented the unsafePerformIO solution. It is now possible to define commands whose name would previously have conflicted with the Prelude:

> cat ~/.hawk/prelude.hs
{-# LANGUAGE ExtendedDefaultRules, OverloadedStrings #-}
import qualified Prelude as P

reverse = P.id
> seq 3 | hawk -a reverse
1
2
3

@gelisam
Copy link
Owner Author

gelisam commented Aug 30, 2013

And, of course, the Prelude module is now implicitly imported by the user's prelude if it is missing:

> cat ~/.hawk/prelude.hs
{-# LANGUAGE ExtendedDefaultRules, OverloadedStrings #-}

rev = reverse
> seq 3 | hawk -a rev
3
2
1

In this situation, however, the Prelude is not available from the user's expression:

> seq 3 | hawk -a reverse
Won't typecheck:
    Not in scope: `reverse'

I'm not sure if that's the expected behaviour or not.

@melrief
Copy link
Collaborator

melrief commented Sep 1, 2013

If we want to mimic standard haskell, then Prelude should be imported unqualified unless the user set NoImplicitPrelude. So I don't think this is the behaviour that we want. But maybe I'm missing the point: I don't understand why this can happen even if in initInterpreter there is the code to import Prelude anyway.

@gelisam
Copy link
Owner Author

gelisam commented Sep 1, 2013

Ah, found it! I had removed that initInterpreter code to always import Prelude because that prelude was introducing conflicting names. Since I was explicitly adding Prelude to the user prelude, I thought this code was now redundant anyway. But in fact, the module list is obtained from the user's original prelude, not from the modified cached version! I just need to add Prelude to the modules list at the same time as I add it to the cached version.

@gelisam
Copy link
Owner Author

gelisam commented Sep 1, 2013

Should be fixed now. Closing.

@gelisam gelisam closed this as completed Sep 1, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants