[Haskell-cafe] Re: map (-2) [1..5]

2006-09-19 Thread Aaron Denney
On 2006-09-11, Aaron Denney [EMAIL PROTECTED] wrote:
 See What About the Natural Numbers - Colin Runciman - it's a good read :)

 I will when I get the chance.

Finally found a copy.  It is a good read.  I mostly agree with him.
The biggest exception is about the need for highly optimized, near the
machine level, representations of the naturals.  17 years later with
much better computers, I think the unary representation works just fine,
and transparently conveys what it means.

-- 
Aaron Denney
--

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


RE: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-11 Thread Simon Peyton-Jones
| Well, it seems a shame that we don't have postfix operators already.
| I guess that means I am arguing we should introduce a unary postfix
| operator, and not even have sugar for factorial, as it conflicts with
| array access.
| 
| We *almost* do:
| Hugs.Base let (!) 0 = 1; (!) x = x*((!) (x-1)) in (5 !)
| Sadly,
| Prelude  let (!) 0 = 1; (!) x = x*((!) (x-1)) in (5 !)

Actually, the up-coming GHC 6.6 does allow this.  Some while ago I made
the type checker a tiny bit more lenient about
  left sections, so that 
(x !)
  would typecheck iff
((!) x) 
  typechecks.  
  
(Strictly, Haskell 98 requires that the section typechecks iff
(\y. (!) x y)
  typechecks, and I should really have made the relaxation dependent on
a 
  flag, but I didn't.)

Anyway, you get postfix operators.  I'd better document this.

Simon
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-11 Thread Henning Thielemann

On Sun, 10 Sep 2006, Aaron Denney wrote:

  Of course, there's always a typeclass, where we could add all sorts of
  other encodings of the Peano axioms, such as binary trees,, but I don't
  see that that buys us much if we don't also get access to operations
  beyond them, such as (an _efficient_) `div` for fastexp.
 
  I don't see why Natural can't have an instance of whatever
  class ends up owning “div”.  It's perfectly well behaved on
  Naturals.
 
 True.  It seems odd to have a multiplicative (pseudo) inverse, but
 not an additive, though.  Breaking up the numeric hierarchy too finely
 seems like it would be a pain -- take it to the limit of a
 separate class per function.  What else would you drag in with div?
 mod, (*), ...?


from http://darcs.haskell.org/numericprelude/src/Algebra/Core.lhs :

 class (Num a) = Integral a where
 div, mod :: a - a - a
 divMod :: a - a - (a,a)

 -- Minimal definition: divMod or (div and mod)
 div a b = fst (divMod a b)
 mod a b = snd (divMod a b)
 divMod a b = (div a b, mod a b)
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-11 Thread Aaron Denney
On 2006-09-10, Neil Mitchell [EMAIL PROTECTED] wrote:
 Hi,

 I think in practice this wouldn't really be an issue. When you're
 using natural numbers, you tend to be in a situation where you're
 either numbering things statically, and not doing any calculations
 with them, or you're using them as a monoid, whereby things only
 increase.

 take? primes? fibs? ackermanns?

take is more an iteration than a numerical calculation -- it works best
as pattern matching on Succ and Zero.

Primes and fibs are purely generative streams that can be calculated
just fine using integers.  If you want to geta specific value out, then
sure, index using naturals, which again is a data-structural induction.

Yes, it's nice to be able to encode the invariant x  0.  It'd also
be nice to be able to encode invariants like (x  10), or (a  x  b)
for array access.  But for both of these it is more natural to work with
a subset of the integers, than a new type.  Yes, even if this means
dealing with partial functions.

And, as I pointed out before, if naturals are represented asunary, then
it means you can do take infinity xs where infinity = Succ infinity

 See What About the Natural Numbers - Colin Runciman - it's a good read :)

I will when I get the chance.

-- 
Aaron Denney
--

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-11 Thread Aaron Denney
On 2006-09-11, Simon Peyton-Jones [EMAIL PROTECTED] wrote:
| Well, it seems a shame that we don't have postfix operators already.

 Actually, the up-coming GHC 6.6 does allow this.

Awesome.

-- 
Aaron Denney
--

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-11 Thread Aaron Denney
On 2006-09-11, Henning Thielemann [EMAIL PROTECTED] wrote:

 On Sun, 10 Sep 2006, Aaron Denney wrote:

  Of course, there's always a typeclass, where we could add all sorts of
  other encodings of the Peano axioms, such as binary trees,, but I don't
  see that that buys us much if we don't also get access to operations
  beyond them, such as (an _efficient_) `div` for fastexp.
 
  I don't see why Natural can't have an instance of whatever
  class ends up owning div.  It's perfectly well behaved on
  Naturals.
 
 True.  It seems odd to have a multiplicative (pseudo) inverse, but
 not an additive, though.  Breaking up the numeric hierarchy too finely
 seems like it would be a pain -- take it to the limit of a
 separate class per function.  What else would you drag in with div?
 mod, (*), ...?


 from http://darcs.haskell.org/numericprelude/src/Algebra/Core.lhs :

 class (Num a) = Integral a where
 div, mod :: a - a - a
 divMod :: a - a - (a,a)

 -- Minimal definition: divMod or (div and mod)
 div a b = fst (divMod a b)
 mod a b = snd (divMod a b)
 divMod a b = (div a b, mod a b)

That particular division means that Naturals can't support div because
they're not a ring, which the (Num a) in that snippet above means for
this numeric hierarcy, right?  So this does drag in div, mod and (*),
which all seem mostly reasonable, but it also drags in (-) and negate,
which you don't want for Naturals.

-- 
Aaron Denney
--

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


Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-10 Thread David House

On 10/09/06, Aaron Denney [EMAIL PROTECTED] wrote:

I still don't like having a plus without a minus.


I think in practice this wouldn't really be an issue. When you're
using natural numbers, you tend to be in a situation where you're
either numbering things statically, and not doing any calculations
with them, or you're using them as a monoid, whereby things only
increase.

--
-David House, [EMAIL PROTECTED]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-10 Thread Neil Mitchell

Hi,


I think in practice this wouldn't really be an issue. When you're
using natural numbers, you tend to be in a situation where you're
either numbering things statically, and not doing any calculations
with them, or you're using them as a monoid, whereby things only
increase.


take? primes? fibs? ackermanns?

There are lots of things things were computation is performed on
natural numbers, in fact, I'd say its relatively rare to find negative
integers!

See What About the Natural Numbers - Colin Runciman - it's a good read :)

Thanks

Neil
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-10 Thread Jim Apple

See also: torsors

http://math.ucr.edu/home/baez/torsors.html

Jim
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread David House

On 09/09/06, Cale Gibbard [EMAIL PROTECTED] wrote:

When I first ran into the problem with (-) and
sections, I was slightly annoyed with having to write (+ (-1))


Let's not forget that there is the library function 'subtract' for
this purpose. What you wrote could be written as (subtract 1), which
is more readable in my opinion. But hey, what do I know, I think using
the underscore for unary negation (à la Emacs calculator) would be an
acceptable enough compromise.

--
-David House, [EMAIL PROTECTED]
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Ross Paterson
On Sat, Sep 09, 2006 at 12:57:56AM -0400, Cale Gibbard wrote:
 Num itself needs to be split, but we can't do it sanely without
 something like class aliases.

I think that a finer grain numeric hierarchy, while retaining Num, etc,
is feasible without changing the language: unlike the case of monads,
the people who will be defining instances of numeric classes are the
very ones who are inconvenienced by the current hierarchy.  The main
impact on clients of the classes is that some functions would have
more general types.

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Aaron Denney
 Cale Gibbard [EMAIL PROTECTED] writes:
 Another thing to note is that all the natural literals are not, as one
 might initially think, plain values, but actually represent the
 embedding of that natural number into the ring (instance of Num), by
 way of 0 and 1.

Excellent point, and good categorical thinking.  The morphisms are more
important than the objects.

Jón Fairbairn [EMAIL PROTECTED] wrote:
 I think the present design is wrong because we don't have a
 type for naturals.

Meh.  Naturals are reasonably useful sometimes, but not often enough, in
my opinion.  Any sort of numeric hierarchy designed to deal with them
would be totally broken from my point of view -- if you don't at least
have inverses, it's not a number, just some sort of weird algebraic
structure.  And if it's not in the numeric hierarchy, and so you can't
do arithmetic syntactically nicely with it, what's the point?

Is it better to make (^^), (^), and take partial functions, or to make (-)
and negate partial functions?

Hmm, here's an idea: have a Nat type, but no arithmetic defined on it
besides Succ, and isZero.  Of course, that makes the fastexp algorithm
unfeasible, and is essentially isomorphic to [()].

Hmm.  That gives
 length = map (const ())
 take = zipWith (flip const)

Feel free to consider this a strawman, but it *is* kind of elegant.
There's no scaling loss, as these are inherently O(N).  And it even
means length and take can handle infinite lists.  What's not to like?

Of course, there's always a typeclass, where we could add all sorts of
other encodings of the Peano axioms, such as binary trees,, but I don't
see that that buys us much if we don't also get access to operations
beyond them, such as (an _efficient_) `div` for fastexp.  (Taking every
n'th element (Peano encoded, of course) is _not_ good enough).

-- 
Aaron Denney
--

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Aaron Denney
On 2006-09-08, Jón Fairbairn [EMAIL PROTECTED] wrote:
 Brian Hulley [EMAIL PROTECTED] writes:
 In the context of programming, I don't see the problem of
 just thinking of the integers as a primitive built-in data
 type which contains some range of positive and negative
 integers which I'd argue should all be treated on an equal
 footing when the context of discourse is the integers not
 the naturals.

 I'm not sure what that means. Why should they be equal? Why
 shouldn't Naturals be more primitive than Integers? 

Certainly they're more primitive.  Too primitive to have reasonable
algebraic properties.

 I don't think there is a need to force spaces to be put
 around every infix application. It's only when there would
 be a conflict with the lexical syntax that spaces are
 needed, just as at the moment we have (F . G) versus (F.G),
 (f  $  g) versus (f  $g) etc.

 That rather goes against your simplicity of design argument,
 doesn't it? Why the special cases? For years I've been
 rather sloppy about spaces around “$”, and now when I use
 template haskell, this bites me.  At some point in the
 future someone might decide that  or % is needed to
 introduce a new chunk of syntax, and formerly valid
 programmes break. So why not just say that varsym varid is
 in general reserved for future special syntaxes, and require
 varsym whitespace varid everywhere?

Hmm.  Quite reasonable, actually, if we were designing the language de
novo.  And easily enough to write correctors for current code.

-- 
Aaron Denney
--

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Aaron Denney
On 2006-09-08, Brian Hulley [EMAIL PROTECTED] wrote:
 Leaving aside the question of negative literals for the moment, what's so 
 special about unary minus that it warrants a special syntax? For example in 
 mathematics we have x! to represent (factorial x), which is also an 
 important function, yet no-one is arguing that we should introduce a unary 
 postfix operator to Haskell just to support it.

Well, it seems a shame that we don't have postfix operators already.
I guess that means I am arguing we should introduce a unary postfix
operator, and not even have sugar for factorial, as it conflicts with
array access.

We *almost* do:
Hugs.Base let (!) 0 = 1; (!) x = x*((!) (x-1)) in (5 !)
Sadly,
Prelude  let (!) 0 = 1; (!) x = x*((!) (x-1)) in (5 !)

interactive:1:41:
No instance for (Num (t - t1))
  arising from the literal `5' at interactive:1:41
Probable fix: add an instance declaration for (Num (t - t1))
In the first argument of `(!)', namely `5'
In the definition of `it':
it = let
   ! 0 = ...
   ! x = ...
 in (5 !)

And hugs doesn't work with out the parentheses in the expression.

We already have this great syntax, parsing semanticsi for precedence,
and so forth for declaring infix operators.  Couldn't we add to that
slightly by declaring postfix operators as well?  Actually, declaring a
unary operator infix yielding a postfix operator doesn't seem like too
much abuse.  I could have sworn I'd seen ternary operators the same way,
but
 ((id) `either` (id) (Left 5))
doesn't appear to work.

Then there's also the infix data constructors for postfix...
 Okay, that's complicated because of lack of precedence, but surely that
just means extra parentheses?

(I haven't thought this through to any great extent.  How much would it
complicate parsing?  Not much, I would assume, as this fails in ghc at
the type-checking stage.)

(Tounge only *half* in cheek.)

-- 
Aaron Denney
--

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Jón Fairbairn
Aaron Denney [EMAIL PROTECTED] writes:

 We already have this great syntax, parsing semanticsi for precedence,
 and so forth for declaring infix operators.  Couldn't we add to that
 slightly by declaring postfix operators as well?  Actually, declaring a
 unary operator infix yielding a postfix operator doesn't seem like too
 much abuse. 

Possibly not, provided they're always used as sections. 
(e #) already always means supply e as the first argument
to (#)).

 (I haven't thought this through to any great extent.  How much would it
 complicate parsing?  Not much, I would assume, as this fails in ghc at
 the type-checking stage.)

I don't think it would complicate mechanical parsing
unreasonably. I do think (if done without the parentheses)
it might complicate /human/ parsing unreasonably.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-07)

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Jón Fairbairn
Aaron Denney [EMAIL PROTECTED] writes:


 Jón Fairbairn [EMAIL PROTECTED] wrote:
  I think the present design is wrong because we don't have a
  type for naturals.
 
 Meh.  Naturals are reasonably useful sometimes, but not often enough, in
 my opinion.  Any sort of numeric hierarchy designed to deal with them
 would be totally broken from my point of view -- if you don't at least
 have inverses, it's not a number,

Crikey. Would you really have me accept that the natural
numbers aren't numbers?

 just some sort of weird algebraic structure.  And if it's
 not in the numeric hierarchy, and so you can't do
 arithmetic syntactically nicely with it, what's the point?

Could you elaborate? I haven't thought it through, but I
can't see why splitting Num into something that puts Natural
above Integer would be particularly problematic. Natural
just has fewer operations than Integer. It doesn't have “-”,
but it does have “difference:: Natural - Natural -
Natural”, and so do the bigger types (“difference a b = abs
(a - b)”)

 Is it better to make (^^), (^), and take partial functions, or to make (-)
 and negate partial functions?

No :-). “-” and “negate” would belong to a class of which
Natural had no instances.  If you're the sort of person who
likes having partial functions like “head” sullying the
scene, you might find it convenient to have
“integralToNatural” that either returns the corresponding
Natural or throws an exception. Actually, if you are someone
like that, you probably want to give it a shorter name...

 Of course, there's always a typeclass, where we could add all sorts of
 other encodings of the Peano axioms, such as binary trees,, but I don't
 see that that buys us much if we don't also get access to operations
 beyond them, such as (an _efficient_) `div` for fastexp.

I don't see why Natural can't have an instance of whatever
class ends up owning “div”.  It's perfectly well behaved on
Naturals.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-07)

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Jón Fairbairn
Aaron Denney [EMAIL PROTECTED] writes:

 On 2006-09-08, Jón Fairbairn [EMAIL PROTECTED] wrote:
  Why shouldn't Naturals be more primitive than Integers?
 
 Certainly they're more primitive.  Too primitive to have reasonable
 algebraic properties.

Hmph. Naturals obey (a+b)+c == a+(b+c), which is a nice and
reasonable algebraic property that Float and Double don't
obey. In fact Float and Double have lots of /un/reasonable
algebraic properties, but we still have them in the
language.  (I think they should be turfed out into a
numerical library).

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-09-07)

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Jón Fairbairn
Brian Hulley [EMAIL PROTECTED] writes:

 Jón Fairbairn wrote:
  [1] “-” is a varsym. The logical way of achieving what you
  suggest (ie -1 -2... as constructors for Integer) would be
  to make it introduce a consym the way “:” does, but then it
  couldn't be an infix operator anymore.
 
 I don't think it's necessary to use the same kind of rule
 for '-' as for ':'.

Not necessary, but you surely don't want yet another rule?

 I imagine that almost every editor at least does lexical
 fontification, and if so, then I don't think there could be
 much confusion in practice between these uses of '-'.

I think that unnecessarily disadvantages people with poorer
than average (including zero) eyesight.

 Yes, a typeclass for exp would be ideal

Well, so long as you call it “exponent” or “expt”.

 (and a newtype for Natural).

Here's a design principle for you: if an error can be
detected at compile time, it should be. If we have literals
for naturals and not negative integers, “negate 100” causes
no problem, it just means “negate (fromNatural 100)”. If we
have literals for integers and try to restrict them to get
naturals, “-100:: Natural” becomes shorthand for
“integralToNatural (-100)”, and would (in the absence of
somewhat arbitrary special-casing in the compiler) give a
runtime error.

 I also agree with Tamas's suggestion that an empirical
 analysis of Haskell source code could be useful to determine
 the practical implications of unary minus,

It has merit and I would laud anyone who got round to doing
it, but there's a danger of measuring the wrong thing. What
we want to know is not what is more frequent, but what
causes the greater number of misreadings and which pieces of
code had the most syntax errors before they were completed,
and that's harder to measure. Though if unary minus turned
out to be very rare, we could just drop it. Using “(0-)”
wouldn't be much of a hardship in that case.

 Anyway no doubt I've posted enough emails about unary minus
 and negative literals so I'll be quiet now ;-)

:-) ... ?

-- 
Jón Fairbairn [EMAIL PROTECTED]


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


Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Brian Hulley

Jón Fairbairn wrote:

Brian Hulley [EMAIL PROTECTED] writes:

I imagine that almost every editor at least does lexical
fontification, and if so, then I don't think there could be
much confusion in practice between these uses of '-'.


I think that unnecessarily disadvantages people with poorer
than average (including zero) eyesight.


For people lacking good eyesight the equivalent of fontification could 
simply be some text-to-speech system which read -2 as negative 2 and 
x - y as x minus y.





Yes, a typeclass for exp would be ideal


Well, so long as you call it “exponent” or “expt”.


I'd completely forgotten about the normal (exp) function. I should have 
written (power) or (pow), though as Cale pointed out a typeclass may not be 
a suitable solution due to the lack of a functional dependency to help the 
compiler choose the correct overloading. - in that case I'd go back to 
advocating (powNat) (powInt) etc.





(and a newtype for Natural).


Here's a design principle for you: if an error can be
detected at compile time, it should be. If we have literals
for naturals and not negative integers, “negate 100” causes
no problem, it just means “negate (fromNatural 100)”. If we
have literals for integers and try to restrict them to get
naturals, “-100:: Natural” becomes shorthand for
“integralToNatural (-100)”, and would (in the absence of
somewhat arbitrary special-casing in the compiler) give a
runtime error.


Ok I'm slowly coming round to the view that having negative literals is not 
ideal.





I also agree with Tamas's suggestion that an empirical
analysis of Haskell source code could be useful to determine
the practical implications of unary minus,


It has merit and I would laud anyone who got round to doing
it, but there's a danger of measuring the wrong thing. What
we want to know is not what is more frequent, but what
causes the greater number of misreadings and which pieces of
code had the most syntax errors before they were completed,
and that's harder to measure. Though if unary minus turned
out to be very rare, we could just drop it. Using “(0-)”
wouldn't be much of a hardship in that case.


Anyway no doubt I've posted enough emails about unary minus
and negative literals so I'll be quiet now ;-)


:-) ... ?


I think the main problem with unary negation is that it's the only place in 
Haskell where the same symbol is being used to represent two different (ie 
not overloads of each other) functions.


I can see why people were tempted to do this, because there is such an 
intimate relationship between unary minus and binary subtraction. However I 
feel it is a slippery slope: convenience has been put before uniformity 
leading to confusion.


While such things might be justified in a domain specific language like 
mathematica or matlab, for a general purpose language like Haskell it seems 
less reasonable to make an exception just for one arithmetic function.


Regards, Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 


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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-09 Thread Aaron Denney
On 2006-09-09, Jón Fairbairn [EMAIL PROTECTED] wrote:
 Aaron Denney [EMAIL PROTECTED] writes:
 Meh.  Naturals are reasonably useful sometimes, but not often enough, in
 my opinion.  Any sort of numeric hierarchy designed to deal with them
 would be totally broken from my point of view -- if you don't at least
 have inverses, it's not a number,

 Crikey. Would you really have me accept that the natural
 numbers aren't numbers?

I'd like it if you would, but don't expect to convince you.

 just some sort of weird algebraic structure.  And if it's
 not in the numeric hierarchy, and so you can't do
 arithmetic syntactically nicely with it, what's the point?

 Could you elaborate? I haven't thought it through, but I
 can't see why splitting Num into something that puts Natural
 above Integer would be particularly problematic.

For a Natural typeclass to be useful in keeping full-blown Integers
away from functions like take, it can't be above the ones Integer
belongs to.  Instead it has to hang off the side of the numeric
hierarchy.  You can split this into a tagging class on the side
and what naturals and integer have in common.  

Or, of course, you could onry allow one implementation of naturals, and
have the Natural typeclass not used to enforce these restriction, but
just the data type itself.

 Natural just has fewer operations than Integer. It doesn't have
 “-”, but it does have “difference:: Natural - Natural -
 Natural”, and so do the bigger types (“difference a b = abs (a -
 b)”)

Is difference ever a useful function?  I guess I don't see it as
terribly natural.  Placing it in the hierarchy somewhere above the class
with (-) also means we can't have a default definition in terms of (-).

 Is it better to make (^^), (^), and take partial functions, or to make (-)
 and negate partial functions?

 No :-). “-” and “negate” would belong to a class of which
 Natural had no instances.

That could work.  I still don't like having a plus without a minus.

 Of course, there's always a typeclass, where we could add all sorts of
 other encodings of the Peano axioms, such as binary trees,, but I don't
 see that that buys us much if we don't also get access to operations
 beyond them, such as (an _efficient_) `div` for fastexp.

 I don't see why Natural can't have an instance of whatever
 class ends up owning “div”.  It's perfectly well behaved on
 Naturals.

True.  It seems odd to have a multiplicative (pseudo) inverse, but
not an additive, though.  Breaking up the numeric hierarchy too finely
seems like it would be a pain -- take it to the limit of a
separate class per function.  What else would you drag in with div?
mod, (*), ...?

I was thinking of useful implementations solely in terms of the
Peano-axiom interface, which only really needs to be there for a default
implementation.

-- 
Aaron Denney
--

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-08 Thread Jón Fairbairn
Cale Gibbard [EMAIL PROTECTED] writes:
 Another thing to note is that all the natural literals are not, as one
 might initially think, plain values, but actually represent the
 embedding of that natural number into the ring (instance of Num), by
 way of 0 and 1.

I wasn't sure where to add this, so here will have to do:

I think the present design is wrong because we don't have a
type for naturals.  So in my view, “-1” should be “negate
(fromNatural 1)” -- whatever names we use for those two
functions.  I can't remember right now why the early
versions of Haskell didn't have a Natural type, or what
makes it difficult to change to now (and I think this is
something we really should do), but even given that, I think
the present special casing of “-” is a reasonable
compromise.

Given a built in Natural type, it makes no sense to have “-”
as part of the syntax for literals, since Natural literals
don't have it and there's no way to add more constructors
(ie negative literals) onto an existing type to get Integer,
but having a symbol for negate does it in a straightforward
way. 


* ** *

For my own taste, I would have “-” as a character that can
appear in identifiers and operators (but special in that if
it appears at the beginning it cannot be followed by
anything? Otherwise -1 would just be an identifier!) and
define

 - n = negate n
 a +- b = a + (- b)

but I think that most people would baulk at having to use
“+-” for infix minus. People would similarly baulk at the
opposite tack of making “-” solely infix and using something
else for negate (as in ML), although finding a different
token (such as “__”) for don't care and using “_” for
unary minus doesn't seem too bad to me.


-- 
Jón Fairbairn [EMAIL PROTECTED]

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-09-08 Thread Jón Fairbairn
Brian Hulley [EMAIL PROTECTED] writes:


 Leaving aside the question of negative literals for the
 moment, what's so special about unary minus that it warrants
 a special syntax? For example in mathematics we have x! to
 represent (factorial x), which is also an important
 function, yet no-one is arguing that we should introduce a
 unary postfix operator to Haskell just to support it.
 
 In maths we also have |x| to denote another common function,
 (abs x), yet afaia everyone is happy to just write (abs x).

That's just a matter of how common the operator is. “-” is
so common that if you asked a random passer-by they'd
probably identify it correctly, whereas “!” and “|...|”
would be likely to elicit a response of no idea mate.

 Would the elimination of the special case rule for unary
 minus not make the language easier to understand?

A bit, certainly.

 What's wrong with typing (negate x) in the rare cases
 where you can't just re-write the expression to use infix
 minus instead (ie x + -y === x - y)?

Nothing, really. But in that case, why have a special case
for negative literals? “negate 42” would be more consistent¹,
and it wouldn't tax language implementors a groat if the
language specified that such an application should always be
folded into whatever your suggested syntax would have
produced.

[1] “-” is a varsym. The logical way of achieving what you
suggest (ie -1 -2... as constructors for Integer) would be
to make it introduce a consym the way “:” does, but then it
couldn't be an infix operator anymore.

 Surely most programs in Haskell are not just arithmetic
 expressions, and while it is convenient to have infix +,
 -, *, `div`, `mod` for the integers, so you can do
 indexing over data types and other counting operations,
 I'd argue that the usual functional notation (eg (exp x)
 (factorial x) (negate x)) should be sufficient for the
 other arithmetic operations just as it's deemed sufficient
 for nearly everything else in Haskell! ;-)

I can't say that I find anything disagreeable about that
suggestion, though the operators aren't on Integers but
belong to typeclasses.

  Anyway, the point of all this is that 0,1,2... are not
  really literals at all. They're nullary operators which
  give particular elements of any given instance of
  Num. Perhaps at some level in the compiler after
  performing the fromInteger transformation they may be
  taken as literal integers, but there is no reason that
  this level has to be exposed to the user.
 
 This seems very theoretical to me.

One of the most valuable aspects of Haskell is it's
theoretical underpinning. Don't play fast and loose with
that!

 In the context of programming, I don't see the problem of
 just thinking of the integers as a primitive built-in data
 type which contains some range of positive and negative
 integers which I'd argue should all be treated on an equal
 footing when the context of discourse is the integers not
 the naturals.

I'm not sure what that means. Why should they be equal? Why
shouldn't Naturals be more primitive than Integers? 

 Another point is that the current treatment requires a
 special rule for pattern matching against a negative
 integer

Perhaps the notional declaration

 data Integer = Succ Natural | Zero | Pred Natural

(with “Succ 0” meaning 1, of course, possibly with nicer
syntax and definitiely with the expectation that it'll be
compiled into a decent machine representation) would address
that?

 or float,

Pattern matching on floats is an abomination, definitely a
candidate for removal.

  I'd also like to say that the exponentiation example is also a good
  one. -4^2 is *always* -16, in every sane mathematical context since
  unary negation is treated as an additive operation, and thus should
  happen after exponentiation and multiplication (though under normal
  circumstances, it doesn't matter whether it's done before or after
  multiplication).
 
 In C, it wouldn't be, since there, unary ops always bind
 tighter than infix ops,

C is almost the last place to look for elegant language
design. (Not quite the last, there's Perl and some
deliberate gargoyles of languages to go after it)

 or better still:
 
 negate (expNat 4 2)
 
 because this would free the ^ symbol for some more widely
 applicable use, and would also make the particular choice of
 exponentiation operator more explicit

Agreed, though I'd want expt to be part of a typeclass
(possibly multi-parameter to get exp:: Integral a = a -
Natural - a as an instance?).

 I don't think there is a need to force spaces to be put
 around every infix application. It's only when there would
 be a conflict with the lexical syntax that spaces are
 needed, just as at the moment we have (F . G) versus (F.G),
 (f  $  g) versus (f  $g) etc.

That rather goes against your simplicity of design argument,
doesn't it? Why the special cases? For years I've been
rather sloppy about spaces around “$”, and now when I use
template haskell, this bites me.  At 

Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-08 Thread Brian Hulley

Jón Fairbairn wrote:

Brian Hulley [EMAIL PROTECTED] writes:

Cale Gibbard wrote:

Anyway, the point of all this is that 0,1,2... are not
really literals at all. They're nullary operators which
give particular elements of any given instance of
Num. Perhaps at some level in the compiler after
performing the fromInteger transformation they may be
taken as literal integers, but there is no reason that
this level has to be exposed to the user.


This seems very theoretical to me.


One of the most valuable aspects of Haskell is it's
theoretical underpinning. Don't play fast and loose with
that!


You're right. I should have made a proper argument so here goes:

1) Num a implies that forall a, there is an additive inverse for a (given by 
(negate))
2) I think Cale is saying that it is sufficient to have overloaded nullary 
operators 0 and 1 in conjunction with the (+) and (negate) methods of Num, 
in order to construct all elements of Num
3) I think also Cale's argument is that the other nullary operators, 2, 3, 
... are just there for convenience, but that this convenience is a good 
thing.


So my argument would be that given that we only actually need 0 and 1, but 
we already have 2, 3,... for convenience, there is no reason to not also 
have -1, -2, -3, ... as well, for even more convenience, especially as the 
numeric hierarchy starts with a structure where every element is required to 
have an additive inverse.



[1] “-” is a varsym. The logical way of achieving what you
suggest (ie -1 -2... as constructors for Integer) would be
to make it introduce a consym the way “:” does, but then it
couldn't be an infix operator anymore.


I don't think it's necessary to use the same kind of rule for '-' as for 
':'. The rule could be that a '-' immediately followed by a digit starts a 
negative number, otherwise the '-' is treated as it is at the moment (ie 
either the start of a comment or a varsym).


I imagine that almost every editor at least does lexical fontification, and 
if so, then I don't think there could be much confusion in practice between 
these uses of '-'.


Also, the fact that we want to allow pattern matching against negative 
integers suggests that positive integers and negative integers should have 
equal status regarding literal representation (more precisely: nullary 
operator overloaded for the integers), rather than having to introduce a 
special pattern matching rule for the negatives.



Pattern matching on floats is an abomination, definitely a
candidate for removal.


Seconded.


negate (expNat 4 2)

because this would free the ^ symbol for some more widely
applicable use, and would also make the particular choice of
exponentiation operator more explicit


Agreed, though I'd want expt to be part of a typeclass
(possibly multi-parameter to get exp:: Integral a = a -
Natural - a as an instance?).


Yes, a typeclass for exp would be ideal (and a newtype for Natural).

Perhaps we could even use (neg) instead of (negate) in deference to the 3 
letter varids used for other common arithmetic ops, to get:


   neg (exp 4 2)
   neg y * 56

(neg can also be read declaratively as negative, instead of the 
imperative negate.)





I don't think there is a need to force spaces to be put
around every infix application. It's only when there would
be a conflict with the lexical syntax that spaces are
needed, just as at the moment we have (F . G) versus (F.G),
(f  $  g) versus (f  $g) etc.


That rather goes against your simplicity of design argument,
doesn't it? Why the special cases? For years I've been
rather sloppy about spaces around “$”, and now when I use
template haskell, this bites me.  At some point in the
future someone might decide that  or % is needed to
introduce a new chunk of syntax, and formerly valid
programmes break. So why not just say that varsym varid is
in general reserved for future special syntaxes, and require
varsym whitespace varid everywhere?


This would certainly be a simple rule that would also make code easier to 
read.


Summary (imagine the different editor colours/font styles):
(- 1)  -- a section because of the space
(-1)   -- a negative number
(x - 1)   -- (-) x 1
(x -1)-- x applied to (-1)
(x -y) -- either (x -  y) or, following the above rule, a syntax 
error.


I also agree with Tamas's suggestion that an empirical analysis of Haskell 
source code could be useful to determine the practical implications of unary 
minus, which might help to address Jared's comments about the improbability 
of being able to reach a consensus when everyone has such different 
experiences/purposes etc.


Anyway no doubt I've posted enough emails about unary minus and negative 
literals so I'll be quiet now ;-)


Best regards,
Brian.
--
Logic empowers us and Love gives us purpose.
Yet still phantoms restless for eras long past,
congealed in the present in unthought forms,
strive mightily unseen to destroy us.

http://www.metamilk.com 



Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-09-08 Thread Cale Gibbard

On 08/09/06, Brian Hulley [EMAIL PROTECTED] wrote:

Jón Fairbairn wrote:
 Brian Hulley [EMAIL PROTECTED] writes:
 Cale Gibbard wrote:
 Anyway, the point of all this is that 0,1,2... are not
 really literals at all. They're nullary operators which
 give particular elements of any given instance of
 Num. Perhaps at some level in the compiler after
 performing the fromInteger transformation they may be
 taken as literal integers, but there is no reason that
 this level has to be exposed to the user.

 This seems very theoretical to me.

 One of the most valuable aspects of Haskell is it's
 theoretical underpinning. Don't play fast and loose with
 that!

You're right. I should have made a proper argument so here goes:

1) Num a implies that forall a, there is an additive inverse for a (given by
(negate))
2) I think Cale is saying that it is sufficient to have overloaded nullary
operators 0 and 1 in conjunction with the (+) and (negate) methods of Num,
in order to construct all elements of Num
3) I think also Cale's argument is that the other nullary operators, 2, 3,
... are just there for convenience, but that this convenience is a good
thing.

So my argument would be that given that we only actually need 0 and 1, but
we already have 2, 3,... for convenience, there is no reason to not also
have -1, -2, -3, ... as well, for even more convenience, especially as the
numeric hierarchy starts with a structure where every element is required to
have an additive inverse.


My counterargument here is that this doesn't actually increase
convenience. In fact, for a lot of reasons, it decreases convenience.


 [1] - is a varsym. The logical way of achieving what you
 suggest (ie -1 -2... as constructors for Integer) would be
 to make it introduce a consym the way : does, but then it
 couldn't be an infix operator anymore.

I don't think it's necessary to use the same kind of rule for '-' as for
':'. The rule could be that a '-' immediately followed by a digit starts a
negative number, otherwise the '-' is treated as it is at the moment (ie
either the start of a comment or a varsym).

I imagine that almost every editor at least does lexical fontification, and
if so, then I don't think there could be much confusion in practice between
these uses of '-'.

Also, the fact that we want to allow pattern matching against negative
integers suggests that positive integers and negative integers should have
equal status regarding literal representation (more precisely: nullary
operator overloaded for the integers), rather than having to introduce a
special pattern matching rule for the negatives.

 Pattern matching on floats is an abomination, definitely a
 candidate for removal.

Seconded.

 negate (expNat 4 2)

 because this would free the ^ symbol for some more widely
 applicable use, and would also make the particular choice of
 exponentiation operator more explicit

 Agreed, though I'd want expt to be part of a typeclass
 (possibly multi-parameter to get exp:: Integral a = a -
 Natural - a as an instance?).

Yes, a typeclass for exp would be ideal (and a newtype for Natural).


Num itself needs to be split, but we can't do it sanely without
something like class aliases. I actually think that the (^), (^^),
(**) distinction is rather refreshing to see in a programming
language. Most languages don't take the care to distinguish that there
are actually different levels of definition of exponentiation. You
can't just merge them -- have you looked at their types? (^^) can't be
defined for Integers, but it works fine for Rational bases, (**) can't
be defined for Rational bases, but works fine for floating point.
Additionally, these operations have different performance and
numerical properties. If we have a typeclass for this, it will be
multiparameter, and there will not be a functional dependency. This
could create additional annoyance in various situations. In
mathematics, these operations are given the same notation, but are
definitely distinguished between by the humans using them.


Perhaps we could even use (neg) instead of (negate) in deference to the 3
letter varids used for other common arithmetic ops, to get:

neg (exp 4 2)
neg y * 56

(neg can also be read declaratively as negative, instead of the
imperative negate.)


I obviously already disagree with this whole bit anyway, but eek,
don't steal exp. We already have a very important function (in fact,
I'd be willing to say that it's probably the most important function
in all of mathematics) called exp, and it's named after its standard
name in mathematics. Also, not using infix notation for exponentiation
would obfuscate many simple mathematical programs. Anything involving
a polynomial will look terrible. (I don't care if you're a C
programmer and you're used to polynomials looking terrible, I'm not.)
I don't really care too much either way with negate - neg, I know
some people hate abbreviations in the libraries, but that one is
probably sufficiently 

[Haskell-cafe] Re: map (-2) [1..5]

2006-08-17 Thread Christian Maeder
 map (\x - x - 2) [1..5]
or
 map (flip (-) 2) [1..5]

HTH Christian

Tamas K Papp schrieb:
 The code in the subject generates an error.  I understand why this is
 (- is treated as part of the number), but I don't know how to solve
 it, ie how to tell Haskell that - is a function/binary operator?
 
 Thanks,
 
 Tamas
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Re: map (-2) [1..5]

2006-08-17 Thread Stefan Monnier
 I'd have thought it would have been simpler to just make the rule that -2 
 (no spaces between '-' and '2') would be a single lexeme,

But then x-2 won't mean subtract 2 from x but call x with arg -2.


Stefan

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


[Haskell-cafe] Re: map (-2) [1..5]

2006-08-17 Thread Jón Fairbairn
Stefan Monnier [EMAIL PROTECTED] writes:

  I'd have thought it would have been simpler to just make the rule that -2 
  (no spaces between '-' and '2') would be a single lexeme,
 
 But then x-2 won't mean subtract 2 from x but call x with arg -2.

Well, since the normal typographical convention is that
hyphenated-words are read as closely connected, I've
always been in favour of including hyphen in variable names
and using spaces to separate them from tokens, so perhaps it
should just mean the identifier 'x-2'.

Though in the days of Unicode we could get round the whole
thing by using code 0x002d for unary minus, 0x2010 in
identifiers and 0x2212 for infix minus... and spend many a
happy hour trying to tell which of the three was intended by
some short horizontal line.

-- 
Jón Fairbairn [EMAIL PROTECTED]
http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html  (updated 2006-07-14)

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


Re: [Haskell-cafe] Re: map (-2) [1..5]

2006-08-17 Thread John Meacham
On Thu, Aug 17, 2006 at 11:18:59AM -0400, Stefan Monnier wrote:
  I'd have thought it would have been simpler to just make the rule that -2 
  (no spaces between '-' and '2') would be a single lexeme,
 
 But then x-2 won't mean subtract 2 from x but call x with arg -2.

but now at least a highlighting editor can tell the difference and
highlight '-2' as a number and x as a variable. I mean,

0x22 does not mean the same thing as 0 x 32 or 0.32 or 0 . 32.

we already have special lexical rules for numbers and no one has
complained about any of them. but issues with  the '-' handling come up
quite regularly.

John

-- 
John Meacham - ⑆repetae.net⑆john⑈
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe