Bikeshedding request for GHCi's :type

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

Bikeshedding request for GHCi's :type

Richard Eisenberg-2
Hi devs,

Over the weekend, I was pondering the Haskell course I will be teaching next year and shuddered at having to teach Foldable at the same time as `length`. So I implemented feature request #10963 (https://ghc.haskell.org/trac/ghc/ticket/10963), which allows for a way for a user to request a specialization of a type. It all works wonderfully, but there is a real user-facing design issue here around the default behavior of :type and whether or not to add new :type-y like commands. I have outlined the situation here: https://ghc.haskell.org/trac/ghc/wiki/Design/GHCi/Type

I'd love some broad input on this issue. If you've got a stake in how this all works, please skim that wiki page and comment on #10963.

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

Re: Bikeshedding request for GHCi's :type

Eric Seidel-3
I think design A (deeply instantiate + generalize) produces the most
sensible types. I don't know what the curly braces mean (perhaps that we
can't use type application anymore since the order changed?) but I don't
think they'd show up at all without -fprint-explicit-foralls, right? If
so, I'm not too concerned about it.

I also think 2C is a neat idea and should be explored further, but I
don't think it should be the default behavior of :type. I've always
expected :type to print the exact type we would infer for the
expression.

Perhaps instead of changing the default behavior of :type or adding new
commands, we could add a flag to enhance :type's output. For example,

  > :type mapM
  mapM :: (Monad m, Traversable t) => (a -> m b) -> t a -> m (t b)
  > :set -fprint-type-specializations
  > :type mapM
  mapM :: (Monad m, Traversable t) => (a -> m b) -> t a -> m (t b)
  Possible Specializations:
  mapM :: Monad m => (a -> m b) -> [a] -> m [b]
  mapM :: (a -> Maybe b) -> [a] -> Maybe [b]
  ...

I think this could be useful even for experienced Haskellers, though I'm
a bit concerned that printing the full type at the top will leave
beginners as bewildered as ever..

Eric

On Tue, Apr 26, 2016, at 06:08, Richard Eisenberg wrote:

> Hi devs,
>
> Over the weekend, I was pondering the Haskell course I will be teaching
> next year and shuddered at having to teach Foldable at the same time as
> `length`. So I implemented feature request #10963
> (https://ghc.haskell.org/trac/ghc/ticket/10963), which allows for a way
> for a user to request a specialization of a type. It all works
> wonderfully, but there is a real user-facing design issue here around the
> default behavior of :type and whether or not to add new :type-y like
> commands. I have outlined the situation here:
> https://ghc.haskell.org/trac/ghc/wiki/Design/GHCi/Type
>
> I'd love some broad input on this issue. If you've got a stake in how
> this all works, please skim that wiki page and comment on #10963.
>
> Thanks!
> Richard
> _______________________________________________
> ghc-devs mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Bikeshedding request for GHCi's :type

John Leo
Speaking as someone teaching his coworkers Haskell now, Eric's is the best suggestion I've seen so far.

What I like about it:
* The original meaning of :type is unchanged.
* No new command is added (I prefer adding a flag to adding another command).
* With the flag on, the full type is shown along with the possible specializations (and good to note the list might not be exhaustive).  This way, beginners can still see what the type should look like even if they want to ignore it for now.  This is similar to learning to read Japanese by using furigana.  It may be a bit confusing for beginners at first, but I expect they'll quickly learn to ignore it until they need it, and I agree it will be useful for experienced Haskellers.

John

On Tue, Apr 26, 2016 at 5:18 PM, Eric Seidel <[hidden email]> wrote:
I think design A (deeply instantiate + generalize) produces the most
sensible types. I don't know what the curly braces mean (perhaps that we
can't use type application anymore since the order changed?) but I don't
think they'd show up at all without -fprint-explicit-foralls, right? If
so, I'm not too concerned about it.

I also think 2C is a neat idea and should be explored further, but I
don't think it should be the default behavior of :type. I've always
expected :type to print the exact type we would infer for the
expression.

Perhaps instead of changing the default behavior of :type or adding new
commands, we could add a flag to enhance :type's output. For example,

  > :type mapM
  mapM :: (Monad m, Traversable t) => (a -> m b) -> t a -> m (t b)
  > :set -fprint-type-specializations
  > :type mapM
  mapM :: (Monad m, Traversable t) => (a -> m b) -> t a -> m (t b)
  Possible Specializations:
  mapM :: Monad m => (a -> m b) -> [a] -> m [b]
  mapM :: (a -> Maybe b) -> [a] -> Maybe [b]
  ...

I think this could be useful even for experienced Haskellers, though I'm
a bit concerned that printing the full type at the top will leave
beginners as bewildered as ever..

Eric

On Tue, Apr 26, 2016, at 06:08, Richard Eisenberg wrote:
> Hi devs,
>
> Over the weekend, I was pondering the Haskell course I will be teaching
> next year and shuddered at having to teach Foldable at the same time as
> `length`. So I implemented feature request #10963
> (https://ghc.haskell.org/trac/ghc/ticket/10963), which allows for a way
> for a user to request a specialization of a type. It all works
> wonderfully, but there is a real user-facing design issue here around the
> default behavior of :type and whether or not to add new :type-y like
> commands. I have outlined the situation here:
> https://ghc.haskell.org/trac/ghc/wiki/Design/GHCi/Type
>
> I'd love some broad input on this issue. If you've got a stake in how
> this all works, please skim that wiki page and comment on #10963.
>
> Thanks!
> Richard
> _______________________________________________
> ghc-devs mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


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

Re: Bikeshedding request for GHCi's :type

Manuel Gómez
On Wed, Apr 27, 2016 at 10:15 AM, John Leo <[hidden email]> wrote:

> Speaking as someone teaching his coworkers Haskell now, Eric's is the best
> suggestion I've seen so far.
>
> What I like about it:
> * The original meaning of :type is unchanged.
> * No new command is added (I prefer adding a flag to adding another
> command).
> * With the flag on, the full type is shown along with the possible
> specializations (and good to note the list might not be exhaustive).  This
> way, beginners can still see what the type should look like even if they
> want to ignore it for now.  This is similar to learning to read Japanese by
> using furigana.  It may be a bit confusing for beginners at first, but I
> expect they'll quickly learn to ignore it until they need it, and I agree it
> will be useful for experienced Haskellers.

Perhaps a pleasant solution would be to borrow a convention from the
PostgreSQL community's interactive console psql and its meta-commands:
http://www.postgresql.org/docs/current/static/app-psql.html#APP-PSQL-META-COMMANDS

For example:

> \d[S+] [ pattern ]
>
> For each [object] matching the pattern, show all columns, their types, the tablespace (if not the default) and any special attributes such as NOT NULL or defaults. […]  The command form \d+ is identical, except that more information is displayed: any comments associated with the columns of the table are shown, as is the presence of OIDs in the table, the view definition if the relation is a view, a non-default replica identitysetting.

Many psql commands use this convention: add a + to the end of the
command, and you get extra information.  It’s quite nmemonic.
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs
Reply | Threaded
Open this post in threaded view
|

Re: Bikeshedding request for GHCi's :type

Iavor Diatchki
Hello Richard,

I think that `:type` should report the real type of an expressions (i.e., the fully generalized inferred type, just like it does now).  Certainly I wouldn't want `:type` to show me some kind of (more or less) arbitrary specialization of the type.

It could be useful to have a ghci command that would show all instantiations of a class method (just 1 level deep) using the instances that are currently in scope.  This would be essentially a combination of `:info` on a class and a method.  For example, this is what it would look like on some of the methods in 7.10's Prelude:

:inst length
length :: [a] -> Int
length :: Maybe a -> Int
length :: Either a b -> Int
length :: (a,b) -> Int

:inst (==)
(==) :: Integer -> Integer -> Bool
(==) :: Word -> Word -> Bool
...
(==) :: Eq a => [a] -> [a] -> Bool    -- Note that we only instantiate the outer class
...
(==) :: (Eq a, Eq b, Eq c) => (a,b,c) -> (a,b,c) -> Bool  -- ditto

:inst mapM
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
mapM :: Monad m => (a -> m b) -> Either e a -> m (Either e b)
mapM :: Monad m => (a -> m b) -> (e,a) -> m (e,b)

This could be generalized to expressions, rather than just methods, but for expressions with multiple constraints one could get an explosion of possible instantiations.  However, it would be quite cool to allow things like this:

:inst 1
1 :: Word
1 :: Integer
1 :: Int
1 :: Float
1 :: Double

Anyway, just some ideas.

-Iavor




















On Wed, Apr 27, 2016 at 8:16 AM, Manuel Gómez <[hidden email]> wrote:
On Wed, Apr 27, 2016 at 10:15 AM, John Leo <[hidden email]> wrote:
> Speaking as someone teaching his coworkers Haskell now, Eric's is the best
> suggestion I've seen so far.
>
> What I like about it:
> * The original meaning of :type is unchanged.
> * No new command is added (I prefer adding a flag to adding another
> command).
> * With the flag on, the full type is shown along with the possible
> specializations (and good to note the list might not be exhaustive).  This
> way, beginners can still see what the type should look like even if they
> want to ignore it for now.  This is similar to learning to read Japanese by
> using furigana.  It may be a bit confusing for beginners at first, but I
> expect they'll quickly learn to ignore it until they need it, and I agree it
> will be useful for experienced Haskellers.

Perhaps a pleasant solution would be to borrow a convention from the
PostgreSQL community's interactive console psql and its meta-commands:
http://www.postgresql.org/docs/current/static/app-psql.html#APP-PSQL-META-COMMANDS

For example:

> \d[S+] [ pattern ]
>
> For each [object] matching the pattern, show all columns, their types, the tablespace (if not the default) and any special attributes such as NOT NULL or defaults. […]  The command form \d+ is identical, except that more information is displayed: any comments associated with the columns of the table are shown, as is the presence of OIDs in the table, the view definition if the relation is a view, a non-default replica identitysetting.

Many psql commands use this convention: add a + to the end of the
command, and you get extra information.  It’s quite nmemonic.
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


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

Re: Bikeshedding request for GHCi's :type

Christopher Allen
I agree with Iavor that :type should report the real type. I see this only stymieing and frustrating efforts to teach the language.

I do like the :inst idea.

On Apr 27, 2016, at 12:22 PM, Iavor Diatchki <[hidden email]> wrote:

Hello Richard,

I think that `:type` should report the real type of an expressions (i.e., the fully generalized inferred type, just like it does now).  Certainly I wouldn't want `:type` to show me some kind of (more or less) arbitrary specialization of the type.

It could be useful to have a ghci command that would show all instantiations of a class method (just 1 level deep) using the instances that are currently in scope.  This would be essentially a combination of `:info` on a class and a method.  For example, this is what it would look like on some of the methods in 7.10's Prelude:

:inst length
length :: [a] -> Int
length :: Maybe a -> Int
length :: Either a b -> Int
length :: (a,b) -> Int

:inst (==)
(==) :: Integer -> Integer -> Bool
(==) :: Word -> Word -> Bool
...
(==) :: Eq a => [a] -> [a] -> Bool    -- Note that we only instantiate the outer class
...
(==) :: (Eq a, Eq b, Eq c) => (a,b,c) -> (a,b,c) -> Bool  -- ditto

:inst mapM
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
mapM :: Monad m => (a -> m b) -> Maybe a -> m (Maybe b)
mapM :: Monad m => (a -> m b) -> Either e a -> m (Either e b)
mapM :: Monad m => (a -> m b) -> (e,a) -> m (e,b)

This could be generalized to expressions, rather than just methods, but for expressions with multiple constraints one could get an explosion of possible instantiations.  However, it would be quite cool to allow things like this:

:inst 1
1 :: Word
1 :: Integer
1 :: Int
1 :: Float
1 :: Double

Anyway, just some ideas.

-Iavor




















On Wed, Apr 27, 2016 at 8:16 AM, Manuel Gómez <[hidden email]> wrote:
On Wed, Apr 27, 2016 at 10:15 AM, John Leo <[hidden email]> wrote:
> Speaking as someone teaching his coworkers Haskell now, Eric's is the best
> suggestion I've seen so far.
>
> What I like about it:
> * The original meaning of :type is unchanged.
> * No new command is added (I prefer adding a flag to adding another
> command).
> * With the flag on, the full type is shown along with the possible
> specializations (and good to note the list might not be exhaustive).  This
> way, beginners can still see what the type should look like even if they
> want to ignore it for now.  This is similar to learning to read Japanese by
> using furigana.  It may be a bit confusing for beginners at first, but I
> expect they'll quickly learn to ignore it until they need it, and I agree it
> will be useful for experienced Haskellers.

Perhaps a pleasant solution would be to borrow a convention from the
PostgreSQL community's interactive console psql and its meta-commands:
http://www.postgresql.org/docs/current/static/app-psql.html#APP-PSQL-META-COMMANDS

For example:

> \d[S+] [ pattern ]
>
> For each [object] matching the pattern, show all columns, their types, the tablespace (if not the default) and any special attributes such as NOT NULL or defaults. […]  The command form \d+ is identical, except that more information is displayed: any comments associated with the columns of the table are shown, as is the presence of OIDs in the table, the view definition if the relation is a view, a non-default replica identitysetting.

Many psql commands use this convention: add a + to the end of the
command, and you get extra information.  It’s quite nmemonic.
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


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

Re: Bikeshedding request for GHCi's :type

Johannes Waldmann-2
In reply to this post by Richard Eisenberg-2
> .. :type should report the real type

What about defaulting? Is it real?
https://ghc.haskell.org/trac/ghc/ticket/11994

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

Re: Bikeshedding request for GHCi's :type

Iavor Diatchki
Currently GHCi shows the "real" type of an expression (i.e., the inferred generalized type), when you ask it:

Prelude> :t 1
1 :: Num a => a

Note that there is no defaulting happening, at least at the top level---of course if there were local things that needed to be defaulted while the expression was being type-checked then those would be defaulted.

If you ask GHCi to *evaluate* a polymorphic expression, then it will try to default the type when it is figuring out how to show the result.  The alternative would be to say "sorry, I can't evaluate this, because it is polymorphic, so please tell me what type do you mean".  This is probably a bit too inconvenient for practical use.

-Iavor




On Thu, Apr 28, 2016 at 5:24 AM, Johannes Waldmann <[hidden email]> wrote:
> .. :type should report the real type

What about defaulting? Is it real?
https://ghc.haskell.org/trac/ghc/ticket/11994

- J.W.
_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs


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

Re: Bikeshedding request for GHCi's :type

Johannes Waldmann-2
Hi,

> If you ask GHCi to *evaluate* a polymorphic expression, then it will ...

Sure, I understand the motivation for defaulting,
and I am not suggesting to change anything there.

What I am saying is that I see no way to have ghci show
* the defaulted type,
* or the even the fact that defaulting did happen.

- J.

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

Re: Bikeshedding request for GHCi's :type

Trevor Elliott-3
Hi,

Part of what you would like is already there. If you run ghci with -Wall, you will get warnings about defaulting polymorphic expressions.

```
Prelude> 1

<interactive>:2:1: Warning:
    Defaulting the following constraint(s) to type ‘Integer’
      (Num a0) arising from a use of ‘it’ at <interactive>:2:1
      (Show a0) arising from a use of ‘print’ at <interactive>:2:1
    In the first argument of ‘print’, namely ‘it’
    In a stmt of an interactive GHCi command: print it
1
Prelude>
```

--trevor

On Thu, Apr 28, 2016 at 8:05 AM Johannes Waldmann <[hidden email]> wrote:
Hi,

> If you ask GHCi to *evaluate* a polymorphic expression, then it will ...

Sure, I understand the motivation for defaulting,
and I am not suggesting to change anything there.

What I am saying is that I see no way to have ghci show
* the defaulted type,
* or the even the fact that defaulting did happen.

- J.

_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

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

Re: Bikeshedding request for GHCi's :type

Richard Eisenberg-2
In reply to this post by Richard Eisenberg-2
I have collected feedback gleaned here, on the ticket, and on reddit and summarized here: https://ghc.haskell.org/trac/ghc/wiki/Design/GHCi/Type#Summaryoffeedbackaboutthisissue

That summary includes this concrete proposal:
 1. Ask for concrete suggestions about names for the new commands.
 2. Use these names on my current implementation (which prints out only one specialization)
 3. Post a feature request looking for more specializations.

I simply don't have time to specify a design or implement an algorithm for printing out multiple specializations. Furthermore, my current implementation meets all specifications proffered for printing out multiple specializations, for all values of "multiple" that equal 1. It is easy to extend later.

Separately, there is a groundswell of support for :doc, but that's beyond the scope of my work on this point. (I personally would love :doc, too.)

So, what shall we name the two new commands?

1. A new command that specializes a type. (Currently with one specialization, but perhaps more examples in the future.)

2. A new command that preserves specialized type variables so that users of TypeApplications know what type parameters to pass in next.

I have suggested :type-def for (1) and :type-spec for (2). I don't strongly like either. :examples and :inst have been suggested for (1). Any other ideas?

Thanks!
Richard

On Apr 26, 2016, at 9:08 AM, Richard Eisenberg <[hidden email]> wrote:

> Hi devs,
>
> Over the weekend, I was pondering the Haskell course I will be teaching next year and shuddered at having to teach Foldable at the same time as `length`. So I implemented feature request #10963 (https://ghc.haskell.org/trac/ghc/ticket/10963), which allows for a way for a user to request a specialization of a type. It all works wonderfully, but there is a real user-facing design issue here around the default behavior of :type and whether or not to add new :type-y like commands. I have outlined the situation here: https://ghc.haskell.org/trac/ghc/wiki/Design/GHCi/Type
>
> I'd love some broad input on this issue. If you've got a stake in how this all works, please skim that wiki page and comment on #10963.
>
> Thanks!
> Richard
> _______________________________________________
> ghc-devs mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

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

Re: [Haskell-cafe] Bikeshedding request for GHCi's :type

Takenobu Tani
Hi Richard,

I like your decision and plan.
Thank you a lot of work, for community.


About new command name for (1): 

Most users, perhaps, have entered the `:t` rather than `:type`.

  ghci> :t  length

In the same way, how about a full name and abbreviation name for (1).
For example, we prepare `:type-default` and `:td`.

  ghci> :td  length

So they don't misunderstand that it is "typedef".


I also like `:type!` and `:types` with Jack :)

  ghci> :t!  length


Regards,
Takenobu


2016-05-03 5:10 GMT+09:00 Richard Eisenberg <[hidden email]>:
I have collected feedback gleaned here, on the ticket, and on reddit and summarized here: https://ghc.haskell.org/trac/ghc/wiki/Design/GHCi/Type#Summaryoffeedbackaboutthisissue

That summary includes this concrete proposal:
 1. Ask for concrete suggestions about names for the new commands.
 2. Use these names on my current implementation (which prints out only one specialization)
 3. Post a feature request looking for more specializations.

I simply don't have time to specify a design or implement an algorithm for printing out multiple specializations. Furthermore, my current implementation meets all specifications proffered for printing out multiple specializations, for all values of "multiple" that equal 1. It is easy to extend later.

Separately, there is a groundswell of support for :doc, but that's beyond the scope of my work on this point. (I personally would love :doc, too.)

So, what shall we name the two new commands?

1. A new command that specializes a type. (Currently with one specialization, but perhaps more examples in the future.)

2. A new command that preserves specialized type variables so that users of TypeApplications know what type parameters to pass in next.

I have suggested :type-def for (1) and :type-spec for (2). I don't strongly like either. :examples and :inst have been suggested for (1). Any other ideas?

Thanks!
Richard

On Apr 26, 2016, at 9:08 AM, Richard Eisenberg <[hidden email]> wrote:

> Hi devs,
>
> Over the weekend, I was pondering the Haskell course I will be teaching next year and shuddered at having to teach Foldable at the same time as `length`. So I implemented feature request #10963 (https://ghc.haskell.org/trac/ghc/ticket/10963), which allows for a way for a user to request a specialization of a type. It all works wonderfully, but there is a real user-facing design issue here around the default behavior of :type and whether or not to add new :type-y like commands. I have outlined the situation here: https://ghc.haskell.org/trac/ghc/wiki/Design/GHCi/Type
>
> I'd love some broad input on this issue. If you've got a stake in how this all works, please skim that wiki page and comment on #10963.
>
> Thanks!
> Richard
> _______________________________________________
> ghc-devs mailing list
> [hidden email]
> http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs

_______________________________________________
Haskell-Cafe mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe


_______________________________________________
ghc-devs mailing list
[hidden email]
http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs