Re: Local definitions in the class instances

2011-01-27 Thread Nick Bowler
On 2011-01-27 13:07 +0200, Boris Lykah wrote:
> I think it would be convenient to allow adding variables and
> functions, which are not members of the class,  to a class instance so
> that they are visible only in the instance scope. It will help if the
> same functions are used by several class functions.
> 
> Example:
> When implementing Num class for my datatype, I found that I routinely
> do unwrapping in each operator definition. I extracted it into
> functions, but as they are used only in instance definition, I want to
> put them there and restrict them to that scope. It would be neater
> than leaving them in the global scope or copypasting into each
> operator.

One problem with this proposal is that it hurts modularity, as there is
no distinction in the instance declarations between the definitions of
"instance-local" functions and those of class methods.

This means that you cannot add new methods to an existing class
(together with a default implementation in terms of the existing
methods) without potentially breaking the existing instances.

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)

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


Re: new keyword: infixlr?

2010-09-13 Thread Nick Bowler
On 2010-09-10 19:13 +0100, Ian Lynagh wrote:
> When first reading the proposal, I thought the idea was to allow the
> compiler to more easily perform optimisations like
> a+b+c+2+3+d => a+b+c+5+d

Of course, since I don't think fixity can be specified per-instance of
Num, one would not be able to use this proposal for this; not all Num
instances have an associative (+).

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: Second draft of the Haskell 2010 report available

2010-07-06 Thread Nick Bowler
On 16:01 Tue 29 Jun , Simon Marlow wrote:
> Comments on the draft report are welcome, before I finalise this and 
> sign off on Haskell 2010.

Part II, "The Haskell 2010 Libraries", appears to be completely missing
the Numeric module.

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: RFC: Fixing floating point conversions.

2010-02-26 Thread Nick Bowler
On 14:23 Thu 25 Feb , John Meacham wrote:
> On Thu, Feb 25, 2010 at 10:40:48AM -0500, Nick Bowler wrote:
> > *** Idea #1 ***
> > 
> > Add two methods to the RealFloat class:
> > 
> >   toDouble   :: RealFloat a => a -> Double
> >   fromDouble :: RealFloat a => Double -> a
> > 
> > and a function:
> > 
> >   toFloating :: (RealFloat a, RealFloat b) => a -> b
> >   toFloating = fromDouble . toDouble
> 
> That is exactly how I solved it in the jhc libraries. 
> 
> Though, I may switch to using a 'FloatMax' type that is always aliased
> to the largest floating point type available, now that Float128 and
> Float80 are potentially available. (but it would just be an alias for
> Double for now)

Indeed, a type alias sounds like a good improvement to idea #1 for
exactly the reasons that you mention.

However, for an actual amendment to the standard, I'd like to see a
solution which allows libraries to define their own instances of the
numeric classes.  Imagine that someone wants to create a library which
implements decimal floating point arithmetic.  With something like
toDouble or toFloatMax, the author is faced with two major obstacles:
 
  * After creating new types, 'FloatMax' (which can't be redefined)
might not be the "max" anymore.
  * When 'FloatMax' has a different radix, there is going to be
loss of information when converting to it.  For example, 1/5 is
exactly representable in decimal floating point, but not in binary
floating point with any finite number of significand digits.

The end result is that 'toFloating' is not suitable for the decimal
floating point library, so the author would have to invent her own
conversion method.

It is for this reason that I prefer something along the lines of idea #2
with a "generic" intermediate type.  Nevertheless, #1 (with or without
FloatMax) is still a /huge/ improvement over the status quo.

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: RFC: Fixing floating point conversions.

2010-02-25 Thread Nick Bowler
On 17:30 Thu 25 Feb , Christian Maeder wrote:
> Nick Bowler schrieb:
> > *** Idea #2 ***
> > 
> > Similar to #1, except using a "generic" type instead of Double.
> > 
> > Define a new type, call it FloatConvert, which represents "rational plus
> > other values".  Something along the lines of:
> > 
> >   data FloatConvert
> >   = FCZero Bool   -- Signed zero
> >   | FCInfinity Bool   -- Signed infinity
> >   | FCNaN Integer -- Generic NaN
> >   | FCFinite Rational -- Finite, non-zero value
> 
> interesting. What is the Integer in FCNaN for?

Many floating point formats have multiple NaNs.  In the IEEE 754 binary
formats, a NaN is specified by a maximum exponent and *any* non-zero
significand.  The extra bits are sometimes used for diagnostic
information.  There are signaling and quiet NaNs, and they have a sign
bit.  IEEE 754 recommends that operations involving NaNs preserve as
much of this information as possible.

I chose Integer since it can encode all of this information.  It is
desirable for conversions from a type to itself to be the identity
function, even in the presence of multiple NaNs.  I'm sure many other
encodings are workable.

> >   * While the free-form encoding of NaN values will allow conversion
> > from a type to itself to be the identity function, it may make
> > it tricky to perform the "ideal" conversion between different
> > types.
> 
> I don't understand this last point about "free-form encoding of NaN"

It's free-form in that, as I specified it, it's up to the particular
RealFloat instance to decide how the Integer is used.  This might make
conversions which preserve, say, signaling NaNs trickier to implement.

> I would come up with a data type like:
> 
>   data ExtNum a
> = NegativeZero
> | NaN
> | Infinity Bool
> | Num a
> 
> add instances for the classes, Eq, Ord, Num, 
> (depending on "a" that must be at least from the class Num for "0")
> 
> and use "ExtNum Rational" for floating point conversions.

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


RFC: Fixing floating point conversions.

2010-02-25 Thread Nick Bowler
Currently, Haskell does not provide any mechanism for converting one
floating type to another, since realToFrac appears to be fundamentally
broken in this regard.  For details on that matter, see the discussion
at http://hackage.haskell.org/trac/ghc/ticket/3676.  Essentially,
realToFrac does not preserve floating values which are not representable
as a Rational.

I'd like to start discussing improvements to this situation by
submitting some ideas which I have considered for comments.  First
though, two proposals:

* Codify a requirement that Double values are a superset of Float
  values.  C demands this, as it makes it possible to define Float to
  Double conversions as value-preserving.  I couldn't find such a
  statement in the report; idea #1 below requires this.

* Define toRational as throwing an exception on non-finite input.
  Infinities magically turning into integers is simply not nice.  I
  personally feel that floating types should not be instances of the
  Real class, but that discussion can be saved for another day.

*** Idea #0 ***

Fix realToFrac.

This seems to be impossible without highly undesirable consequences, see
the trac ticket linked above for details.

*** Idea #1 ***

Add two methods to the RealFloat class:

  toDouble   :: RealFloat a => a -> Double
  fromDouble :: RealFloat a => Double -> a

and a function:

  toFloating :: (RealFloat a, RealFloat b) => a -> b
  toFloating = fromDouble . toDouble

Advantages:
  * No extensions (other than this one) beyond Haskell 98 are required.
  * Simple to define instances, exactly two functions per floating type.
  * Trivial to implement.

Disadvantages:
  * It encodes directly into the RealFloat class the knowledge that
Double can represent values of any other floating type.  This
makes it difficult or impossible to create new floating types later.

*** Idea #2 ***

Similar to #1, except using a "generic" type instead of Double.

Define a new type, call it FloatConvert, which represents "rational plus
other values".  Something along the lines of:

  data FloatConvert
  = FCZero Bool   -- Signed zero
  | FCInfinity Bool   -- Signed infinity
  | FCNaN Integer -- Generic NaN
  | FCFinite Rational -- Finite, non-zero value

Add two new methods to the RealFloat class:

  toFloatConvert   :: RealFloat a => a -> FloatConvert
  fromFloatConvert :: RealFloat a => FloatConvert -> a

and a function:

  toFloating :: (RealFloat a, RealFloat b) => a -> b
  toFloating = fromFloatConvert . toFloatConvert

Advantages:
  * No extensions (other than this one) beyond Haskell 98 are required.
  * Simple to define instances, exactly two functions per floating type.
  * Easy to add floating types to the language, and easy for users to
define their own in libraries.

Disadvantages:
  * A data type whose sole purpose is to convert floating types seems
like a wart.
  * While the free-form encoding of NaN values will allow conversion
from a type to itself to be the identity function, it may make
it tricky to perform the "ideal" conversion between different
types.

*** Idea #3 ***

Use a multi-parameter type class:

  class FloatConvert a b where
  toFloating :: a -> b

Advantages:
  * Can define any conversion imaginable without constraints.
  * Straightforward to add floating types to the language.

Disadvantages:
  * Requires multi-parameter type classes.
  * Not practical for library authors to define their own instances
of this class except in special circumstances, since it requires
knowledge of all other floating types.

Of these three ideas, I think #2 (or something similar) is the most
workable.  What do others think?

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Re: Proposal: Hexadecimal floating point constants

2010-02-23 Thread Nick Bowler
On 12:26 Sat 20 Feb , Heinrich Apfelmus wrote:
> Nick Bowler wrote:
> > Similarly, the greatest finite double value can be written as
> > 0x1.fp+1023.
> >
> > These constants have the form
> >
> >   0x[HH][.H]p[+/-]DDD
> 
> If you don't want to wait on an (uncertain) inclusion into the Haskell
> standard, you can implement a small helper function to that effect
> yourself; essentially using  encodeFloat .

Indeed, I have already implemented such a function.  My gripe here is
that it's extremely cumbersome to use such a function in a program, and
it adds the possibily of programs crashing due to syntax errors at
runtime.

On 13:15 Mon 22 Feb , Simon Peyton-Jones wrote:
> Or, alternatively, use quasiquoting
>   
>   [hex| 1.fp+1023 |]

Ah, I was not aware of this feature.  It does seem like a decent
solution, in that it allows errors to be caught at compile time.
Somewhat more verbose than I had hoped, but it's probably fine.
Thanks.

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime


Proposal: Hexadecimal floating point constants

2010-02-19 Thread Nick Bowler
I'd like to propose what I believe is a simple but valuable extension to
Haskell that I haven't seen proposed elsewhere.

C has something it calls hexadecimal floating constants, and it would be
very nice if Haskell had it too.  For floating point systems where the
radix is a power of two (very common), they offer a means of clearly and
exactly specifying any finite floating point value.

For example, suppose we want to write the least positive value of an
IEEE754 double.  With hexadecimal floating constants, we write
0x0.1p-1022 and a reader can immediately tell what this is.
One could equivalently write this in a normalized fashion as 0x1p-1074.
The exact representation of this value in base 10 is very, very long
(there are over 750 significant digits), but we can abuse roundoff to
write it succinctly as 5e-324, which is much less clear about which
value was intended.

Similarly, the greatest finite double value can be written as
0x1.fp+1023.

These constants have the form

  0x[HH][.H]p[+/-]DDD

where we have the hexadecimal prefix 0x, zero or more hexadecimal
digits, and an optional fractional separator followed by zero or more
hexadecimal digits.  There must be at least one hexadecimal digit.
Finally, there is a p followed by an (optionally signed) exponent
encoded in decimal.

The hexadecimal digits are interpreted in the obvious way and then
scaled by 2 raised to the given exponent.

Implementing this proposal would change the meaning of expressions like

  let p4 = 5 in (+) 0x5p4

I don't believe anyone writes code like that, but it's resolved by
adding a space, as in

  let p4 = 5 in (+) 0x5 p4

-- 
Nick Bowler, Elliptic Technologies (http://www.elliptictech.com/)
___
Haskell-prime mailing list
Haskell-prime@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-prime