relaxing instance declarations

2013-04-28 Thread Doug McIlroy
Is there any strong reason why the where clause in an instance 
declaration cannot declare anything other than class
operators? If not, I suggest relaxing the restriction.

It is not unusual for declarations of class operators to
refer to special auxiliary functions. Under current rules
such functions have to be declared outside the scope in
which they are used.

Doug McIlroy

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: relaxing instance declarations

2013-04-28 Thread Edward Kmett
You can always put those helper functions in the class and then just not
export them from the module.


On Sun, Apr 28, 2013 at 10:49 AM, Doug McIlroy wrote:

> Is there any strong reason why the where clause in an instance
> declaration cannot declare anything other than class
> operators? If not, I suggest relaxing the restriction.
>
> It is not unusual for declarations of class operators to
> refer to special auxiliary functions. Under current rules
> such functions have to be declared outside the scope in
> which they are used.
>
> Doug McIlroy
>
> ___
> Haskell-prime mailing list
> Haskell-prime@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-prime
>
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: relaxing instance declarations

2013-04-28 Thread Doug McIlroy
Not always. For example, you can't mess with the declaration
of a standard class, such as Num.

On Sun, Apr 28, 2013 at 12:06 PM, Edward Kmett  wrote:

> You can always put those helper functions in the class and then just not
> export them from the module.

On Sun, Apr 28, 2013 at 10:49 AM, Doug McIlroy wrote:

> Is there any strong reason why the where clause in an instance
> declaration cannot declare anything other than class
> operators? If not, I suggest relaxing the restriction.
>
> It is not unusual for declarations of class operators to
> refer to special auxiliary functions. Under current rules
> such functions have to be declared outside the scope in
> which they are used.
>
> Doug McIlroy

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: relaxing instance declarations

2013-04-28 Thread Edward Kmett
Makes sense. I'm not sure what a good syntactic story would be for that feature 
though. Just writing down member names that aren't in the class seems to be too 
brittle and error prone, and new keywords seems uglier than the current 
situation.

Sent from my iPad

On Apr 28, 2013, at 1:24 PM, Doug McIlroy  wrote:

> Not always. For example, you can't mess with the declaration
> of a standard class, such as Num.
> 
> On Sun, Apr 28, 2013 at 12:06 PM, Edward Kmett  wrote:
> 
>> You can always put those helper functions in the class and then just not
>> export them from the module.
> 
> On Sun, Apr 28, 2013 at 10:49 AM, Doug McIlroy wrote:
> 
>> Is there any strong reason why the where clause in an instance
>> declaration cannot declare anything other than class
>> operators? If not, I suggest relaxing the restriction.
>> 
>> It is not unusual for declarations of class operators to
>> refer to special auxiliary functions. Under current rules
>> such functions have to be declared outside the scope in
>> which they are used.
>> 
>> Doug McIlroy

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: relaxing instance declarations

2013-04-29 Thread Max Bolingbroke
You could probably get away with just using two "where" clauses:

instance Foo a where
bar = ...
  where
auxilliary = ...




On 28 April 2013 18:42, Edward Kmett  wrote:

> Makes sense. I'm not sure what a good syntactic story would be for that
> feature though. Just writing down member names that aren't in the class
> seems to be too brittle and error prone, and new keywords seems uglier than
> the current situation.
>
> Sent from my iPad
>
> On Apr 28, 2013, at 1:24 PM, Doug McIlroy  wrote:
>
> > Not always. For example, you can't mess with the declaration
> > of a standard class, such as Num.
> >
> > On Sun, Apr 28, 2013 at 12:06 PM, Edward Kmett  wrote:
> >
> >> You can always put those helper functions in the class and then just not
> >> export them from the module.
> >
> > On Sun, Apr 28, 2013 at 10:49 AM, Doug McIlroy  >wrote:
> >
> >> Is there any strong reason why the where clause in an instance
> >> declaration cannot declare anything other than class
> >> operators? If not, I suggest relaxing the restriction.
> >>
> >> It is not unusual for declarations of class operators to
> >> refer to special auxiliary functions. Under current rules
> >> such functions have to be declared outside the scope in
> >> which they are used.
> >>
> >> Doug McIlroy
>
> ___
> Haskell-prime mailing list
> Haskell-prime@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-prime
>
>
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: relaxing instance declarations

2013-04-29 Thread Iavor Diatchki
Hello,

I think that if we want something along those lines, we should consider a
more general construct that allows declarations to scope over other
declarations (like SML's `local` construct).  It would be quite arbitrary
to restrict this only to instances.

-Iavor



On Mon, Apr 29, 2013 at 2:41 PM, Max Bolingbroke  wrote:

> You could probably get away with just using two "where" clauses:
>
> instance Foo a where
> bar = ...
>   where
> auxilliary = ...
>
>
>
>
> On 28 April 2013 18:42, Edward Kmett  wrote:
>
>> Makes sense. I'm not sure what a good syntactic story would be for that
>> feature though. Just writing down member names that aren't in the class
>> seems to be too brittle and error prone, and new keywords seems uglier than
>> the current situation.
>>
>> Sent from my iPad
>>
>> On Apr 28, 2013, at 1:24 PM, Doug McIlroy  wrote:
>>
>> > Not always. For example, you can't mess with the declaration
>> > of a standard class, such as Num.
>> >
>> > On Sun, Apr 28, 2013 at 12:06 PM, Edward Kmett 
>> wrote:
>> >
>> >> You can always put those helper functions in the class and then just
>> not
>> >> export them from the module.
>> >
>> > On Sun, Apr 28, 2013 at 10:49 AM, Doug McIlroy > >wrote:
>> >
>> >> Is there any strong reason why the where clause in an instance
>> >> declaration cannot declare anything other than class
>> >> operators? If not, I suggest relaxing the restriction.
>> >>
>> >> It is not unusual for declarations of class operators to
>> >> refer to special auxiliary functions. Under current rules
>> >> such functions have to be declared outside the scope in
>> >> which they are used.
>> >>
>> >> Doug McIlroy
>>
>> ___
>> Haskell-prime mailing list
>> Haskell-prime@haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-prime
>>
>>
>
> ___
> Haskell-prime mailing list
> Haskell-prime@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-prime
>
>
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: relaxing instance declarations

2013-04-30 Thread Doug McIlroy
Max's idea (see below) of a second where clause is cute, but
not sanctioned by Haskell syntax.

Iavor wrote, "It would be quite arbitrary to restrict this only
to instances."

Actually what I have in mind is to make the language MORE
consistent, by eliminating distinctions between instance-wheres
and ordinary declaration-wheres.  Currently instance-wheres may
only declare class methods, while declaration-wheres may declare
variables at will.  Also instance-wheres may not declare type
signatures, while declaration-wheres may.  I propose dropping
these restrictions on instance-wheres.

Hazard: Adding a method to an existing class could accidentally
capture a name that was previously local to an instance-where.
Capture can be prevented by declaring type signatures for local
variables.  The compiler might warn when such defensive
declarations are lacking.

Doug

On Mon, 29 Apr 2013 15:56 Iavor Diatchki  wrote

Hello,

I think that if we want something along those lines, we should consider a
more general construct that allows declarations to scope over other
declarations (like SML's `local` construct).  It would be quite arbitrary
to restrict this only to instances.

-Iavor



On Mon, Apr 29, 2013 at 2:41 PM, Max Bolingbroke  wrote:

> You could probably get away with just using two "where" clauses:
>
> instance Foo a where
> bar = ...
>   where
> auxilliary = ...
>
>
>
>
> On 28 April 2013 18:42, Edward Kmett  wrote:
>
>> Makes sense. I'm not sure what a good syntactic story would be for that
>> feature though. Just writing down member names that aren't in the class
>> seems to be too brittle and error prone, and new keywords seems uglier than
>> the current situation.
>>
>> Sent from my iPad
>>
>> On Apr 28, 2013, at 1:24 PM, Doug McIlroy  wrote:
>>
>> > Not always. For example, you can't mess with the declaration
>> > of a standard class, such as Num.
>> >
>> > On Sun, Apr 28, 2013 at 12:06 PM, Edward Kmett 
>> wrote:
>> >
>> >> You can always put those helper functions in the class and then just
>> not
>> >> export them from the module.
>> >
>> > On Sun, Apr 28, 2013 at 10:49 AM, Doug McIlroy > >wrote:
>> >
>> >> Is there any strong reason why the where clause in an instance
>> >> declaration cannot declare anything other than class
>> >> operators? If not, I suggest relaxing the restriction.
>> >>
>> >> It is not unusual for declarations of class operators to
>> >> refer to special auxiliary functions. Under current rules
>> >> such functions have to be declared outside the scope in
>> >> which they are used.
>> >>
>> >> Doug McIlroy
>>
>> ___
>> Haskell-prime mailing list
>> Haskell-prime@haskell.org
>> http://www.haskell.org/mailman/listinfo/haskell-prime
>>
>>
>
> ___
> Haskell-prime mailing list
> Haskell-prime@haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-prime
>
>

Content-Type: text/html; charset=UTF-8

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: relaxing instance declarations

2013-04-30 Thread Edward Kmett
The problem I see with this is it becomes very brittle to just silently
accept bad class member names.

Before, if I had a method

class Foo a where
  bar :: a -> Int
  bar _ = 0

and I went to implement something with a typo

instance Foo Int where
  baz = id

then I'd get an error, but your proposal it'd just silently be accepted,
and lead to to long nights searching for why my instance wasn't doing what
I expected long after I'd shipped my product.

This kind of class isn't an academic concern, many real world classes are
defined with 2-3 members circularly. Consider Foldable or Traversable.

newtype Baz = Baz a

instance Foldable Baz where
  foldmap f (Baz a) = f a

is an innocent typo that would then just mean that foldMap when applied to
Baz will silently loop forever with no warning to the programmer.
Traversable Baz behaves similarly with the cyclic between sequenceA+fmap
and traverse.

I'd argue that I've made typos on member names *far* more often than I've
wanted this feature.

In fact, I've actually tried to live with a very similar lexical scoping
design in a toy language of mine I called Kata. In Kata, you could just
introduce new members by writing them in a 'public' block, and constrain
subclasses by putting in members without definitions, but it was
sufficiently brittle that I wound up adding another syntactic construct
which could only be used to instantiate definitions not make new names.
That resolve the issue and made the language much nicer to play around in.

I'd really rather not switch from a design that is robust and usually does
the right thing to one that is more brittle and prone to introducing hard
to find bugs. =(

-Edward



On Tue, Apr 30, 2013 at 7:05 PM, Doug McIlroy  wrote:

> Max's idea (see below) of a second where clause is cute, but
> not sanctioned by Haskell syntax.
>
> Iavor wrote, "It would be quite arbitrary to restrict this only
> to instances."
>
> Actually what I have in mind is to make the language MORE
> consistent, by eliminating distinctions between instance-wheres
> and ordinary declaration-wheres.  Currently instance-wheres may
> only declare class methods, while declaration-wheres may declare
> variables at will.  Also instance-wheres may not declare type
> signatures, while declaration-wheres may.  I propose dropping
> these restrictions on instance-wheres.
>
> Hazard: Adding a method to an existing class could accidentally
> capture a name that was previously local to an instance-where.
> Capture can be prevented by declaring type signatures for local
> variables.  The compiler might warn when such defensive
> declarations are lacking.
>
> Doug
>
> On Mon, 29 Apr 2013 15:56 Iavor Diatchki  wrote
>
> Hello,
>
> I think that if we want something along those lines, we should consider a
> more general construct that allows declarations to scope over other
> declarations (like SML's `local` construct).  It would be quite arbitrary
> to restrict this only to instances.
>
> -Iavor
>
>
>
> On Mon, Apr 29, 2013 at 2:41 PM, Max Bolingbroke <
> batterseapo...@hotmail.com
> > wrote:
>
> > You could probably get away with just using two "where" clauses:
> >
> > instance Foo a where
> > bar = ...
> >   where
> > auxilliary = ...
> >
> >
> >
> >
> > On 28 April 2013 18:42, Edward Kmett  wrote:
> >
> >> Makes sense. I'm not sure what a good syntactic story would be for that
> >> feature though. Just writing down member names that aren't in the class
> >> seems to be too brittle and error prone, and new keywords seems uglier
> than
> >> the current situation.
> >>
> >> Sent from my iPad
> >>
> >> On Apr 28, 2013, at 1:24 PM, Doug McIlroy 
> wrote:
> >>
> >> > Not always. For example, you can't mess with the declaration
> >> > of a standard class, such as Num.
> >> >
> >> > On Sun, Apr 28, 2013 at 12:06 PM, Edward Kmett 
> >> wrote:
> >> >
> >> >> You can always put those helper functions in the class and then just
> >> not
> >> >> export them from the module.
> >> >
> >> > On Sun, Apr 28, 2013 at 10:49 AM, Doug McIlroy  >> >wrote:
> >> >
> >> >> Is there any strong reason why the where clause in an instance
> >> >> declaration cannot declare anything other than class
> >> >> operators? If not, I suggest relaxing the restriction.
> >> >>
> >> >> It is not unusual for declarations of class operators to
> >> >> refer to special auxiliary functions. Under current rules
> >> >> such functions have to be declared outside the scope in
> >> >> which they are used.
> >> >>
> >> >> Doug McIlroy
> >>
> >> ___
> >> Haskell-prime mailing list
> >> Haskell-prime@haskell.org
> >> http://www.haskell.org/mailman/listinfo/haskell-prime
> >>
> >>
> >
> > ___
> > Haskell-prime mailing list
> > Haskell-prime@haskell.org
> > http://www.haskell.org/mailman/listinfo/haskell-prime
> >
> >
>
> Content-Type: text/html; charset=UTF-8
>
___
Haskell-prime mai

RE: relaxing instance declarations

2013-05-02 Thread Sittampalam, Ganesh
Doug suggested this below:

 

“Capture can be prevented by declaring type signatures for local
variables.  The compiler might warn when such defensive
declarations are lacking.”

 

I think what Doug is proposing is that it be a warning *not* to include a type 
signature for any local declaration in an instance, and continue to be an error 
to provide a type signature for any class member implementation. That would 
mean that if you started warnings-free, a change in the type class that 
captured a local would always result in an error.

 

The downsides I see are that

(a)   it doesn’t seem very intuitive for the presence or absence of type 
signatures to signify whether something is local or not

(b)   GHC has a recent extension “InstanceSigs” that allows signatures to be 
given on class members

 

 

Overall I like the idea of regularizing the language and have wanted something 
like this myself in the past, but Edward’s objection feels significant to me.

 

 

From: haskell-prime-boun...@haskell.org 
[mailto:haskell-prime-boun...@haskell.org] On Behalf Of Edward Kmett
Sent: 01 May 2013 02:46
To: Doug McIlroy
Cc: haskell-prime@haskell.org Prime
Subject: Re: relaxing instance declarations

 

The problem I see with this is it becomes very brittle to just silently accept 
bad class member names.

 

Before, if I had a method

 

class Foo a where

  bar :: a -> Int

  bar _ = 0

 

and I went to implement something with a typo

 

instance Foo Int where

  baz = id

 

then I'd get an error, but your proposal it'd just silently be accepted, and 
lead to to long nights searching for why my instance wasn't doing what I 
expected long after I'd shipped my product.

 

This kind of class isn't an academic concern, many real world classes are 
defined with 2-3 members circularly. Consider Foldable or Traversable.

 

newtype Baz = Baz a

 

instance Foldable Baz where

  foldmap f (Baz a) = f a

 

is an innocent typo that would then just mean that foldMap when applied to Baz 
will silently loop forever with no warning to the programmer. Traversable Baz 
behaves similarly with the cyclic between sequenceA+fmap and traverse.

 

I'd argue that I've made typos on member names far more often than I've wanted 
this feature.

 

In fact, I've actually tried to live with a very similar lexical scoping design 
in a toy language of mine I called Kata. In Kata, you could just introduce new 
members by writing them in a 'public' block, and constrain subclasses by 
putting in members without definitions, but it was sufficiently brittle that I 
wound up adding another syntactic construct which could only be used to 
instantiate definitions not make new names. That resolve the issue and made the 
language much nicer to play around in.

 

I'd really rather not switch from a design that is robust and usually does the 
right thing to one that is more brittle and prone to introducing hard to find 
bugs. =(

 

-Edward

 

 

On Tue, Apr 30, 2013 at 7:05 PM, Doug McIlroy  wrote:

Max's idea (see below) of a second where clause is cute, but
not sanctioned by Haskell syntax.

Iavor wrote, "It would be quite arbitrary to restrict this only
to instances."

Actually what I have in mind is to make the language MORE
consistent, by eliminating distinctions between instance-wheres
and ordinary declaration-wheres.  Currently instance-wheres may
only declare class methods, while declaration-wheres may declare
variables at will.  Also instance-wheres may not declare type
signatures, while declaration-wheres may.  I propose dropping
these restrictions on instance-wheres.

Hazard: Adding a method to an existing class could accidentally
capture a name that was previously local to an instance-where.
Capture can be prevented by declaring type signatures for local
variables.  The compiler might warn when such defensive
declarations are lacking.

Doug

On Mon, 29 Apr 2013 15:56 Iavor Diatchki  wrote


Hello,

I think that if we want something along those lines, we should consider a
more general construct that allows declarations to scope over other
declarations (like SML's `local` construct).  It would be quite arbitrary
to restrict this only to instances.

-Iavor



On Mon, Apr 29, 2013 at 2:41 PM, Max Bolingbroke  wrote:

> You could probably get away with just using two "where" clauses:
>
> instance Foo a where
> bar = ...
>   where
> auxilliary = ...
>
>
>
>
> On 28 April 2013 18:42, Edward Kmett  wrote:
>
>> Makes sense. I'm not sure what a good syntactic story would be for that
>> feature though. Just writing down member names that aren't in the class
>> seems to be too brittle and error prone, and new keywords seems uglier than
>> the current situation.
>>
>> Sent from my iPad
>>
>> On Apr 28, 2013, at 1:24 PM, Doug McIlroy  wrote:
>>

Re: relaxing instance declarations

2013-05-02 Thread Ben Millwood

On Tue, Apr 30, 2013 at 09:46:01PM -0400, Edward Kmett wrote:

instance Foldable Baz where
 foldmap f (Baz a) = f a

is an innocent typo that would then just mean that foldMap when applied to
Baz will silently loop forever with no warning to the programmer.
Traversable Baz behaves similarly with the cyclic between sequenceA+fmap
and traverse.


Maybe we need a better answer for the default method cycle problem? I 
had the following vague idea one day: don't allow default definitions in 
class members. Just use things along the lines of fmapDefault, or, say, 


subtractFromPlusNegate :: (n -> n -> n) -> (n -> n) -> n -> n -> n
subtractFromPlusNegate (+!) neg a b = a +! neg b

A bit clumsier but way more explicit: no more warning-silent infinite 
loops from code you didn't even write. The only drawback is the lack of 
the ability to introduce new class methods with default definitions. 
But! Here's my second idea: use RecordWildcards and NamedFieldPuns, 
allow pattern bindings instead of just simple variables in class 
instances, and do something like this:


 data MonoidInstance m = MkMonInst
   { mempty :: m
   , mappend :: m -> m -> m
   }

 monoidFromMconcat :: ([m] -> m) -> MonoidInstance m
 monoidFromMconcat mcat = MkMonInst
   { mconcat = mcat
   , mempty = mcat []
   , mappend x y = mcat [x,y]
   }

 -- possibly slightly silly
 monoidFromMemptyMappend :: m -> (m -> m -> m) -> MonoidInstance m
 monoidFromMemptyMappend mempty mappend = MkMonInst {..}
  where
   mconcat = foldr mempty mappend

 instance Monoid [a] where
   MkMonInst {..} = monoidFromMconcat concat

Now if I later wanted to add a new method to Monoid, I could just add a 
new field to MonoidInstance and have the instance-generator functions 
produce it from the others.


Notice that this also leaves me free to have overlapping minimal 
complete definitions, which the current system doesn't – I explicitly 
state which one I am using by my choice of monoidFrom function.


Anyway, that's something of a digression. My opinion on the issue at 
hand is that I'd very much like to see a general form of 
"declaration-let" that would allow me to declare some things local to a 
group of bindings. If I understand correctly, this would make the 
specific proposal at hand redundant, and is useful in other situations 
as well.


-- Ben

___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime