Re: clonetype

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

Re: clonetype

Alex Queiroz-2
Hi,

On 24/09/18 12:42, Harendra Kumar wrote:
>
> and we are good to go.  What is the shortest possible way to achieve
> this with currently available mechanisms, if any?
>

What about GeneralizedNewtypeDeriving[1]?

[1]
https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#generalised-derived-instances-for-newtypes

Cheers,
--
-alex
https://unendli.ch/
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Oleg Grenrus
The problem is that "All instances" is hard to pin point. We have open world assumption, so instances can be added later (in the dependency tree). Should they be cloned too? And even of you restrict to "instances visible at clonetype definition", that's IMHO not a good idea either, as it's implicit and volatile set (editing imports changes may change the set).

So use either tagged-trick/pattern or GND.

Haskell's heavy type machinery exists so we can explicitly and exactly say what we need or want. Tagged/phantom-pattern and GND are different, they have different pros & cons. Having `clonetype-fits-all` seems non-trivial to me.

Sent from my iPhone

On 24 Sep 2018, at 15.25, Harendra Kumar <[hidden email]> wrote:

That comes close, but Haskell having such a heavy type machinery to do all the esoteric type stuff in the world, but not allowing you to express such a simple day to day programming thing in a simpler manner is not very satisfying.

-harendra

On Mon, 24 Sep 2018 at 16:16, Oleg Grenrus <[hidden email]> wrote:
data MyStringTag
type MyString = Tagged MyStringTag String

Sent from my iPhone

On 24 Sep 2018, at 13.42, Harendra Kumar <[hidden email]> wrote:

Often, we need to create a newtype that is equivalent to a given type for safety reasons. Using type  synonym is useless from type safety perspective. With newtype, we have to add a "deriving" clause to it for deriving the required instances, to make it practically useful.

Does it make sense, and is it possible to have something like a "clonetype" that creates a new type and derives all the instances of the parent type as well? It will be quite helpful in creating equivalent newtype synonyms quickly. Almost always, I do not use a newtype where I should just because of the inconvenience of deriving the instances. Ideally, we should just be able to say something like:

clonetype MyString = String

and we are good to go.  What is the shortest possible way to achieve this with currently available mechanisms, if any?

-harendra
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Li-yao Xia-2
Another issue with saying "derive all instances for this newtype" is
that not all instances are coercible.

type family F a where
   F Char = Int
class C a where
   f :: a -> F a
instance C Char where
   f _ = 'a'

newtype D = D Char

There is no way to derive an instance C D.

A more explicit and flexible solution would be "deriving synonyms",
discussed recently here:

https://www.reddit.com/r/haskell/comments/9dx6s9/proposal_data_deriving_synonyms/

Li-yao

On 9/24/18 8:47 AM, Oleg Grenrus wrote:

> The problem is that "All instances" is hard to pin point. We have open
> world assumption, so instances can be added later (in the dependency
> tree). Should they be cloned too? And even of you restrict to "instances
> visible at clonetype definition", that's IMHO not a good idea either, as
> it's implicit and volatile set (editing imports changes may change the set).
>
> So use either tagged-trick/pattern or GND.
>
> Haskell's heavy type machinery exists so we can explicitly and exactly
> say what we need or want. Tagged/phantom-pattern and GND are different,
> they have different pros & cons. Having `clonetype-fits-all` seems
> non-trivial to me.
>
> Sent from my iPhone
>
> On 24 Sep 2018, at 15.25, Harendra Kumar <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>> That comes close, but Haskell having such a heavy type machinery to do
>> all the esoteric type stuff in the world, but not allowing you to
>> express such a simple day to day programming thing in a simpler manner
>> is not very satisfying.
>>
>> -harendra
>>
>> On Mon, 24 Sep 2018 at 16:16, Oleg Grenrus <[hidden email]
>> <mailto:[hidden email]>> wrote:
>>
>>     data MyStringTag
>>     type MyString = Tagged MyStringTag String
>>
>>     Sent from my iPhone
>>
>>     On 24 Sep 2018, at 13.42, Harendra Kumar <[hidden email]
>>     <mailto:[hidden email]>> wrote:
>>
>>>     Often, we need to create a newtype that is equivalent to a given
>>>     type for safety reasons. Using type  synonym is useless from type
>>>     safety perspective. With newtype, we have to add a "deriving"
>>>     clause to it for deriving the required instances, to make it
>>>     practically useful.
>>>
>>>     Does it make sense, and is it possible to have something like a
>>>     "clonetype" that creates a new type and derives all the instances
>>>     of the parent type as well? It will be quite helpful in creating
>>>     equivalent newtype synonyms quickly. Almost always, I do not use
>>>     a newtype where I should just because of the inconvenience of
>>>     deriving the instances. Ideally, we should just be able to say
>>>     something like:
>>>
>>>     clonetype MyString = String
>>>
>>>     and we are good to go.  What is the shortest possible way to
>>>     achieve this with currently available mechanisms, if any?
>>>
>>>     -harendra
>>>     _______________________________________________
>>>     Haskell-Cafe mailing list
>>>     To (un)subscribe, modify options or view archives go to:
>>>     http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
>>>     Only members subscribed via the mailman list are allowed to post.
>>
>
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
>
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Stefan Monnier
In reply to this post by Alex Queiroz-2
> Does it make sense, and is it possible to have something like a "clonetype"
> that creates a new type and derives all the instances of the parent type as
> well?

Presumably, the reason why you create a newtype is because you want the
type system to distinguish the two types.  Having automatically access
to all the base type's classes may sometimes be what you want, but in
other cases it hides too much of the distinction between the two types.


        Stefan

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Harendra Kumar
In reply to this post by Oleg Grenrus


On Mon, 24 Sep 2018 at 18:17, Oleg Grenrus <[hidden email]> wrote:
The problem is that "All instances" is hard to pin point. We have open world assumption, so instances can be added later (in the dependency tree). Should they be cloned too? And even of you restrict to "instances visible at clonetype definition", that's IMHO not a good idea either, as it's implicit and volatile set (editing imports changes may change the set).

A clone type says "both the types are exactly the same in all semantics except that they cannot be used interchangeably", it is just like "type" except that the types are treated as being different. The way visible instances change for the original type by editing imports, the same way they change for the clone type as well, I do not see a problem there. However, the two types may diverge if we define more instances for any of them after cloning and that may potentially be a source of confusion?
 
Haskell's heavy type machinery exists so we can explicitly and exactly say what we need or want.

Mortal programmers would love to have "conveniently" added to that list :-)
 
-harendra

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Oleg Grenrus
On 24.09.2018 17:06, Harendra Kumar wrote:

>
>
> On Mon, 24 Sep 2018 at 18:17, Oleg Grenrus <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     The problem is that "All instances" is hard to pin point. We have
>     open world assumption, so instances can be added later (in the
>     dependency tree). Should they be cloned too? And even of you
>     restrict to "instances visible at clonetype definition", that's
>     IMHO not a good idea either, as it's implicit and volatile set
>     (editing imports changes may change the set).
>
>
> A clone type says "both the types are exactly the same in all
> semantics except that they cannot be used interchangeably", it is just
> like "type" except that the types are treated as being different. The
> way visible instances change for the original type by editing imports,
> the same way they change for the clone type as well, I do not see a
> problem there. However, the two types may diverge if we define more
> instances for any of them after cloning and that may potentially be a
> source of confusion?

If you want that, then the GeneralizedNewtypeDeriving is the solution.
It's not so convinient, as you have to list the instances you need, but
on the flip side of the coin is the "explicitness" of the deriving
clause. GHC will barf if you forget an import for an instance you want,
or if you have unused import. Often redundancy is your friend. Type
annotations very often aren't necessary, but it's good practice to write
them (e.g. for top-level definitions). So I'd say that not having
`clonetype` is a feature.

>  
>
>     Haskell's heavy type machinery exists so we can explicitly and
>     exactly say what we need or want.
>
>
> Mortal programmers would love to have "conveniently" added to that
> list :-)
>  
> -harendra
>

- Oleg

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Harendra Kumar


On Tue, 25 Sep 2018 at 01:12, Oleg Grenrus <[hidden email]> wrote:
On 24.09.2018 17:06, Harendra Kumar wrote:
>
>
> On Mon, 24 Sep 2018 at 18:17, Oleg Grenrus <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     The problem is that "All instances" is hard to pin point. We have
>     open world assumption, so instances can be added later (in the
>     dependency tree). Should they be cloned too? And even of you
>     restrict to "instances visible at clonetype definition", that's
>     IMHO not a good idea either, as it's implicit and volatile set
>     (editing imports changes may change the set).
>
>
> A clone type says "both the types are exactly the same in all
> semantics except that they cannot be used interchangeably", it is just
> like "type" except that the types are treated as being different. The
> way visible instances change for the original type by editing imports,
> the same way they change for the clone type as well, I do not see a
> problem there. However, the two types may diverge if we define more
> instances for any of them after cloning and that may potentially be a
> source of confusion?

If you want that, then the GeneralizedNewtypeDeriving is the solution.
It's not so convinient, as you have to list the instances you need, but
on the flip side of the coin is the "explicitness" of the deriving
clause. GHC will barf if you forget an import for an instance you want,
or if you have unused import. Often redundancy is your friend. Type
annotations very often aren't necessary, but it's good practice to write
them (e.g. for top-level definitions). So I'd say that not having
`clonetype` is a feature.

 
That's where I started. I already use a newtype with GND for this, and it looks like this:

newtype Count = Count Int64
    deriving ( Eq
             , Read
             , Show
             , Enum
             , Bounded
             , Num
             , Real
             , Integral
             , Ord
             )

The problem is that most programmers are lazy or hard pressed for time and having to write a newtype with a big list of instances actually discourages the use of newtypes freely for this case, they may just make it a habit to let it go. We can't just deny this and say that programmers must be disciplined. They will often try taking the path of least effort. So in practice I am not sure what is better, being explicit or encouraging the use of distinct types and potentially avoiding bugs by doing so. What kind of actual problems/bugs may arise by not being explicit in this particular case?

-harendra

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Levent Erkok
If you're OK with a little template Haskell and standalone-deriving, then you can use the trick discussed here:

  https://stackoverflow.com/questions/45113205/is-there-a-way-to-shorten-this-deriving-clause

Here's a concrete implementation in my case:


And a use-case:


Without that trick, the line would've looked like almost like what you had to write with `Count`.

I've used this trick for quite some time now, and it's both cheap and quite effective. I agree that a directly supported `deriving` syntax would be nicer, but TH fits the bill well here.

-Levent.

On Mon, Sep 24, 2018 at 1:36 PM Harendra Kumar <[hidden email]> wrote:


On Tue, 25 Sep 2018 at 01:12, Oleg Grenrus <[hidden email]> wrote:
On 24.09.2018 17:06, Harendra Kumar wrote:
>
>
> On Mon, 24 Sep 2018 at 18:17, Oleg Grenrus <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     The problem is that "All instances" is hard to pin point. We have
>     open world assumption, so instances can be added later (in the
>     dependency tree). Should they be cloned too? And even of you
>     restrict to "instances visible at clonetype definition", that's
>     IMHO not a good idea either, as it's implicit and volatile set
>     (editing imports changes may change the set).
>
>
> A clone type says "both the types are exactly the same in all
> semantics except that they cannot be used interchangeably", it is just
> like "type" except that the types are treated as being different. The
> way visible instances change for the original type by editing imports,
> the same way they change for the clone type as well, I do not see a
> problem there. However, the two types may diverge if we define more
> instances for any of them after cloning and that may potentially be a
> source of confusion?

If you want that, then the GeneralizedNewtypeDeriving is the solution.
It's not so convinient, as you have to list the instances you need, but
on the flip side of the coin is the "explicitness" of the deriving
clause. GHC will barf if you forget an import for an instance you want,
or if you have unused import. Often redundancy is your friend. Type
annotations very often aren't necessary, but it's good practice to write
them (e.g. for top-level definitions). So I'd say that not having
`clonetype` is a feature.

 
That's where I started. I already use a newtype with GND for this, and it looks like this:

newtype Count = Count Int64
    deriving ( Eq
             , Read
             , Show
             , Enum
             , Bounded
             , Num
             , Real
             , Integral
             , Ord
             )

The problem is that most programmers are lazy or hard pressed for time and having to write a newtype with a big list of instances actually discourages the use of newtypes freely for this case, they may just make it a habit to let it go. We can't just deny this and say that programmers must be disciplined. They will often try taking the path of least effort. So in practice I am not sure what is better, being explicit or encouraging the use of distinct types and potentially avoiding bugs by doing so. What kind of actual problems/bugs may arise by not being explicit in this particular case?

-harendra
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Harendra Kumar
Since this is a basic use case, I was originally looking for a language solution that is extremely easy to use, intuitive and can be used by newcomers without having to learn the tricks. The TH solution solves the repetition problem, but not the initial inertia to use it, and we will have to use TH in almost all our programs. The deriving synonym extension that Li-yao mentioned earlier is perhaps a better solution than TH if implemented.

-harendra

On Tue, 25 Sep 2018 at 02:13, Levent Erkok <[hidden email]> wrote:
If you're OK with a little template Haskell and standalone-deriving, then you can use the trick discussed here:

  https://stackoverflow.com/questions/45113205/is-there-a-way-to-shorten-this-deriving-clause

Here's a concrete implementation in my case:


And a use-case:


Without that trick, the line would've looked like almost like what you had to write with `Count`.

I've used this trick for quite some time now, and it's both cheap and quite effective. I agree that a directly supported `deriving` syntax would be nicer, but TH fits the bill well here.

-Levent.

On Mon, Sep 24, 2018 at 1:36 PM Harendra Kumar <[hidden email]> wrote:


On Tue, 25 Sep 2018 at 01:12, Oleg Grenrus <[hidden email]> wrote:
On 24.09.2018 17:06, Harendra Kumar wrote:
>
>
> On Mon, 24 Sep 2018 at 18:17, Oleg Grenrus <[hidden email]
> <mailto:[hidden email]>> wrote:
>
>     The problem is that "All instances" is hard to pin point. We have
>     open world assumption, so instances can be added later (in the
>     dependency tree). Should they be cloned too? And even of you
>     restrict to "instances visible at clonetype definition", that's
>     IMHO not a good idea either, as it's implicit and volatile set
>     (editing imports changes may change the set).
>
>
> A clone type says "both the types are exactly the same in all
> semantics except that they cannot be used interchangeably", it is just
> like "type" except that the types are treated as being different. The
> way visible instances change for the original type by editing imports,
> the same way they change for the clone type as well, I do not see a
> problem there. However, the two types may diverge if we define more
> instances for any of them after cloning and that may potentially be a
> source of confusion?

If you want that, then the GeneralizedNewtypeDeriving is the solution.
It's not so convinient, as you have to list the instances you need, but
on the flip side of the coin is the "explicitness" of the deriving
clause. GHC will barf if you forget an import for an instance you want,
or if you have unused import. Often redundancy is your friend. Type
annotations very often aren't necessary, but it's good practice to write
them (e.g. for top-level definitions). So I'd say that not having
`clonetype` is a feature.

 
That's where I started. I already use a newtype with GND for this, and it looks like this:

newtype Count = Count Int64
    deriving ( Eq
             , Read
             , Show
             , Enum
             , Bounded
             , Num
             , Real
             , Integral
             , Ord
             )

The problem is that most programmers are lazy or hard pressed for time and having to write a newtype with a big list of instances actually discourages the use of newtypes freely for this case, they may just make it a habit to let it go. We can't just deny this and say that programmers must be disciplined. They will often try taking the path of least effort. So in practice I am not sure what is better, being explicit or encouraging the use of distinct types and potentially avoiding bugs by doing so. What kind of actual problems/bugs may arise by not being explicit in this particular case?

-harendra
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Evan Laforge
In reply to this post by Harendra Kumar
For some reason I thought ConstraintKinds would let you do:

type UsualStuff a = (Eq a, Read a, ...)
newtype .. deriving (UsualStuff)

No such luck apparently!
On Mon, Sep 24, 2018 at 1:36 PM Harendra Kumar <[hidden email]> wrote:

>
>
>
> On Tue, 25 Sep 2018 at 01:12, Oleg Grenrus <[hidden email]> wrote:
>>
>> On 24.09.2018 17:06, Harendra Kumar wrote:
>> >
>> >
>> > On Mon, 24 Sep 2018 at 18:17, Oleg Grenrus <[hidden email]
>> > <mailto:[hidden email]>> wrote:
>> >
>> >     The problem is that "All instances" is hard to pin point. We have
>> >     open world assumption, so instances can be added later (in the
>> >     dependency tree). Should they be cloned too? And even of you
>> >     restrict to "instances visible at clonetype definition", that's
>> >     IMHO not a good idea either, as it's implicit and volatile set
>> >     (editing imports changes may change the set).
>> >
>> >
>> > A clone type says "both the types are exactly the same in all
>> > semantics except that they cannot be used interchangeably", it is just
>> > like "type" except that the types are treated as being different. The
>> > way visible instances change for the original type by editing imports,
>> > the same way they change for the clone type as well, I do not see a
>> > problem there. However, the two types may diverge if we define more
>> > instances for any of them after cloning and that may potentially be a
>> > source of confusion?
>>
>> If you want that, then the GeneralizedNewtypeDeriving is the solution.
>> It's not so convinient, as you have to list the instances you need, but
>> on the flip side of the coin is the "explicitness" of the deriving
>> clause. GHC will barf if you forget an import for an instance you want,
>> or if you have unused import. Often redundancy is your friend. Type
>> annotations very often aren't necessary, but it's good practice to write
>> them (e.g. for top-level definitions). So I'd say that not having
>> `clonetype` is a feature.
>>
>
> That's where I started. I already use a newtype with GND for this, and it looks like this:
>
> newtype Count = Count Int64
>     deriving ( Eq
>              , Read
>              , Show
>              , Enum
>              , Bounded
>              , Num
>              , Real
>              , Integral
>              , Ord
>              )
>
> The problem is that most programmers are lazy or hard pressed for time and having to write a newtype with a big list of instances actually discourages the use of newtypes freely for this case, they may just make it a habit to let it go. We can't just deny this and say that programmers must be disciplined. They will often try taking the path of least effort. So in practice I am not sure what is better, being explicit or encouraging the use of distinct types and potentially avoiding bugs by doing so. What kind of actual problems/bugs may arise by not being explicit in this particular case?
>
> -harendra
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Wolfgang Jeltsch-3
In reply to this post by Harendra Kumar
Am Dienstag, den 25.09.2018, 02:05 +0530 schrieb Harendra Kumar:
That's where I started. I already use a newtype with GND for this, and it looks like this:

newtype Count = Count Int64
    deriving ( Eq
             , Read
             , Show
             , Enum
             , Bounded
             , Num
             , Real
             , Integral
             , Ord
             )

The problem is that most programmers are lazy or hard pressed for time and having to write a newtype with a big list of instances actually discourages the use of newtypes freely for this case, they may just make it a habit to let it go. We can't just deny this and say that programmers must be disciplined. They will often try taking the path of least effort.

I think that the time it takes to come up with and write down such explicit lists is usually small compared to the time it takes to do all the other development. And once you have made the instantiation lists explicit, you will probably save time in the future, because bugs will detected automatically more often. The latter point is something that is often overlooked: people are under time pressure and strive for quick solutions but spend more time in the long run this way.

All the best,
Wolfgang

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Harendra Kumar

On Wed, 26 Sep 2018 at 18:11, Wolfgang Jeltsch <[hidden email]> wrote:
Am Dienstag, den 25.09.2018, 02:05 +0530 schrieb Harendra Kumar:
That's where I started. I already use a newtype with GND for this, and it looks like this:

newtype Count = Count Int64
    deriving ( Eq
             , Read
             , Show
             , Enum
             , Bounded
             , Num
             , Real
             , Integral
             , Ord
             )

The problem is that most programmers are lazy or hard pressed for time and having to write a newtype with a big list of instances actually discourages the use of newtypes freely for this case, they may just make it a habit to let it go. We can't just deny this and say that programmers must be disciplined. They will often try taking the path of least effort.

I think that the time it takes to come up with and write down such explicit lists is usually small compared to the time it takes to do all the other development. And once you have made the instantiation lists explicit, you will probably save time in the future, because bugs will detected automatically more often. The latter point is something that is often overlooked: people are under time pressure and strive for quick solutions but spend more time in the long run this way.

Two quick thoughts:

1) Nobody has pointed out what kind of bugs (with specific examples) will arise if we have something like clonetype. Are those bugs more dangerous or will consume more time compared to what we are trying to avoid in the first place? I am just trying to learn more about it, not claiming that this is better.

2) It is a real unsolvable problem that people take shortcuts when available, people will be people; this is also one of the reasons why Haskell is not so successful, other languages are easy in the short run. If we accept that this a fact of life, we have two options in general, (1) provide a safer shorter route so that we automatically choose that one (2) close the unsafe shorter route to force ourselves to choose the safe one. I was trying to explore if there is a solution on the lines of the first option. The second option means that we should not allow two arguments of the same type in a function, forcing them to always make a newtype, perhaps a much more draconian solution and not worth the pain.

-harendra
 

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.
Reply | Threaded
Open this post in threaded view
|

Re: clonetype

Sven Panne-2
Am Mi., 26. Sep. 2018 um 16:50 Uhr schrieb Harendra Kumar <[hidden email]>:
1) Nobody has pointed out what kind of bugs (with specific examples) will arise if we have something like clonetype. Are those bugs more dangerous or will consume more time compared to what we are trying to avoid in the first place? I am just trying to learn more about it, not claiming that this is better.

I think the main danger here is that it is totally unclear what actually gets derived. Is there a written specification of what actually should be derived? How would such an extension interact with other already existing extensions and separate compilation/instances added at a later time? If this can't be specified exactly, concisely and intuitively, you *will* have a maintenance nightmare, just like with all implicit things.

2) It is a real unsolvable problem that people take shortcuts when available,

No, this is not unsolvable. People, especially newcomers to writing SW, must be educated, otherwise they will have to repeat the mistakes already made by lots of other people (a.k.a. "learning the hard way"):

   * What initially looks like a good cunning idea and/or like a shortcut will almost always turn out to be a nightmare later during maintenance and debugging.

   * Explicit is better than implicit. Note that this doesn't necessarily mean that you have to repeat yourself.

   * Only a tiny amount (I think I've read 5-10% several times) of time is actually spent programming things, the rest is spent understanding the problem, reading code (from other people or often even worse: your former past ;-), debugging and extending existing SW. Trying to optimize for the tiny fraction doesn't look like a good idea. This manifests in the mantra: "A good programming language doesn't make it easy to write correct SW, it makes it hard to write incorrect SW."
 
people will be people; this is also one of the reasons why Haskell is not so successful, other languages are easy in the short run. If we accept that this a fact of life, [...]

This shouldn't easily be accepted, quite the opposite. A lot of users of "easy" and "concise" programming languages have learned the hard way that their beloved language doesn't scale at all, leading to the development of TypeScript (extending JavaScript), mypy (extending Python), Hack (extending PHP), etc.  What can be accepted as a fact of life is that there is often a tempting short route which is totally fine for throw-away scripts, quick hacks, etc., and there is a longer route, investing into the future. You have to choose...
 
Coming back to the problem at hand: Even if we find a way to factor out the deriving-clauses to stay explicit, e.g. via the deriving synonyms proposal, I am not so sure if this is a good idea. How can you be sure when changing such a synonym that *all* affected types should really be changed? This would again be a maintenance nightmare.

_______________________________________________
Haskell-Cafe mailing list
To (un)subscribe, modify options or view archives go to:
http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
Only members subscribed via the mailman list are allowed to post.