Re: [Haskell-cafe] Mystery of an Eq instance

2013-09-22 Thread Richard A. O'Keefe

On 20/09/2013, at 11:47 PM, damodar kulkarni wrote:

 
 There is an Eq instance defined for these types!
 
 So I tried this:
 *Main sqrt (10.0) ==3.1622776601683795
 True
 *Main sqrt (10.0) ==3.16227766016837956
 True
 *Main sqrt (10.0) ==3.1622776601683795643
 True
 *Main sqrt (10.0) ==3.16227766016837956435443343
 True
 
 It seems strange.

But *WHY*?   There is nothing in the least strange about this!
Did it occur to you to try

3.1622776601683795 == 3.16227766016837956435443343

(Hint: the answer does not begin with F.)

Four times you asked if the square root of 10 was equal to
a certain (identically valued but differently written) number,
and each time you got the same answer.  Had any of the answers
been different, that would have been shocking.

 So my doubts are:
 1. I wonder how the Eq instance is defined in case of floating point types in 
 Haskell?

At least for finite numbers, the answer is compatibly with C, Fortran,
the IEEE standard, and every programming language on your machine that
supports floating point arithmetic using IEEE doubles.

 2. Can the Eq instance for floating point types be considered meaningful? 
 If yes, how?

Except for infinities and NaNs, yes.
As exact numerical equality.

When you get into infinities and NaNs, things get trickier,
but that's not at issue here.

It seems to me that you may for some reason be under the impression
that the 3. values you displayed have different values.  As
mathematical real numbers, they do.  But they all round to identically
the same numerical value in your computer.

 In general, programmers are **advised** not to base conditional branching on 
 tests for **equality** of two floating point values.

At least not until they understand floating point arithmetic.

 3. Is this particular behaviour GHC specific? (I am using GHC 6.12.1)

No.
 
 If there are references on this please share.

The IEEE floating point standard.
The LIA-1 standard.
The C99 and C11 standards.
What every computer scientist should know about floating point arithmetic
-- citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.22.6768‎

Most of the unpleasant surprises people have with Haskell floating point
numbers are *floating point* surprises, not *Haskell* surprises.

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


Re: [Haskell-cafe] Fwd: Can I use String without in ghci?

2013-09-04 Thread Richard A. O'Keefe

On 3/09/2013, at 10:44 PM, Rustom Mody wrote:
 Whoops! my bad -- I was *thinking* 'pipes' but ended up *writing* 'IPC'   :-)
 
 So let me restate more explicitly what I intended -- pipes, FIFOs, sockets, 
 etc.
 IOW read/write/send/recv calls and the mathematical model represented by the 
 (non-firstclass) pair of C data structures in those functions: buf, len (or 
 count).

Yes, but none of these have anything to do with strings.

string has a precise meaning in C:
7.1.1#1
A string is a contiguous sequence of characters
terminated by and including the first null character.   The
term multibyte string is sometimes used instead of emphasize
special processing given to multibyte characters contained
in the string or to avoid confusion with a wide string.  A
pointer to a string is a pointer to its initial (lowest
addressed) character.  The length of a string is the number
of characters preceding the null character and the value of
a string is the sequence of the values of the contained
characters, in order.
7.1.1#6
(same as #1 but string-wide string and character-wide character)

If you are going to claim Humpty-Dumpty's privilege,
we cannot have a meaningful discussion.

Let me propose a more general definition of string which is
consistent with the three kinds of string natively supported by
the C string.h library and the four or five alternatives I've
personally used in C, with AWK, Python, JavaScript, Java, Erlang,
Ada, Smalltalk, Objective C, and PL/I.  (Haskell gets a little
fuzzy here.)

A *string* is a *completed* sequence of characters
which may be traversed in the natural order *and others*.

In this definition, there are four key aspects:

 - CHARACTERS.  The elements of a string belong to some finite
   set whose elements we have agreed to regard as representing
   characters.
 - SEQUENCE.  The implementation might be a multiway tree, a
   piece table, an AVL DAG, or something more exotic, but there
   is a privileged view of it as a sequence.
 - COMPLETED.  For any particular state of the string, there is
   some present fact of the matter about what the length is and
   each element is known.
 - TRAVERSAL.  You can go from the beginning of the string to
   the end.  And you can go back again.  Palindrome tests are easy.

Now here's another definition:

A (byte, character) *stream* is a *non-completed*
sequence of (bytes, characters) which may be traversed
once in the natural order; repeated traversal, and
other traversal orders, need not be possible.


Now let us look at pipes, FIFOs, sockets, c.
 
These things aren't even close to being strings.
They are BYTE STREAMS.

- The contents are *not* characters, they are *bytes*.
  It was and remains common practice to read and write *non-textual*
  data using these interfaces.  There are portability issues in
  transputting binary data in native format, but there are serious
  performance advantages to doing so.  Interfaces like XDR make it
  straightforward to read and write arrays and records and trees
  with never a character in sight.

  The fact that the external data are *byte* sequences rather than
  *character* sequences is the reason that we now have a problem
  with having to specify the encoding of an external stream when
  we *want* characters.  In another mailing list I'm on a problem
  came up when a data set from the US government was proclaimed
  to be ASCII but was in fact Windows CP1250 (or some such number)
  and the receiver's system didn't _have_ any locale that could
  decode that code-page.

  To put that another way, given an external byte sequence
  accessed using pipes, FIFOs, sockets, c, if it is to be
  interpreted as bytes, there is no question about what its
  contents are, but if it is to be interpreted as characters,
  the information needed to discern what the characters _are_
  is as a rule not in that byte sequence.

- The buffers transferred in a read() or write() call are not
  strings either.  They are *chunks* of a byte sequence.  (Oh,
  and if you have wide character data inside your program, it
  is very likely to be a bad idea to transput them directly
  this way.)  write(fd, record, sizeof record) is not uncommon.

- The size of an external byte sequence accessed using pipes,
  FIFOs, sockets, c is not knowable through that interface.
  The information can be conveyed by some other means, but
  it cannot be trusted.  (I could _say_ that there are 400 bytes
  but _send_ 500, or 300.)  The interface is a *stream*
  interface, not a *string* interface.

- Only forward traversal is possible.
 
 As an aside: modern usage types the buf as void * .  The version 7 unix 
 manuals on which I grew up (and first edition of KR), there was no void; buf 
 would be just 'char *buf; '

Version 7 did have void but did not have void *.
Since void * and char * are required to have identical 

Re: [Haskell-cafe] How to read a file and return a String?

2013-09-04 Thread Richard A. O'Keefe
The original poster wants to
 - read a file
 - get the contents as a String
 - break the string into lines
 - do something with the lines
 - and presumably print the result

Easy.  Put the following lines in a file called 'rf.hs':

file_name = rf.hs

main =
readFile file_name = \string - putStr (process (lines string))

process lines = maximum lines ++ \n

Then
m% ghc rf.hs
m% ./rf
=  process lines = maximum lines ++ \n

Explanation:

   readFile file_name
is an IO action which when performed will read the named file
and deliver a string

   cmd1 = \x - cmd2
is an IO action which when performed will first perform cmd1,
then bind its result to x, and then perform cmd2.
= is the fundamental operation for chaining actions together.

   lines
is a plain old String - [String] function

   process
is a plain old [String] - String function, whatever you want

   putStr x
is an IO action which when performed will write x

The run time environment causes main to be performed.



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


Re: [Haskell-cafe] stream interface vs string interface: references

2013-09-03 Thread Richard A. O'Keefe

On 3/09/2013, at 5:17 PM, damodar kulkarni wrote:
 I didn't want to clutter that thread so I am asking a question here.
 Where do I find foundational and/or other good references on the topic of 
 stream interface vs string interface to convert objects to text? I tried 
 google but failed. 

It has to do with the cost of string concatenation.

Let's take a simple thing.
A Set of Strings.

Smalltalk has

String
  printOn: aStream
aStream nextPut: $'.
self do: [:each |
  each = $' ifTrue: [aStream nextPut: $'].
  aStream nextPut: each].
aStream nextPut: $'.

(Smalltalk uses '' for strings with quote doubling for embedded
quotes and has no character escapes.  s nextPut: c writes character
c to stream s.  do: [:...] is a loop.)

Set
  printOn: aStream
|started|
started := false.
aStream nextPutAll: 'a Set ('.
self do: [:each |
  started ifTrue: [aStream space] ifFalse: [started := true].
  each printOn: aStream].
aStream nextPut: $'.

Object
  printString
|stream|
stream := WriteStream on: (String new: 40).
self printOn: stream.
^stream contents

(A WriteStream is an internal stream.  It starts with the
array-like object you give it and grows it, typically by
doubling, as needed.  `contents' returns the part actually
written to.)

Let's actually do something subtly different.
Each Set will contain the printString of a number
and also another set, so
   a Set('3' a Set('2' a Set('1' a Set(

s := Set new.
1 to: 1000*1000 do: [:i |
s := Set with: s with: i printString].
s printOn: Transcript.

The set having been created, how much allocation is done
by the output phase?   *NONE*.  And the time is *LINEAR*
in the size of the output.

To summarise: Smalltalk makes append print version to output stream
the basic form and obtain print version as a string a derived form.
The result is that printing (acyclic) objects of any size takes time
linear in the size of the output.

Now consider the Java version.
Java makes obtain print version as a string the basic form and
append print version to output stream a derived form.

There's a nasty little wrinkle which is that foo.toString() is
foo instead of the expected \foo\ in Java.  So the output
will be [3, [2, [1, []]] or something like that.

String {
String toString() {
return this;
}
}

HashSet {
String toString() {
StringBuilder b = new StringBuilder();
boolean started = false;
b.append([);
for (Object o: this) {
if (started) b.append(, ); else started = true;
b.append(o.toString());
}
b.append(]);
return b.toString();
}
}

This takes *QUADRATIC* time, but it's annoyingly hard to demonstrate
because it keeps crashing with a stack overflow for even quite small n.
Thankfully, the -Xss option comes to the rescue.

ntime (seconds)
  1000.16
  2000.18
  5000.22
 10000.30
 20000.62
 50002.58
1   12.08
2   51.54

Not only does it take an obscene amount of time to print a large
object, it turns over a totally unwarranted amount of space.

Now you might object that sets like this are not realistic.
If you are trying to write large circuits or abstract syntax
trees or the like to a file, or using this *style* even if
not this specific *interface* to write XML documents, the
example errs by being unrealistically *easy* for Java.
It's easy to understand what's going wrong.

Consider [2, [1, []]]
When visiting {}, we create [].  So far so good.
When visiting {1, {}}, we *copy* the [] into [1, []].
When visiting {2, {1, {}}}, we *copy* the [1, []] into
[2, [1, []]].
And so it goes.  This does an awful lot of copying and
*none* of it is needed given a sane interface.

What is the take of Haskell on this?
There is a *reason* 'shows' exists.

newtype Date = Date (Int,Int,Int)
instance Show Date
  where showsPrec _ (Date (y,m,d)) rest =
 Date ( ++ shows y (, ++ shows m (, ++ shows d () ++ rest)))

The only uses of ++ here are where the left operand is a short literal.
Using this approach, Haskell programs can produce strings in linear time
and linear space.

For lazy I/O, using shows in Haskell is a good analogue of using
#printOn: in Smalltalk.  The basic form is include this as PART of
a stream, with convert this to a whole string as a derived form.

What the equivalent of this would be for Iteratees I don't yet
understand.



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


Re: [Haskell-cafe] Reasoning about performance

2013-09-03 Thread Richard A. O'Keefe
allPairs2 can be simplified using a trick I wouldn't dare use in
any language but Haskell:

triangle4 xs = fused undefined [] xs
  where fused x (y:ys) zs = (x,y) : fused x ys zs
fused _ [] (z:zs) = fused z zs zs
fused _ [] [] = []

I submit this just for grins; it happens to be a touch faster but
not enough to bother about.

While the result _isn't_ all possible pairs of elements, making
the allPairs name a bit dodgy, it _does_ have O(|xs|**2) of them...

I would be surprised if the relative performance of two
approaches in ghci were always the same as their relative
performance in ghc.


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


Re: [Haskell-cafe] function arithmetic?

2013-09-01 Thread Richard A. O'Keefe

On 1/09/2013, at 7:06 PM, Christopher Howard wrote:
 It seemed to be suggesting that a Num instance for functions would imply the 
 need for constant number functions, which leads to difficulties. But I don't 
 see why one would have to take it that far.

You *cannot* make a type an instance of Num without saying how to
map integer literals to that type.  If you want (f+g)x = fx + gx
then having 2x = 2 makes perfect sense, because then (f+2)x = fx + 2
just as an APL or S programmer would expect.

The fact that 2(x+y) will then evaluate to 2 without evaluating x or y
is unfortunate, but inevitable.  I'm sure I could live with it.





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


Re: [Haskell-cafe] Can I use String without in ghci?

2013-09-01 Thread Richard A. O'Keefe

On 1/09/2013, at 6:02 PM, yi lu wrote:

 I want to know if it is possible that I use strings without .
 
 If I type
 Preludefoo bar
 which actually I mean
 Preludefoo bar
 However I don't want to type s.
 
 I have noticed if bar is predefined or it is a number, it can be used as 
 arguments. But can other strings be used this way?

If bar is predefined, it *isn't* the string 'b':'a':'r':[].
If bar is a number, it *isn't* a string.
So other strings is quite misleading.

In Haskell, if you use strings a lot, you are probably doing
something wrong.  For things that are not text manipulation
tasks, there is practically always a better type, and these
days, for things that _are_ text manipulation, there is
practically always a better type.

A slogan I have programmed by since I first met C and recognised
how vastly superior to PL/I it was for text manipulation _because_
it didn't have a proper string type is Strings are Wrong!.



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


Re: [Haskell-cafe] Can I use String without in ghci?

2013-09-01 Thread Richard A. O'Keefe

On 2/09/2013, at 3:55 PM, Rustom Mody wrote:

 On Mon, Sep 2, 2013 at 5:43 AM, Richard A. O'Keefe  wrote:
 

 A slogan I have programmed by since I first met C and recognised
 how vastly superior to PL/I it was for text manipulation _because_
 it didn't have a proper string type is Strings are Wrong!.
 
 I wonder if you notice the irony in your use of 'C' as exemplar in this 
 context?

In all seriousness, a text editor application written in C was
*an order of magnitude* smaller in C than in PL/I *because* of
the lack of a string data type.

 C rode to fame on the back of Unix. And Unix's innovation – one of many – is 
 that at the OS level the string type was made common fare – a universal type. 
  So everything from file names to file contents to IPC is a string.

The idea of file names being strings was no innovation.
Yes, in crippled monstrosities like TOPS-10 file names were
weird records -- I can still remember too much of the details --
and every ruddy TOPS-10 program had to do its own file name
parsing and it seemed as if they all did it differently.  But
the B6700 MCP interfaces treated file names as strings before
UNIX was dreamed of.

File contents in UNIX are *not* strings and never have been --
NUL termination is no part of files and binary files have been
commonplace since the beginning (an a.out file is not a string!).
They are *byte arrays*.

As for IPC, since when have System V shared memory, semaphores,
or message queues had anything to do with strings?
(Hint: the 'name' of a System V shared memory segment is a
 key_t, and that's an integral type, not a string.
 Hint: the 'name' of a System V semaphore is also a key_t
 integer, not a string.
 Hint: the 'name' of a System V message queue is also a key_t
 integer, not a string.
 Hint: messages sent using msgsnd are not strings, they are
 byte arrays with a separate count parameter.
)

Classic UNIX uses strings for file names, and really, that's it.
(The command line argv[] is not really an exception, because it
was used for file names as well as options, and in fact mixing
the two up caused endless problems.)
Everything else in V7, S3, or SysV was identified by a *number*.
Plan 9 has exit(string) but Unix has exit(byte).

From the perspective of someone who used UNIX v6 in 1979,
*POSIX* IPC -- with its IPC objects *might* be in the file
system but then again might *not* be so their names are
sorta-kinda-like file names but not really) -- and /proc are
recent innovations.

The idea that 'string' was even remotely like a universal type
in UNIX is bizarre.

Heck, UNIX never even used 'string' for *lines* in text files!

 Of course when instructing a beginning programmer your basic premise 'Strings 
 are Wrong!' is most likely right.

No, I'm talking about experienced programmers writing high performance
programs.

  However if programs are seen as entities interacting with an 'external' 
 world, the currency at the portals is invariably string.

- The currency at the portals is *not* invariably string.
  Learn PowerShell.
- Text is one thing and string is another.  This was the
  B6700 lesson (well, really the B5500 lesson): for many purposes
  you want a text *stream* not a text *string* at the interface.
  It's also the what-Smalltalk-got-right-and-Java-got-wrong
  lesson: the right way to convert objects to text is via a
  *stream* interface, not a *string* interface.

  And more than just noob programmers have got this wrong – think of the 
 precious one-byte opcodes that Intel wastes on ascii and decimal arithmetic.

Hang on, they are there in order to *support* the numbers are text model.
You can't have it both ways.

 So while this is true:
 
 If bar is predefined, it *isn't* the string 'b':'a':'r':[].
 If bar is a number, it *isn't* a string.
 So other strings is quite misleading.
 
  in the innards of haskell, bar is a string

No, in the innards of Haskell, bar is possibly a number,
possibly a pointer to some sort of record, possibly some
other data structure, but almost certainly *not* a string.


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


Re: [Haskell-cafe] abs minBound (0 :: Int) negate minBound == (minBound :: Int)

2013-08-20 Thread Richard A. O'Keefe

On 20/08/2013, at 6:44 PM, Kyle Miller wrote:
 By working as expected I actually just meant that they distribute (as in 
 a(b+c)=ab+ac) and commute (ab=ba and a+b=b+a),

That is a tiny fraction of working as expected.
The whole modular arithmetic argument would come close to
having some virtue, *except* that division just plain does not
fit.  In particular, it's painfully easy to find x y such that
 (x*y) div y is not congruent to x modulo 2**n.

The existence of division makes the everything's OK because
it's modular argument look very sick indeed.

  The interpretation of any of these numbers being positive or negative is 
 specious, but people still do it because it works reasonably well for small 
 integers.

No, they do it because their programming language specifications
encourage them to do it, because their introductory courses teach
them to do it, and their compilers, on seeing x  0, do not scream
at them that is not well defined!, so the idea that it is
supposed to work is constantly reinforced.  And above all, people
still do it because in most programming languages they have no
practical alternative.

  Also, there's the definite advantage that you can use the same instructions 
 for adding/multiplying signed and unsigned integers (for instance, pointer 
 arithmetic).

As the user of a programming language, what conceivable advantage
is that to me?  All the machines I have access to these days have
two sets of multiply and divide instructions, and there have been
machines with two sets of add and subtract instructions, and it is
no big deal.

The B6700 had one set of instructions (which actually dealt with both
integers and floating point).  It didn't have _any_ instructions for
unsigned integer arithmetic, and Fortran, COBOL, BASIC, Pascal, Algol,
and PL/I programmers didn't miss them.  (In particular, to a B6700
programmer familiar with his/her machine's instruction set, the idea
that variable access might have anything to do with unsigned
operations would have seemed, heck, did seem quite bizarre.)

For that matter, IBM mainframes have had, since the 1960s,
A   signed Add
AL  unsigned Add Logical
S   signed Subtract
SL  unsigned Subtract Logical
M   signed Multiply \ 
ML  unsigned Multiply Logical   | these four
D   signed Divide   | are common
DL  unsigned Divide Logical /
and it never stopped them being fast.  I doubt that the presence of
these instructions had any significant effect on the complexity of
the machines.  Even some 1980s single-chip machines did this.

 You mention that the B6700 trapped on overflows.  While this is a nice 
 feature, this has nothing to do with the number format.

That's half true.  The B6700 number format was such that there was nothing
sensible they _could_ do on integer overflow.  (Look it up or trust me;
truncation would have been violently unnatural on those lovely machines.)

 One example of a nice thing about doing computations modulo 2^n is that you 
 can do a bit twiddling trick called reciprocal multiplication (maybe 
 sometimes called magic number multiplication).  One reference for this is at 
 [1].  Another reference is Hacker's Delight.  But maybe you can save this for 
 your ear's fingers.

I have a copy of Hacker's Delight within arm's reach.
This is not really something that people writing applications want.
Usually, what they need is affordable multiplication and division
that give right answers when right answers are to be had and don't
drive the program insane with rubbish when right answers are not to
be had.

There are plenty of clever things computer architects can do, up to
and including keeping a last divisor cache in the division unit
to accelerate divisions that reuse a recent divisor.

 I can't really say I understand why anyone would actually want to use Int 
 (unless they knew they wanted a modulo 2^n Int).

Because they are calling an existing function that requires it.

It's just like the question the only integral type in standard C that
*cannot* be used safely to hold an 8-bit character is char, so why
would anyone want to use char*?  Answer: because of all the library
functions that demand it.

 but Integer is actually (if you're using GMP with your ghc):

Yes, that's tolerably well known.  You only pay the space overhead
when you need it (like Lisp or Smalltalk).  But you always pay the
time overhead.

 Where are you getting that about C?  Do you mean that it's careful to allow 
 implementations to decide to trap overflows?  Because as far as I can tell, 
 the C standard just says signed overflows give undefined behavior.

The thing is that the standardisers *could* have defined signed int arithmetic
to wrap (just like the benighted Java designers did) but they *chose* to leave
the effect undefined (just like the Pascal standard) *so that* implementations
that trap on overflow (which 

Re: [Haskell-cafe] abs minBound (0 :: Int) negate minBound == (minBound :: Int)

2013-08-19 Thread Richard A. O'Keefe

On 20/08/2013, at 3:43 AM, Kyle Miller wrote:

 On Sun, Aug 18, 2013 at 8:04 PM, Richard A. O'Keefe o...@cs.otago.ac.nz 
 wrote:
 The argument for twos-complement, which always puzzled me, is that the other
 systems have two ways to represent zero.  I never found this to be a problem,
 not even for bitwise operations, on the B6700.  I *did* find abs x  0
 succeeding to be a pain in the posterior.  (The B6700 had two different tests:
 'are these two numbers equal' and 'are these two bit patterns equal'.)
 
 I think a better argument for twos complement is that you're just doing all 
 of your computations modulo 2^n (where n is 32 or 64 or whatever), and 
 addition and multiplication work as expected modulo anything.

To me, that's not a better argument.  It isn't even a _good_ argument.
It amounts to saying if you do things wrong, you can justify it by
saying you're really doing something else right, and it's the programmer's
fault for wanting the wrong thing.

One great thing about the B6700 was that you were guaranteed
EITHER the mathematically correct answer in the numbers you were
thinking in terms of OR an exception telling you the machine couldn't
do what you wanted.  When it comes to *applications* programming,
the number of times I have *wanted* arithmetic modulo 2^n (in the last
40 years) can be counted on the fingers of one ear.

You may call it multiplication work[ing] as expected when the product of two
positive numbers comes out negative; I call it a wrong answer.

Prelude let tens = 1 : map (*10) tens :: [Int]
Prelude take 19 tens
[1,10,100,1000,1,10,100,1000,1,10,100,1000,1,10,100,1000,1,10,100]
Prelude [x * x | x - take 19 tens]
[1,100,1,100,1,100,1,100,1,100,7766279631452241920,1864712049423024128,2003764205206896640,-2537764290115403776,4477988020393345024,5076944270305263616,-8814407033341083648,4003012203950112768,-5527149226598858752]

Yes, I know that Haskell has Integer.
If I want to do more arithmetic than a bit of simple counting,
I like to use it.
The gibberish that Int multiplication spewed out above is why.

Roughly speaking, there are three ways to handle integer
arithmetic: the Lisp way, the Ada way, and the Java way.
Lisp just gets it right (think Haskell's Integer type).
Java *defines* wrong answers to be right.
Ada recognises that sometimes you want modular arithmetic (so it offers you
modular types) and sometimes you don't (so it offers you bounded but
non-modular types, where overflow is trapped).

Even the C standard is careful to allow signed arithmetic to trap overflows.

When we tell our students that there is an integer N  0 such that N+1  0,
first they are shocked and confused, then they forget about it, and then
they are caught by it, and at last they remember it, but aren't sure what
they can _do_ about it in Java.


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


Re: [Haskell-cafe] abs minBound (0 :: Int) negate minBound == (minBound :: Int)

2013-08-18 Thread Richard A. O'Keefe

On 19/08/2013, at 3:38 AM, Nicolas Frisby wrote:

 The docs at
 
   
 http://www.haskell.org/ghc/docs/latest/html/libraries/base/Prelude.html#v:gcd
 
 give a NB mentioning that (abs minBound == minBound) is possible for 
 fixed-width types.

At least three ways to represent negative integers in binary have been used:
- twos-complement   (asymmetric, -INT_MIN == INT_MIN, abs can have a negative 
result)
- ones-complement(symmetric, -INT_MIN == INT_MAX, abs is always 
non-negative)
- sign-and-magnitude (symmetric, -INT_MIN == INT_MAX, abs is always 
non-negative)

Having used a B6700 as an undergraduate, I still think sign-and-magnitude is the
only really safe-and-simple scheme.  However, twos-complement has conquered.

The argument for twos-complement, which always puzzled me, is that the other
systems have two ways to represent zero.  I never found this to be a problem,
not even for bitwise operations, on the B6700.  I *did* find abs x  0
succeeding to be a pain in the posterior.  (The B6700 had two different tests:
'are these two numbers equal' and 'are these two bit patterns equal'.)

 Two questions:
 
   1) This behavior surprised me. Does it surprise enough people to include a 
 warning in the Haddock for abs and negate?

We cannot expect everyone who uses Haskell to be familiar with
the eccentricities of popular hardware.  I think it's worth mentioning.

   2) Is this a common behavior in other languages?

Yes.

 My tinkering with gcc suggests it does not support the value -2^63, but 
 instead bottoms out at (-2^63+1).

Your tinkering was insufficient.

f% cat 2c.c
#include stdio.h
#include limits.h

int main(void) {
printf(%d\n, INT_MIN + INT_MAX);
return 0;
}
f% gcc 2c.c
f% a.out
-1

Oh wait.  You said 63, not 31.

Change the key line to

printf(%lld\n, LLONG_MIN + LLONG_MAX);

LLONG_MIN is going to be -(2**63) on any SPARC, x86, x86-64,
Power(PC), Alpha, ARM, MIPS, or z/Series machine, and a host
of others.

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


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


Re: [Haskell-cafe] Alternative name for return

2013-08-07 Thread Richard A. O'Keefe

On 7/08/2013, at 2:10 PM, damodar kulkarni wrote:

 I bet you can find an abundance of C programmers who think that
 strcmp is an intuitive name for string comparison (rather than compression, 
 say).
 
 But at least, 'strcmp' is not a common English language term, to have 
 acquired some unintentional 'intuition' by being familiar with it even in our 
 daily life. The Haskell terms, say, 'return' and 'lift', on the other hand, 
 do have usage in common English, so even a person with _no_ programming 
 background would have acquired some unintentional 'intuition' by being 
 familiar with them.

Lift is - a brand of soft drink, the thing Americans call an elevator, 
a thing put in your shoes seem taller, and a free ride, amongst other things.
As a verb, it can mean to kick something.

To find lift intuitive, you have to be familiar with the *mathematical*
idiom of lifting a value from one space to another via some sort of
injection.  Fair enough, but this *still* counts as an example of
intuitive = familiar, because this is *not* a sense of lift that is
familiar to undergraduate and masters computing students unless they have
taken rather more mathematics papers than most of them have.

If you're familiar with *English* rather than, say, the C family of
programming languages, return isn't _that_ bad, there is certainly
nothing about the word that suggests providing a value.  I once tried
to propose a C-style 'return' statement to some people who were
designing a programming language, before I or they had ever heard of
C, and they flatly rejected it.  Months later I found out that this
was because they were looking for something that did not just resume
the caller but also provided a value, and when I protested that that's
exactly what 'return' did in the languages I proposed stealing from,
they -- being familiar with Fortran -- said that it had never occurred
to them that 'return' could have anything to with providing a value.

It is intuitive has no other discernable meaning than *I* am familiar with 
it,
or something very much like it.

_That's_ the point I want to make.  *Whatever* anyone uses for Haskell's
return, many people are bound to find it unintuitive.  Choose a name
on any grounds but that.



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


Re: [Haskell-cafe] Alternative name for return

2013-08-07 Thread Richard A. O'Keefe

On 7/08/2013, at 9:17 PM, Jerzy Karczmarczuk wrote:
 I am the last here who would quarrel with Richard O'K., but I firmly believe 
 that such reasoning is a Pandora box. 
 
 The King, the government, the Pope, etc. have no power, only the 
 interpretation of their decrees by outer agents _does_ things.

I regard the analogy as flawed because my sovereign
[Her Majesty Elizabeth the Second, by the Grace of God Queen of New Zealand
 and Her Other Realms and Territories, Head of the Commonwealth, Defender
 of the Faith/Her Majesty Elizabeth the Second, by the Grace of God, Queen
 of Australia and Her other Realms and Territories, Head of the Commonwealth
 (I have dual citizenship, so she gets to be my Queen twice)
] is a moral agent, so is the Bishop of Rome, and so are my Prime Ministers
John Key and Kevin Rudd.  These people are agents in their own right; they
and the people who follow their orders are _things of the same kind_.

Maybe the analogy isn't that flawed. Julia Gillard found out that when
enough people stopped saying yes to her, her power disappeared like
morning dew.  The official teaching of the Roman church is that
contraception is not OK, yet the 2013 birth rates for Spain and Portugal
were about 1.5.  It really does look as though the Pope's power does rest
on the consent of the people: if people don't like what he tells them,
they don't do it.

I leave it to other readers with a misspent youth to supply the name and title
of the Science Fiction story in which FIW is the political key.

Analogies are helpful if they help.  Comparing IO 'actions' to plain old data
like a magnetic card key and the Haskell environment to the reader helped _me_;
if it helps no-one else, forget it.


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


Re: [Haskell-cafe] Alternative name for return

2013-08-07 Thread Richard A. O'Keefe

On 8/08/2013, at 2:09 AM, damodar kulkarni wrote:
 Thanks for pointing this out, I was not able to point my thoughts in this 
 direction.
 
 But I still have a doubt: if my familiarity doesn't come in the form of some 
 analogy, then my acquired intuition about it would be of little use. In 
 fact, it may well be misleading. Am I correct?

Very much so.  This is why I despise, detest, and loathe as abominations
programming languages in which string concatenation is written +.
(If you want a binary operation which is associative and has an identity
but doesn't commute, the product lies ready to hand, and the repeated
product (exponentiation) is actually _useful_ for strings.  It's still
better to use a non-arithmetic operator, as PL/I, Fortran, Ada, and Haskell do.)

 If so, the best we can hope is the name-giver to describe, as explicitly as 
 possible, the analogy (sort of a thought process) he/she had had in his/her 
 mind while giving a particular name to a given concept?

Complete agreement from me.

For what it's worth, return can mean to shift back to a previous topic,
so it's not _that_ crazy for when you've switched from a monadic context
to a pure context and are now switching back.


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


Re: [Haskell-cafe] Alternative name for return

2013-08-07 Thread Richard A. O'Keefe

On 8/08/2013, at 2:56 AM, Donn Cave wrote:
 The RFC822 headers of your email suggest that you use a Macintosh computer,
 so apart from the apparently disputable question of whether you're familiar
 with English, you have the same online dictionary as mine.

My department has an electronic subscription to the OED.

 Second definition:
 give, put, or send (something) back to a place or person, with examples
 she returned his kiss, usage from tennis and football, verdicts, etc.
 Third definition:  yield or make a profit, fourth (re)elect a person or 
 party.
 Return is all about providing a value, in English.

Check the OED.  Most of its meaning are about _turning back_,
_resuming_, _reverting_.  Yielding or making a profit is not at
all about providing a value, but about money going out AND
COMING BACK.  It's the coming back part that makes it a return.

value occurs twice in OED 'return, v.1, in neither case
referring to providing a value.
OED re-turn, v.2 has value once, again not referring to
providing a value (in fact, to detecting possible theft).
OED return, n has the fact or an instance of bringing value
in exchange for effort or investment, where the salient part
is IN EXCHANGE FOR:  effort going out, value COMING BACK.
There are two other similar senses, out of I don't know how
many senses (because I lost count after 80).

A return can be a reply, answer or retort (as in the Fool's
Marry, it was a sharp retort in one of the Discworld novels,
when an alchemist's vessel exploded), a summary of a [cricket]
play's bowling or batting performance, a response to a demand,
a wing or side of a building, or a side street, among many
other things.

In all of the senses, the underlying idea is not provision of a
value, but going, turning, or bending back.

 When a term like return is used in a computer programming language in
 a sense that confounds any prior expectation based on English or other
 programming languages, that's the opposite of intuitive.

OK, so when in the past someone met RETURN in their second programming
language, what had their experience taught them to expect?

ISO/IEC 1989:20xx CD 1.2 (E)

14.9.32 RETURN statement

The RETURN statement obtains either sorted records from the final
phase of a sort operation or merged records during a merge operation.

14.9.32.1 General format

RETURN file-name-1 RECORD [ INTO identifier-1 ]
   AT END imperative-statement-1
[ NOT AT END imperative-statement-2 ]
  [ END-RETURN ]

This is a somewhat more elaborate form of a statement which has been
present in COBOL since at least 1974 and probably longer.  The latest
estimate I've seen is that four thousand million lines of new COBOL
are added every year.

Operationally, the COBOL RETURN statement is more like a READ than
anything else.




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


Re: [Haskell-cafe] Alternative name for return

2013-08-06 Thread Richard A. O'Keefe

On 6/08/2013, at 9:28 PM, J. Stutterheim wrote:

 That argument makes sense, although I find it a bit counter-intuitive still.

In discussions like this, I have never been able to discover any meaning for
intuitive other than familiar.  Applying pure to an IO operation doesn't
go against *my* intuition because Haskell has *trained* my intuition to
see 'putStrLn Hi' as a pure value; it's not the thing itself that has effects,
but its interpretation by an outer engine, just as my magnetic card key has by
itself no power to open doors, but the magnetic reader that looks at the card
_does_.  I don't attribute agency to the card!  I'm not arguing that my
intuition is _right_, only that it is _different_.

In particular, for anyone who has much experience with Haskell, return is
almost the only name that could possibly be intuitive because that _is_ the
name that is familiar.  Haskell programmers who've got used to Applicative
will also find pure intuitive, *because it is familiar*.

I bet you can find an abundance of C programmers who think that
strcmp is an intuitive name for string comparison (rather than compression, 
say).



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


Re: [Haskell-cafe] Haddock GSOC project progress

2013-07-31 Thread Richard A. O'Keefe

On 31/07/2013, at 8:16 PM, Simon Hengel wrote:
 
 * There is no such thing as a parse error in Markdown, and I think we
   should try to make this true for Haddock markup, too

It is very far from clear that this is a virtue in Markdown.
In trying to learn Markdown, I found it an excessively tiresome
defect.  Whenever I was trying to learn how to produce some
combination of effects, instead of Markdown telling me
at THIS point you had something I wasn't expecting, it would
just produce incorrect output, defined as anything other than
what I intended.  It also meant that two different Markdown
processors would accept the same text silently but do different
things with it.

This is one of the reasons I won't use Markdown.


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


Re: [Haskell-cafe] Proposal: Non-recursive let

2013-07-25 Thread Richard A. O'Keefe

On 25/07/2013, at 7:09 PM, o...@okmij.org wrote:
 Here is a snippet from a real code that could benefit from
 non-recursive let. 

[[A big blob of extremely dense code.]]

_Nothing_ is going to make that easy to read.

And I say that as someone who loves Haskell and is in *awe* of
Oleg.  I mean, if the functional rain is pouring down and Oleg
says Hey, sunny!, I normally furl my umbrella...

One of the things that I find makes it hard for _me_ to read
is the coding style where do is sneaked away out of sight.
Am I alone in wanting do at the _beginning_ of a line so
that it stands out?  Do real Haskell experts just get used to
using do so much that they don't feel it's _worth_ making
visible?

It's a queer thing, I always feel that the advice about
keeping function bodies small is patronising nonsense for
beginners and that *my* code is perfectly readable no matter
how big it is, but end up wishing that *other* people kept
*their* functions small.  It's not as if my code were bug-free...
Must be something in the water.

That's relevant though.  If your functions are small, you don't
get enough versions of a variable for non-recursive let to pay off.

In this specific example, as a _reader_, a much less competent
reader than Oleg, the only problem I can see with using ast1
and header1 is that th names are not different *ENOUGH* from
ast1 and header.  I'd like names that go some towards
explaining *why* 'ast1' has _token and _period_values slots
that 'ast' doesn't (and for that matter, something a bit longer
than 'ast', which doesn't seem to stand for Abstract Syntax Tree
here), and *why* 'headers1' shouldn't include _limit_to and
_limit_rcvd slots unless there is a title.

All in all, a good example of code where using non-recursive let
would have DECREASED readability by one person strange to the code.

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


Re: [Haskell-cafe] Proposal: Non-recursive let

2013-07-22 Thread Richard A. O'Keefe

On 21/07/2013, at 7:36 AM, Evan Laforge wrote:
 Just by coincidence, I recently wrote this:

This is a BEAUTIFUL example.
I think we may disagree about what it's an example OF,
however.  I found the code a little difficult to
follow, but when that's fixed up, there's no longer
any reason to want non-recursive let, OR a monad.

I've run out of time tonight, but hope to say more tomorrow.


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


Re: [Haskell-cafe] Proposal: Non-recursive let

2013-07-22 Thread Richard A. O'Keefe

On 22/07/2013, at 8:14 PM, Andreas Abel wrote:

 Just today, my student asked me why the following program does nothing:

Did you ask your student why their code should not be torn into pieces,
burned to ashes, and incorporated into a pot for radioactive waste?

All those occurrences of unsafePerformIO!

(OK, so I wouldn't _really_ be rude to a student like that.
 But I'd have a hard time controlling my face...)


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


Re: [Haskell-cafe] Proposal: Non-recursive let

2013-07-16 Thread Richard A. O'Keefe
Brian Marick sent me a couple of his stickers.
The one I have on my door reads to be less wrong than yesterday.
The other one I keep free to bring out and wave around:

An example would be handy about now.

All of the arguing to and fro -- including mine! -- about
non-recursive let has been just so much hot air.  I could
go on about how the distinction between 'val' and 'val rec'
in ML was one of the things I came to dislike intensely,
and how Haskell's single coherent approach is one of the
things that attracted me to Haskell.

But why should anyone else care?

When presented with a difficulty, it is very common for some
functional language users to propose adding just one more
feature from some other language, commonly an imperative one
(which ML, Caml, and F# arguably are).  Typically this is
something that _would_ solve the immediate problem but would
create worse problems elsewhere, and there is some other
solution, either one already available in the language, or a
better one that would solve additional problems or cause
fewer ones.

The best help for any discussion is A CONCRETE EXAMPLE OF
REAL CODE.  Not little sketches hacked up for the purpose
of discussion, but ACTUAL CODE.  The person who initially
proposes a problem may think some details are not relevant,
whereas someone else may see them as the key to the solution.

For example, looking at some code in another mostly-
functional language, which had been presented as reason why
we needed a new construct, I rewrote it in less than half
the number of lines using existing constructors, using only
existing features.

Without seeing THE ACTUAL CODE that prompted this thread,
it is impossible to tell whether that might be the case here.

In this specific case, we are seeing state being threaded
through a bunch of updates, and IN THE ABSENCE OF THE ACTUAL
CODE, it seems to me that monad notation is the most
intention-revealing notation available for the purpose in
Haskell, and if Haskell did have non-recursive let it would
STILL be best to write such code using a state monad so that
human beings reading the Haskell code would have some idea
of what was happening, because that's how state changes are
supposed to be expressed in Haskell, and anything else
counts as obfuscation.

But THE ACTUAL CODE might show that this case was different
in some important way.



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


Re: [Haskell-cafe] Non-recursive let [Was: GHC bug? Let with guards loops]

2013-07-15 Thread Richard A. O'Keefe

On 15/07/2013, at 8:23 PM, J. Stutterheim wrote:
 The OS dependency for dynamics stems from the fact that the Clean dynamics 
 are quite a bit more powerful than Haskell's. For example, using dynamics, it 
 is possible to send arbitrary functions to another Clean application, which 
 can then dynamically link these functions in at runtime and immediately 
 execute them. It doesn't even need to be the same program, which Cloud 
 Haskell does require (and theoretically, it can even be another OS). This 
 advanced dynamic linking feature requires intimate knowledge of the target 
 OS' binary representation.

There is no obvious reason why it should.
Imagine a programming language implementation where a function
is compiled to some abstract representation (like Kistler's Juice)
and a native representation is added on loading or on first use.
For Oberon, Kistler found that transmitting compressed abstract
syntax trees and generating native code on reception took less
time and yielded better code than sending native code.  Even when
reading from a local disc, loading compressed ASTs and generating
native code on the fly was faster than a conventional dynamic linker.

A major issue here, of course, is that Windows could be 32-bit or
64-bit, x86 or ARM, and even if you restrict attention to one of
these combinations, there are things like exactly what SIMD
instructions are available.

 (I would actually really like to see Haskell's dynamics system to become as 
 powerful as Clean's; it also supports polymorphism, for example)

Perhaps you could say something about the following problem:

I have a data structure that includes some functions.
These functions use version X of module M.
I send that data structure to another application,
which is using version Y of module M, where Y /= X.

What happens?  This is the primary reason why Erlang has not
imitated Kali Scheme, which could also send functions.
For that matter, what happens if the function is sent to another
application (on a remote machine) that doesn't have _any_
version of module M and doesn't know where to find one?

I am _not_ suggesting that these are problems that Clean could not solve
or has not solved.  On the contrary, I'm saying that it would be very
interesting to hear how Clean has solved them.

From a security point of view, of course, failing to practice Safe Hex
is a bit worrying, but proof-carrying code and signatures can go some
way towards addressing that concern.


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


Re: [Haskell-cafe] ordNub

2013-07-15 Thread Richard A. O'Keefe

On 16/07/2013, at 3:21 PM, Clark Gaebel wrote:
 
 I'm still against having an Ord version, since my intuition tells me
 that hash-based data structures are faster than ordered ones.

There are at least four different things that an Ord version might
mean:

 - first sort a list, then eliminate duplicates
 - sort a list eliminating duplicates stably as you go
   (think 'merge sort', using 'union' instead of 'merge')
 - build a balanced tree set as you go
 - having a list that is already sorted, use that to
   eliminated duplicates cheaply.

These things have different costs.  For example, if there are N
elements of which U are unique, the first as O(N.log N) cost,
the third has O(N.log U) cost, and the fourth has O(N) cost.

What I want is more often ordNubBy than ordNub, though.

 Someone
 else can write the patch, though!
 
 As a tangent, can anyone think of a data structure for which you can
 write an Ord instance but Hashable/Eq is impossible (or prove
 otherwise)? How about the converse?

Since Ord has Eq as a superclass, and since 0 is a functionally
correct hash value for anything, if you can implement Ord you
can obviously implement Hashable/Eq.  Whether it is *useful* to
do so is another question.

It turns out that it _is_ possible to define good quality hash
functions on sets, but most code in the field to do so is pretty bad.
(Just a modular sum or exclusive or.)

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


Re: [Haskell-cafe] Non-recursive let [Was: GHC bug? Let with guards loops]

2013-07-14 Thread Richard A. O'Keefe

On 12/07/2013, at 6:12 PM, Andreas Abel wrote:
[I can't try your F# example but ocaml does something different.]

Yes.  They are different languages.

By the way, I used the F# that comes with Mono.

 On 12.07.2013 02:22, Richard A. O'Keefe wrote:
 For what it's worth,
 
 let x = 1 in
 -   let x = x+1 in
 - let x = x+2 in
 -   x;;
 
 prints
 
 val it : int = 4
 
 in the F# interactive system, but
 
 let x = 1 in
 - let x = x+1 in
 - let x = x+2 in
 -   x;;
 
  let p = e in body
 
 is just
 
  (\ p - body) e
 
 it cannot be simpler than that.

True.  But it *can* be more complex than that,
and in F# it *is*.

  So I do not see your point.

The differently indented versions of the nested let do
different things.  Although F# is a descendant of Ocaml,
it is not the case that all lets in F# allow shadowing.

That's the point.


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


Re: [Haskell-cafe] Non-recursive let [Was: GHC bug? Let with guards loops]

2013-07-14 Thread Richard A. O'Keefe

On 13/07/2013, at 11:27 PM, J. Stutterheim wrote:
 - they then abandoned the Macintosh world for
  Windows.  The Mac IDE was killed off; there is
  now an IDE for Windows but not MacOS or Linux.
 
 The good news is that the latest version of Clean[2] and its code 
 generator[3] now works fine again on 64 bit Mac OS X

Is that still the command-line tools, or has the IDE been resurrected?

 - other major features remain Windows-only
 
 The bad news is that this is true to some extend; the dynamics system is 
 still largely Windows-only. However, this is the only language feature I can 
 think of that really is Windows-only.

I have never been able to understand why there should be ANY
OS-dependency in the dynamics feature.

 - the available books about Clean are way out of
  date, several drafts of other books remain
  incomplete.
 - the documentation (like the Report) has always been
  rather amateurish and incomplete.  Certainly
  compared with the Haskell documentation.
 
 An iTasks book is actually in the works, which will contain a fair bit of 
 Clean (although it is not a dedicated Clean book). There are also concrete 
 plans to update the language manual soon-ish.

Not to be offensive, because after saying Denk U I have no more
Dutch words I can use, but it would really pay to find a native
speaker of English to give the manual a final polish.
 
 - there is nothing to compare with the Haskell Platform.
 
 Actually, yes there is[4].

A misundertanding.  Nothing to compare with is idiomatic for
nothing of comparable size to.  Yes, you _can_ compare the
Clean Platform with the Haskell Platform; it's a lot smaller.

 It can be described as a mix between Haskell Platform and a mini Hackage-like 
 repository. There is no such thing as a Clean alternative to cabal install, 
 though.
 
 Keep in mind that there is only a handful of people working on Clean, while 
 Haskell has a huge community in comparison. 

Haskell has always benefited from
- openness
- multiple implementations
- documentation


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


Re: [Haskell-cafe] Non-recursive let [Was: GHC bug? Let with guards loops]

2013-07-11 Thread Richard A. O'Keefe

On 11/07/2013, at 6:16 PM, o...@okmij.org wrote:

 
 I'd like to emphasize that there is a precedent to non-recursive let
 in the world of (relatively pure) lazy functional programming.

So what?  You can find precedents for almost anything.
I could even point you to a lazy mostly-functional language
with assignment statements in which an identifier occurrence
may refer to two different variables in the course of execution.

Having a precedent doesn't mean that it's a good thing.

 The programming language Clean has such non-recursive let

I am familiar with Clean and used it quite a bit for several years.
My experience with that Clean idiom is *WHY* I hate this usage and
love monads.
 
 Let me point out the latest Report on the programming language Clean
http://clean.cs.ru.nl/download/doc/CleanLangRep.2.2.pdf

which I already have.  If the Clean developers hadn't decided to
concentrate on Windows, leaving the systems I used to wither,
and if they hadn't made fairly massive changes to the language
that broke all my code, it's _possible_ that I might eventually have
come to regard this style as acceptable.

 It seems the designers of Clean have the opposite view on the explicit
 renaming (that is, sequential numbering of unique variables).

That is so.  If that's what you want, you know where to find it.

Like I said, precedent is not proof of goodness.

 
readchars:: *File - ([Char], *File)
readchars file
#(ok,char,file)   = freadc file
|not ok   = ([],file)
#(chars,file) = readchars file
=([char:chars], file)

This is *PRECISELY* the kind of stuff that I find confusing.
If they would just *NUMBER* the states so that I can tell what
is happening when, I would be so much happier.

 The code uses the same name 'file' all throughout, shadowing it
 appropriately. Clean programmers truly do all IO in this style, see
 the examples in
http://clean.cs.ru.nl/download/supported/ObjectIO.1.2/doc/tutorial.pdf
 
 [To be sure I do not advocate using Clean notation '#' for
 non-recursive let in Haskell. Clean is well-known for its somewhat
 Spartan notation.]

I wouldn't call Clean Spartan.  Clean syntax is elaborate.
It achieves brevity not by avoiding keywords but by using
punctuation marks for them, as in [t] vs [!t] vs [|t]
-- does it leap to the eye that [t] is lazy, [!t] is head
strict, and [|t] is strictness-polymorphic? --
and the very important distinction between
a *function* f x = e and a *macro* f x :== e.
(There's a reason why the higher-order list processing
'functions' are actually 'macros'.  See page 109 of the report.
There's precedent for a LOT of things that I don't want in Haskell.)

 State monad is frequently mentioned as an alternative. But monads are
 a poor alternative to uniqueness typing.

In this particular case, uniqueness typing is an utter red herring.
People are advocating state monads JUST TO HIDE THE WIRING, not to
get the effect of destructive assignment.
I *agree* that uniqueness typing is a fine thing and recommended it
to the Mercury developers, who adopted it.

I don't care whether they are called monads, state combinators,
or weeblefretzers.  What I care about is that that
 - the states are HIDDEN from the human reader and
 - they are AUTOMATICALLY wired up correctly for the author.

Suppose we have

# (x,s) = foo s
# (y,z) = bar x s
# (z,s) = ugh x y s

where my finger slipped on the s key in the second line and
pressed the z key instead.  Precisely BECAUSE the variable name
is the same each time, nobody notices, not the compiler, not you,
not me.  The program just goes wrong.

With numbered variables,

let (x,s1) = foo s0
(y,z2) = bar x s1
(z,s3) = ugh x y s2
in ...

the compiler notices that s2 isn't defined.

With suitable combinators,

foo = \x - bar x = \y - ugh x y ...

nobody can make the mistake in the first place,
because the state variable isn't _there_ to get wrong.
 
 Why Clean is relatively unknown? Well, why is Amiga?

Clean is relatively unknown because
 - they started in the Macintosh world, and when
   they provided a compiler for the Unix world,
   they did not port their modern graphics and
   I/O library to it.  So you could never write
   a program that would run on Macs and other things.
 - they then abandoned the Macintosh world for
   Windows.  The Mac IDE was killed off; there is
   now an IDE for Windows but not MacOS or Linux.
 - other major features remain Windows-only
 - the change from Clean 1.3 to Clean 2 was huge,
   like I mentioned above, none of my code survived
   the change, and there was at that time no
   conversion program
 - the available books about Clean are way out of
   date, several drafts of other books remain
   incomplete.
 - the documentation (like the Report) has always been
   rather amateurish and incomplete.  Certainly
   compared with the Haskell documentation.
 - 

Re: [Haskell-cafe] Non-recursive let [Was: GHC bug? Let with guards loops]

2013-07-10 Thread Richard A. O'Keefe

On 10/07/2013, at 8:42 PM, Andreas Abel wrote:
 
 Hear, hear! In OCaml, I can (and often do) write
 
 let (x,s) = foo 1 [] in
 let (y,s) = bar x s in
 let (z,s) = baz x y s in ...

I really wish you wouldn't do that.

After reading Dijkstra's paper on the fact that we have
small heads many years ago -- long enough to forget the
actual title, sorry -- I realised that I too was a Bear
of Very Little Brain and Get Confused Very Easily.

I find that that when the same name gets reused like
that I get very confused indeed about which one I am
looking at right now.

If the variable is hidden (as by the DCG transformation
in Prolog, or a state monad, I don't get confused about
the variable because it isn't visible.

If each instance of the variable is labelled with a
sequence number, I don't get confused because each
variable has a different name and I can *see* which
one this is.

Yes, sequence numbering variable states is a chore for
the person writing the code, but it's a boon for the
person reading the code.

Me, I'd be perfectly happy with

setup (x,s) = state (\_ - (x,s))

(setup $ foo 1 []) = \x -
bar x = \y -
baz x y = \z -
...

One reason for this is that it makes refactorings like
extracting bar ... = ... baz ... thinkable.  A long
sequence of updates is probably crying out for such a
refactoring.


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


Re: [Haskell-cafe] Non-recursive let [Was: GHC bug? Let with guardsloops]

2013-07-10 Thread Richard A. O'Keefe

On 11/07/2013, at 4:00 AM, Donn Cave wrote:
 I've gone to some trouble to dig up an nhc98 install (but can't seem to
 find one among my computers and GHC 7 won't build the source thanks to
 library re-orgs etc.)  Because, I vaguely recall that nhc98's rules
 were different here?  Anyone in a position to prove me wrong?

I have a copy of nhc98 running (v1.16 of 2003-03-08).
Program:

main = let ones = 1 : ones in print $ take 10 $ ones

Output:

[1,1,1,1,1,1,1,1,1,1]

So no, nhc98's rules were _not_ different.
It would have been no use as a Haskell98 compiler if they had been.


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


Re: [Haskell-cafe] Non-recursive let [Was: GHC bug? Let with guardsloops]

2013-07-10 Thread Richard A. O'Keefe

On 11/07/2013, at 11:09 AM, Donn Cave wrote:

 let x = t + 1 in
  let y = x in
  let x = y + 1 in x
 

Still no cigar.
nhc98 v1.16
Program:
main = print $ (let t = 0 in let x = t + 1 in let y = x in let x = y + 1 in x)
Output:
2



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


Re: [Haskell-cafe] question about indentation conventions

2013-07-01 Thread Richard A. O'Keefe

On 2/07/2013, at 12:00 AM, Richard Cobbe wrote:

 Sure.  So my first question boils down to which of the two alternatives
 below does the community prefer?  (To be clear about the intended
 semantics: this is the application of the function f to the arguments x, y,
 and z.)
 
f x
y
z

This (a) clearly violates the Golden Rule of Indentation
 and (b) Goes out of its way to confuse human readers.
I do not know any indenting program that would tolerate
such a layout for C or Lisp.

 or
 
f x
 y
 z
 
 Both are correct, in most contexts.

What part of y and z are PARTS of f x y z and so SHOULD BE INDENTED
relative to the whole expression is hard to understand?

If by correct you mean will not confuse a Haskell parser,
you're right.  If you mean will not dangerously mislead human
readers, only the second form is acceptable.

I do not trust any program to do my indentation.
And let's face it, if your Haskell functions are big
enough that manual indentation is a big issue, they
are too big.



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


Re: [Haskell-cafe] question about indentation conventions

2013-06-30 Thread Richard A. O'Keefe

On 1/07/2013, at 1:04 PM, Richard Cobbe wrote:
 
 I should have been clearer in my original question: I'm curious about what
 to do when a multi-argument function application gets split across lines.
 That wiki page dicsusses how the layout rule interacts with various special
 forms (let, where, if, do, case), but it doesn't seem to address function
 applications, beyond implying that it's ok to indent the continuing lines
 of a function application.

It looked pretty explicit to me:

The golden rule of indentation
...
you will do fairly well if you just remember a single rule:
Code which is part of some expression should be indented 
further in than the beginning of that expression (even if
the expression is not the leftmost element of the line).

This means for example that
f (g x
y
z)
is OK but
f (g x
y z)
is not.



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


Re: [Haskell-cafe] Roman Numeral Problem

2013-06-24 Thread Richard A. O'Keefe
An important question here is whether you want to notice
when a Roman numeral is invalid, e.g., iix, or not.

From a parsing point of view context-free grammars are not
ideal.  We have the patterns
i{1,3} | iv | vi{1,3} | ix  units
x{1,3} | xl | lx{1,3} | xc  tens
c{1,3} | cd | dc{1,3} | cm  hundreds
m{1,3} | mↁ | ↁm{1,3} | mↂ  thousands
so we want to write a grammar rule like


roman(N) --
group('m', 'ↁ', 'ↂ', M),
group('c', 'd', 'm', C),
group('x', 'l', 'c', X),
group('i', 'v', 'x', I),
{N is M*1000 + C*100 + X*10 + I}.
  
group(U, F, T, N) --
( [U,T] - {N = 9}
; [U,F] - {N = 4}
; [U,U,U]   - {N = 3}
; [U,U] - {N = 2}
; [U]   - {N = 1}
; [F,U,U,U] - {N = 8}
; [F,U,U]   - {N = 7}
; [F,U] - {N = 6}
; [F]   - {N = 5}
).

using DCG notation.  This is not context-free.  It is an
attribute grammar with attributes passed down the parse
tree (U, F, T) and passed up the parse tree (N).

Parser combinators are the easy way to do this in Haskell;
see 'parsec' or any number of parser combinator tutorials.

For that matter, it's pretty trivial to do this particular
one with plain code that pretty much mirrors the structure
shown above.  Just write something that takes (as many
arguments as you want) then a list of characters coming in
and returns a pair with a computed answer and the remaining
characters.  But wait!  That _is_ a parser combinator!
I guess parser combinators can't be that hard after all (:-).

Good luck finding the five thousand character (ↁ) or the
ten thousand character (ↂ) or any of the other Unicode
I'm not a letter, no, honest, I'm really not, I'm a
Roman numeral characters on your keyboard.


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


Re: [Haskell-cafe] Haskell Platform 2013.2.0.0 64bit.pkg

2013-06-13 Thread Richard A. O'Keefe
My original problem was that I wanted to load a particular set of
packages using 'cabal install'.  It didn't work (cabal install issues)
and while the maintainer reacted promptly and helpfully, cabal
kept on trying to install the wrong version.

Part of the problem was that blasting away ~/.cabal and ~/Library/Haskell
wasn't enough:  it's necessary to blast away ~/.ghc as well (which I had
forgotten existed and of course never saw).

* It would be handy if 'uninstall-hs' had an option, say
* uninstall-hs --user
* so that a user could in one step make it as if they had never
* used the Haskell Platform.

(Sigh.  Changes to the GHC command line interface since 7.0 have
broken one of the packages I used to have installed, and the
maintainer's e-mail address doesn't work any more.  And sometimes
it seems as if every time I install anything with cabal something
else breaks.)

PS. Earlier today cabal gave me some confusing messages which
turned out to mean 'GSL isn't installed'.  Non-Haskell dependencies
could be explained a little more clearly.


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


[Haskell-cafe] Haskell Platform 2013.2.0.0 64bit.pkg

2013-06-12 Thread Richard A. O'Keefe
Today I cleared out everything, using uninstall-hs and
rm -rf ~/.cabal ~/Library/Haskell

I downloaded Haskell Platform 2013.2.0.0 64bit.pkg
and installed it.

I was unsuccessful in installing the packages I wanted
using cabal install, which suggested running ghc-pkg check.

So I cleared out everything again and reinstalled the HP.
In the admin account, ghc-pkg check says

Warning: haddock-interfaces:
  /Library/Haskell/ghc-7.6.3/lib/haskell-platform-2013.2.0.0/
  doc/html/haskell-platform.haddock
  doesn't exist or isn't a file
Warning: haddock-html:
  /Library/Haskell/ghc-7.6.3/lib/haskell-platform-2013.2.0.0/
  doc/html
  doesn't exist or isn't a directory



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


Re: [Haskell-cafe] (no subject)

2013-06-10 Thread Richard A. O'Keefe

On 11/06/2013, at 1:58 AM, Alberto G. Corona wrote:

 I have ever wondered how a committee could have made Haskell.

A committee made Algol 60, described as an improvement on most
of its successors.  A committee maintains Scheme.

On the other hand, an individual gave us Perl.
And an individual gave us JavaScript.
And let's face it, an individual gave C++ its big start.


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


Re: [Haskell-cafe] Int is broken [Was: Different answers on different machines]

2013-06-04 Thread Richard A. O'Keefe

On 4/06/2013, at 4:22 PM, Rustom Mody wrote:

 
 
 On Tue, Jun 4, 2013 at 7:35 AM, Richard A. O'Keefe o...@cs.otago.ac.nz 
 wrote:
 
 On 3/06/2013, at 6:58 PM, Carter Schonwald wrote:
  If the Int type had either of these semantics by default, many many 
  performance sensitive libraries would suddenly have substantially less 
  compelling performance.  Every single operation that was branchless before 
  would have a branch *every* operation. this would be BAD.
 
 Actually, the x86 can be configured to trap integer overflows,
 so on that not entirely unpopular platform, there need be NO
 extra branches.
 
 Well yes and no. See http://software.intel.com/en-us/forums/topic/306156

I made a mistake, for which I apologise.
There were two things I wanted the x86 to trap, several years ago,
and I found that one of them *could* be trapped and the other could
not.  The one that couldn't was integer overflow.

I do note that the page cited answers a *different* question
which is does the Intel COMPILER support integer overflow trapping.
The question I answered wrongly was does the Intel HARDWARE support
integer overflow trapping (by raising an exception on integer
overflow if a bit is set in a certain control register).

Having apologised for my error, I close with the observation that
Jacob Navia, developer of lcc-win32 (he started with the LCC compiler
but added serious x86-specific optimisation and other Windows goodness),
claims that sticking JO after signed integer operations adds very little
to run time because it is predicted very well by the branch prediction
hardware, since it is almost never taken.

 In Discipline of Programming (in 1976!) Dijkstra exactly described this 
 problem, and squarely put the blame on poorly engineered machines.
 He introduced 3 concepts/terms:
 UM : unbounded machine
 SLM : sufficiently large machine
 HSLM : hopefully sufficiently large machine

Dijkstra was a Burroughs Research Fellow, and the B6700 was a textbook
example of an HSLM.  I couldn't believe how primitive other systems
were after using that.  The signed-integer-overflow-trapping C compiler
I mentioned was a MIPS one (MIPS distinguishing between ADD and ADDU, c).


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


Re: [Haskell-cafe] Int is broken [Was: Different answers on different machines]

2013-06-03 Thread Richard A. O'Keefe

On 3/06/2013, at 6:58 PM, Carter Schonwald wrote:
 If the Int type had either of these semantics by default, many many 
 performance sensitive libraries would suddenly have substantially less 
 compelling performance.  Every single operation that was branchless before 
 would have a branch *every* operation. this would be BAD. 

Actually, the x86 can be configured to trap integer overflows,
so on that not entirely unpopular platform, there need be NO
extra branches.

Alternatively, and more portably, there could be separate
Int and UnsafeInt types, and the performance sensitive libraries
could be rewritten to use UnsafeInt.

For just one week, I had the joy of using a C compiler where
signed integer overflow was trapped.  It was *wonderful*.


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


Re: [Haskell-cafe] list comprehension doesn't work

2013-05-14 Thread Richard A. O'Keefe

On 15/05/2013, at 2:57 AM, John wrote:

 Hi,
 
 I have to write a function which returns a list of all pairs (x,y) where x,
 y ∈ N AND:
 –  x is the product of two natural numbers (x = a · b, where a, b ∈ N) AND
 –  x is really bigger than 5 but really smaller than 500, AND
 –  y is a squer number (y = c² where c ∈ N) NOT greater than 1000, AND
 –  x is a divisor of y.

Step 1.  If   a = 0 and b = 0  x = a*b  x  500  x  5
 then a  0 and a  500
  and b  0 and b  500.

This suggests something like

xs = [x |
  a - [1..499],
  b - [1..499],
  let x = a*b,
  5  x, x  500
 ]

Step 2.
However, that will generate duplicates.  If a*b = x then b*a = x, and
non-square values of x will be generated twice.
Let's just filter [6..499].
If x is in that range, and a is a number in the range [1..x-1],
and x `mod` a is zero, then x = a*b for some integer b, and b will
_have_ to be in the range you are looking for.

xs = [x |
  x - [6..499],
  or [x `mod` a == 0 | a - [1..x-1]]
 ]

xs has 494 elements.  At first I was surprised to see that 7 was in
the list.  However, if x = 7, a = 7, b = 1, then indeed a and b are
natural numbers and x is there product, so _every_ number in the
range 6..499 qualifies.

Step 3.  If   c = 0 and y = c*c and y = 1000
 then c = 0 and c = 31

This gives us

ys = [c*c | c - [0..31]]

or even

ys = map (^2) [0..31]

which of course has 32 elements.

Step 4.

Now all that's left to test is whether x divides some y:

[(x,y) | x - xs, y - ys, y `mod` x == 0

pairs :: [(Int,Int)]

pairs = [(x,y) | x - xs, y - ys, y `div` x == 0]
  where xs = [x | x - [6..499], or [x `mod` a == 0 | a - [1..x-1]]]
ys = [c*c | c - [0..31]]

This has 641 elements.

If the definition was supposed to be that x is a *composite* number
with factors a, b, then we need to search for a in the range [2..x1].

Using

pairs = [(x,y) | x - xs, y - ys, y `div` x == 0]
  where xs = [x | x - [6..499], or [x `mod` a == 0 | a - [2..x-1]]]
ys = [c*c | c - [0..31]]   --  ^

xs has 402 elements and pairs has 546 elements.

 listPairs :: [(Int, Int)]
 listPairs = [(x,y) | x-[0..], y-[0..], x-[0..]*[0..], x  5, x  500,
 (y*y)  1001, mod y x == 0]
 
 However it doesn't work unfortunatly 
 
 Could anyone tell me where my mistake is?

One mistake is that [0..]*[0..] is a type error.
* wants a pair of numbers, and [0..] is not a number.
(There are modules that make lists numbers, but then
 as*bs is usually the same as zipWith (*) as bs, which
 is not what you want anyway.)

The main mistake is that

[x | x - [0..], x  5, x  500]

is equivalent to

for (x = 0; true; x++) if (x  5  x  500) yield x

That is, the [0..] part is happy to keep on generating
increasing integers, it neither knows, nor does it care,
that there is an x  500 test downstream.

If you really want an infinite set searched, by all means
use [0..].  But if you only want a finite range, put BOTH
bounds in the interval so that it will stop.


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


Re: [Haskell-cafe] Markdown extension for Haddock as a GSoC project

2013-04-29 Thread Richard A. O'Keefe
I should add that as a consumer of Haddock documentation
I can testify that fancier styling (in whatever format)
would be of little benefit to _me_.  What I need is more
plain text and more examples.

To be perfectly honest, most of the time when looking at
a Haddock page, I end up clicking on the Source button
because there are things I need to know that are in the
source but not the documentation.

So I do agree that markup that doesn't get in the way of
a _reader_ who is looking at the source code is an excellent
thing.

I say this as someone who had to read some Java today and
ended up stuffing it through a comment stripper so that I
could easily find what I needed to find.

This thread is not about the visually lightweight aspect of
Markdown.  That's a good thing.  No argument there.

The thread is about how well documented the notation should be.


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


Re: [Haskell-cafe] Markdown extension for Haddock as a GSoC project

2013-04-29 Thread Richard A. O'Keefe

On 29/04/2013, at 10:04 PM, kudah wrote:

 On Mon, 29 Apr 2013 18:04:47 +1200 Richard A. O'Keefe
 o...@cs.otago.ac.nz wrote:
 
 so that there is no possibility of catching errors early;
 by definition in that processor there are no errors.
 
 Haddock's markup isn't any better in that regard.

Did I praise Haddock?

 I spent two hours on
 my first day with haddock figuring out that I needed an empty comment
 line before a code block. It didn't issue any warnings or errors either.

Report that as a bug.

For what it's worth, I've resurrected an old design I did and have
been playing with it to see just how bad it really is to use something
like @iword than _word_.  (Can anyone remember the name of the old
formatting program that the * and _ convention comes from?  I've got a
manual for it buried in a box I can't reach, and I've been trying to
remember the name.  The manual was a UBC technical report some time in
the early 80s, which may mean it was written in BCPL.)
I took a thousand line documentation file and converted it to this
unambiguous markup with a single reserved character, and the size
increase was actually, well, actually, it got @ismaller.

I'm not going to describe the notation, because the point is that
unambiguous and lightweight are compatible properties.


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


Re: [Haskell-cafe] Markdown extension for Haddock as a GSoC project

2013-04-28 Thread Richard A. O'Keefe

On 29/04/2013, at 3:26 AM, Chris Smith wrote:

 I think it's worth backing up here, and remembering the original point
 of the proposal, by thinking about what is and isn't a goal.  I think
 I'd classify things like this:
 
 Goals:
 - Use a lightweight, common, and familiar core syntax for simple formatting.
 - Still allow haddock-specific stuff like links to other symbols.
 
 Non-Goals:
 - Compliance/compatibility with any specification or other system.
 - Have any kind of formal semantics.

Why I find the idea of rejecting semantics appalling:

  Last week I was working with a documentation tool for another language
  which claims to be Markdown and where
*bold* only allows one or more alphabetic words
**bold**   allows any text
_italic_   only allows one or more alphabetic words
__italic__ allows any text
  Today I had to revise some documentation for yet a third language
  which also claims to be Markdown and where
*word*  and _word_   both gave italics
**word* and __word__ both gave bold.

  Oh, and the markup wasn't documented, because it was just Markdown,
  and everyone knows Markdown, right?

The syntax I was using was legal syntax, but the semantics was not the
semantics I expected and was not written down.

I don't care how formal the syntax and semantics are,
but I care very much how complete they are.

 Formal semantics is a non-issue: the behavior will still be defined by
 the implementation, in that people will write their documentation, and
 if it looks wrong, they will fix it.

Sorry, but this is rubbish.  If the semantics is not documented,
then people will write their documentation, and it will look wrong,
AND THEY WILL NEVER HAVE BEEN GIVEN A CLUE ABOUT WHAT TO WRITE INSTEAD.

 We don't want to reason formally
 about the formatting of our comments, or prove that it's correct.
 Avoiding unpleasant surprises is good; but avoiding *all* possible
 ambiguous corner cases in parsing, even when they are less likely than
 typos, is not particularly important.

Hmm.  Just today, again, looking at the revision list for a Markdown
processor, I see comments like
This changes the syntax from all previous versions...
 Code blocks and spans ... will now generate different output...
(which reminds me that the author may not be able to fix the looks
of their documentation because it may have been perfectly fine when
they wrote it, and they may be unavailable when the semantics changes)
Tweaked the rules ... this may affect existing content
(see above)
Sort-of fixed a bug ... Given Markdown's list creation rules,
I'm not sure this *can* be fixed.
(which is the kind of thing that happens when you decide a clear syntax
and semantics are not necessary).

  If some ambiguity becomes a big
 problem, it will get fixed later as a bug.

As the comment extracted above suggests, it may not be fixable.

We may not care about compatibility with other dialects of Markdown,
but we should care about compatibility between versions of Haddock.

Damn!  Why did Watts Humphrey have to die before he'd convinced
the world that the cheapest way to fix bugs is to keep them out
in the first place?


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


Re: [Haskell-cafe] Markdown extension for Haddock as a GSoC project

2013-04-28 Thread Richard A. O'Keefe

On 29/04/2013, at 4:18 PM, Chris Smith wrote:
 
 My point was not anything at all to do with programming.  It was about 
 writing comments, which is fundamentally a communication activity.  That 
 makes a difference.  It's important to keep in mind that the worst possible 
 consequence of getting corner cases wrong here is likely that some 
 documentation will be confusing because the numbering is messed up in an 
 ordered list.

The problem is not what it does to the formatting.

The problem is what it does to *PEOPLE*.

It wastes their time.

Suppose there are 10,000 Haskell programmers (I have no idea what
the true number of Haskell programmers who like to document is; I
hope it's more) and they lose just 6 minutes a day working around
glitches in their documentation tools.  That's 1000 hours a day;
call it 40 days of human life blown away in aggravation every day.

To quote Jayne, Where does that get to be fun?

Why is it acceptable to waste anyone's time with confusing
documentation?

Did anyone else read that Markdown-in-Haskell mentioned here recently
whose author comments (quoting from memory) any random string of garbage
is legal Markdown, so that there is no possibility of catching errors
early; by definition in that processor there are no errors.

 Pointing out that different processors treat markdown differently with 
 respect to bold or italics and such is ultimately missing the point.

It may be missing your point, but it hits mine square in
the bulls-eye.  It wasn't just that they were *different*,
it was that the difference wasn't *documented*, and I had
to waste an hour of my *LIFE* that I will never get back
because some lazy swine couldn't be buggered doing
documentation.

About a documentation tool.

Savour the irony!

 That doesn't mean the choices should not be documented.  Sure they should.

If we agree that the semantics should be documented,
what are we arguing about?

  But it seems ridiculous to sidetrack the proposal to do something nice by 
 concerns about the minutiae of the syntax.

Nobody is suggesting that the proposal should be *CHANGED*.
So talk about sidetrack is unwarranted.
The pathetic request from a suffering humanity is that
the mark(up/down/sideways) should be *DOCUMENTED* clearly.

As for minutiae of the syntax, *you* may call the fact that
`` in the middle of a line and `` at the beginning of a line
do different things minutiae of the syntax, but *I* call it
wantonly squandering my few remaining hours because you think
that no or confusing documentation is OK.

The more I use Markdown, the better HTML looks.
That is, the more effective HTML looks *AS A COMMUNICATION TOOL*,
where effectiveness is measured in terms of the effort required
to get the result you want.

Other people may have other experiences, and that's wonderful.
Having better documentation WILL NOT HURT THEM.





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


Re: [Haskell-cafe] cabal-install 1.16.0.2 on Mac

2013-04-11 Thread Richard A. O'Keefe
The basic problem is that the University has a strict policy
that academic staff must not have root access on any machine
that is connected to the University network.  I was given an
administrator account so that I could resume the printer and
install (some) stuff, but /Developer is owned by root, and I
will be given root access on the Greek Calends.

I would have thought that many organisations would have similar
policies.

On 12/04/2013, at 2:44 AM, Brandon Allbery wrote:
 (Newer Xcode should actually complain and tell you to run the removal script 
 on startup, because its presence can even break Xcode under some 
 circumstances.)

4.6.1 was the latest available in March when I installed it,
and it _didn't_ complain or tell me to run any removal script.


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


[Haskell-cafe] cabal-install 1.16.0.2 on Mac

2013-04-10 Thread Richard A. O'Keefe
Machine:an Intel Core 2 Duo desktop Mac.
OS: Mac OS X 10.7.4
Xcode:  4.6.1 (including command line tools)
Haskell:Haskell Platform 2012.4.0.0 64bit.pkg
downloaded today (GHC 7.4.2)

cabal update advised me to install a new cabal-install.

m% cabal install cabal-install
Resolving dependencies...
Downloading Cabal-1.16.0.3...
[ 1 of 65] Compiling Distribution.Compat.Exception ( 
/var/folders/_n/5bc02hb51d361crtq41g_gc4000g8p/T/Cabal-1.16.0.3-85340/Cabal-1.16.0.3/Distribution/Compat/Exception.hs,
 
/var/folders/_n/5bc02hb51d361crtq41g_gc4000g8p/T/Cabal-1.16.0.3-85340/Cabal-1.16.0.3/dist/setup/Distribution/Compat/Exception.o
 )
 snip 
[52 of 67] Compiling Distribution.Simple.Build.PathsModule ( 
Distribution/Simple/Build/PathsModule.hs, 
dist/build/Distribution/Simple/Build/PathsModule.o )

Distribution/Simple/Build/PathsModule.hs:210:19:
Warning: Pattern match(es) are non-exhaustive
 In a case alternative:
 Patterns not matched:
 PPC
 PPC64
 Sparc
 Arm
 ...
[53 of 67] Compiling Distribution.Simple.GHC ( Distribution/Simple/GHC.hs, 
dist/build/Distribution/Simple/GHC.o )

 snip 
[65 of 65] Compiling Main ( 
/var/folders/_n/5bc02hb51d361crtq41g_gc4000g8p/T/Cabal-1.16.0.3-85340/Cabal-1.16.0.3/Setup.hs,
 
/var/folders/_n/5bc02hb51d361crtq41g_gc4000g8p/T/Cabal-1.16.0.3-85340/Cabal-1.16.0.3/dist/setup/Main.o
 )
Linking 
/var/folders/_n/5bc02hb51d361crtq41g_gc4000g8p/T/Cabal-1.16.0.3-85340/Cabal-1.16.0.3/dist/setup/setup
 ...
Configuring Cabal-1.16.0.3...
Building Cabal-1.16.0.3...
Preprocessing library Cabal-1.16.0.3...
[ 1 of 67] Compiling Paths_Cabal  ( dist/build/autogen/Paths_Cabal.hs, 
dist/build/Paths_Cabal.o )

 snip 

[56 of 65] Compiling Distribution.Client.SetupWrapper ( 
Distribution/Client/SetupWrapper.hs, 
dist/build/cabal/cabal-tmp/Distribution/Client/SetupWrapper.o )

Distribution/Client/SetupWrapper.hs:51:12:
Warning: In the use of `ghcVerbosityOptions'
 (imported from Distribution.Simple.GHC):
 Deprecated: Use the GhcOptions record instead
[57 of 65] Compiling Distribution.Client.Upload ( 
Distribution/Client/Upload.hs, 
dist/build/cabal/cabal-tmp/Distribution/Client/Upload.o )

 snip 

[65 of 65] Compiling Main ( Main.hs, 
dist/build/cabal/cabal-tmp/Main.o )
Linking dist/build/cabal/cabal ...
Installing executable(s) in /home/cshome/o/ok/.cabal/bin
/Developer/usr/bin/strip: object: /home/cshome/o/ok/.cabal/bin/cabal malformed 
object (unknown load command 15)
cabal: Error: some packages failed to install:
cabal-install-1.16.0.2 failed during the final install step. The exception
was:
ExitFailure 1

m% file ~/.cabal/bin/cabal
/home/cshome/o/ok/.cabal/bin/cabal: Mach-O 64-bit executable x86_64

The strip(1) page ends with this, which may be relevant:
LIMITATIONS
   Not every layout of a Mach-O file can be stripped by this program.  But
   all layouts produced by the Apple compiler system can be stripped.

m% otool -l ~/.cabal/bin/cabal
 snip 
Load command 14
 cmd LC_FUNCTION_STARTS
  cmdsize 16
 dataoff  12743064
datasize 204136
Load command 15
  cmd ?(0x0029) Unknown load command
  cmdsize 16
00c58f00  


So something is definitely putting something in there that 
the Xcode 4.6.1 tools do not like.


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


Re: [Haskell-cafe] unsafeInterleaveST (and IO) is really unsafe [was: meaning of referential transparency]

2013-04-10 Thread Richard A. O'Keefe

On 10/04/2013, at 2:45 PM, o...@okmij.org wrote:
... unsafeInterleaveST is really unsafe ...

 import Control.Monad.ST.Lazy (runST)
 import Control.Monad.ST.Lazy.Unsafe (unsafeInterleaveST)
 import Data.STRef.Lazy
 
 bad_ctx :: ((Bool,Bool) - Bool) - Bool
 bad_ctx body = body $ runST (do
   r - newSTRef False
   x - unsafeInterleaveST (writeSTRef r True  return True)
   y - readSTRef r
   return (x,y))
 
 t1 = bad_ctx $ \(x,y) - x == y   -- True
 t2 = bad_ctx $ \(x,y) - y == x   -- False

If I remember correctly, one of the Griswold systems on the
path between SNOBOL and Icon had a special feature for looking
below the language level, called The Window into Hell. 

Derek Lowe has a list of Things I Won't Work With.
http://pipeline.corante.com/archives/things_i_wont_work_with/

unsafeInterleaveST has just joined my Things I Won't Work With list.
But since it is new to me, I don't understand what it does or *how*
it breaks this code.  Does it involve side effects being reordered in
some weird way?

I think there is a big difference between this and lazy I/O.
unsafeInterleaveST *sounds* dangerous.
Lazy I/O *sounds* safe.
And most of the alternatives (like conduits) hurt my head,
so it is really *really* tempting to stay with lazy I/O and
think I'm doing something safe.



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


Re: [Haskell-cafe] cabal-install 1.16.0.2 on Mac

2013-04-10 Thread Richard A. O'Keefe

On 11/04/2013, at 12:56 PM, Brandon Allbery wrote:
 
 Xcode 4.2 and on do not use /Developer at all. You have an older Xcode on 
 your system somehow, which does not understand newer object files; you should 
 remove the entire /Developer tree. (Xcode, in order to be distributable via 
 the App Store, is completely self-contained in /Applications/Xcode.app.)

Unfortunately, I cannot.  I _am_ able to install stuff, but uninstalling
generally gives me problems, and removing /Developer is something I'm not
allowed to do.

However, putting
/Applications/Xcode.app/Contents/Developer/usr/bin
at the front of my $PATH seems to do the job.

Thanks.



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


Re: [Haskell-cafe] Prolog-style patterns

2013-04-08 Thread Richard A. O'Keefe
There is no fundamental problem with non-linear patterns
using ==.  (The functional logic programming world long
ago generalised the idea of unification to 'narrowing'.)

There _is_ a technical problem in Haskell about whether
the == here is necessarily the one from the Prelude or
whether it might be a different == that is in scope:
what would

import Prelude hiding (Eq)
x == y = x  y

member x (x:_ ) = True
member x (_:ys) = member x ys
member _ [] = False

mean?  What, if anything, would it mean when no == is in
scope?

This is something that could be sorted out with good will.
For example, you could say that it is a compile-time error
if this notation is used and Prelude.== is not in scope.
But since guards make the linear pattern restriction less
poctalgic than it is in say ML, people have found other
maddened grizzly bears to stun first.

We had similar questions about n+k patterns, a feature
that I still love.


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


Re: [Haskell-cafe] abs on Float/Doubles

2013-04-07 Thread Richard A. O'Keefe

On 8/04/2013, at 11:21 AM, Levent Erkok wrote:
 It appears that the consensus is that this is a historical definition dating 
 back to the times when IEEE754 itself wasn't quite clear on the topic itself, 
 and so nobody thought that hard about negative zeroes. (The quote is from a 
 comment from Lennart.)

I would expect abs(f) to be identical to copysign(f, 1.0).



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


Re: [Haskell-cafe] Haskell is a declarative language? Let's see how easy it is to declare types of things.

2013-04-04 Thread Richard A. O'Keefe

On 5/04/2013, at 1:22 AM, Tillmann Rendel wrote:

 Hi,
 
 Richard A. O'Keefe wrote:
 As I understand it, in ML, it seemed to be a clever idea to not have type 
 signatures at all.
 
 Wrong.  In ML, it seemed to be a clever idea not to *NEED* type signatures,
 and for local definitions they are very commonly omitted.
 
 In the ML I used, I remember that it was syntactically impossible to use type 
 signatures directly adjacent to a local definition.

Notice that the goal-posts just got moved far far away.
The original complaint was that ML did not allow type signatures.
Now the complaint is that it does not allow them to be
directly adjacent.

 Instead, I was thaught to put something like a type signature in a comment, 
 approximately like this:
 
  (*  getOpt : 'a option * 'a - 'a *)
  fun getOpt (SOME x, y) = x
| getOpt (NONE, y) = y

Well, that's a bit silly, isn't it?
Put getOpt in a structure where it belongs,
and the type in the signature, where the
compiler can enforce it.

A type signature that is not enforced is a type signature
you cannot trust.

 But you can certainly HAVE type signatures, and for modules
 ('structures') it is normal to have them in the interfaces ('signatures').
 
 In my opinion, a signature for a structure would not count as directly 
 adjacent. Also, while I don't know much about the history of ML, I suspect 
 that structures and signatures were a later addition to the core language.

The history of ML is not so hard to find out.
Structures and signatures have been part of Standard ML since the
1980s.  The ML in Edinburgh LCF and Luca Cardelli's VAX ML were
significantly different languages from SML, but VAX ML at least did
have modules.  The distinction between Core and Modules in old
SML documentation has to do with convenience of specification more
than anything else.

 I just checked Milner, Tofte and Harper, The Definition of Standard ML, MIT 
 Press 1990 (available at 
 http://www.itu.dk/people/tofte/publ/1990sml/1990sml.html),

That's the old out-of-date edition.  The current version of the language is
SML'97.  However, this much is the same:

 - there are declarations that provide *interfaces* (grammatical category
   spec -- see page 13), which may occur in signatures
 - and declarations that provide *values* (grammatical category dec --
   see page 8), which may occur in structures, at top level, and elsewhere

So it is definitely true that, by design, SML type signatures (strictly
speaking, valdescs) are segregated from SML function definitions
(valbinds or fvalbinds).

This is pretty much a consequence of SML having a very expressive module
system in which modules _have_ signatures.

 and learned that we can have explicit type annotations for both patterns and 
 expressions, so the following variants of the above are possible in Standard 
 ML:
 
 1. We can embed parts of the signature into the definition:
 
  fun getOpt (SOME (x : 'a), y : 'a) : 'a = x
| getOpt (NONE, y : 'a) : 'a = y

Perhaps better:

fun get_opt (SOME x, _) = x
  | get_opt (NONE,   y) = y

val getOpt : 'a option * 'a - 'a = get_opt

which can be written

local
   fun getOpt(SOME x, _) = x
 | getOpt(NONE,   y) = y
in
   val getOpt: 'a option * 'a - 'a = getOpt
end

 With decomposing the type signature into its parts, and then duplicating 
 these parts, this is not very attractive.

This is a sure sign that you are NOT using the language the way it was intended
to be used, and maybe it isn't the language that's wrong.

 2. We can do better by avoiding the derived form for function bindings:
 
  val getOpt : 'a option * 'a - 'a
= fn (SOME x, y) = x
   | (NONE, y) = y
 
 This looks ok to me, and I wonder why I was not thaught this style,

Because it is atrociously ugly.
(Aside.) val here should be val rec in general. (End Aside).

ML is designed to have type specifications for functions *inside signatures*.
Since functions are supposed to be declared inside structures,
and structures are supposed to *have* signatures,
it would be rather silly to write function type specifications twice.
So ML is *not* designed to encourage you to do that.


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


Re: [Haskell-cafe] GSoC Project Proposal: Markdown support for Haddock

2013-04-04 Thread Richard A. O'Keefe

On 5/04/2013, at 12:34 PM, Johan Tibell wrote:
 
 Markdown has won. Look at all the big programming sites out there,
 from GitHub to StackOverflow, they all use a superset of Markdown.

Yes, but they tend to use _different_ supersets of Markdown.

Would it be too much to ask that a notation be used which has
a formal syntax and a formal semantics?

I mean, this *is* Haskell we're talking about, not some
slapped-together who-cares-if-a-primary-buffer-panel-falls-off
FireflyXXX dynamic programming language.


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


Re: [Haskell-cafe] GSoC Project Proposal: Markdown support for Haddock

2013-04-04 Thread Richard A. O'Keefe

On 5/04/2013, at 2:00 PM, Johan Tibell wrote:

 Would it be too much to ask that a notation be used which has
 a formal syntax and a formal semantics?
 
 We will document our superset, sure. That's what others did as well.
 The point is using Markdown as the shared base.

Nononono.
Sure, the others documented their supersets.
But they did *NOT* provide what I am asking for:
 - a FORMAL SYNTAX and
 - a FORMAL SEMANTICS.
I tried to use one of these systems, and found myself
unable to determine which combinations of features were
legal and what legal combinations of features *meant*.
I corresponded with some people who had built markdown
parsers, and the answer was the same each time: they had
reversed engineered some other parser (typically a Perl
one) and bashed on it until they were bug-compatible.

If I want to get a particular effect in LaTeX or even in
HTML+CSS, I can usually figure it out *without* having to
run any program.  If I want to get a particular effect in
Markdown, I flounder around and end up doing without.

I am sick of documentation that vaguely hints at things,
and I am especially sick of Markdown so-called documentation.

To say it one more time:  I was unable to use the official
Markdown documentation,
http://daringfireball.net/projects/markdown/syntax,
to guide the construction of a parser.

For example, br is a valid URL enclosed in . . ., so
is it a link, as the Automatic Links section would suggest,
or is it embedded HTML, as the Inline HTML section would
suggest?  Can you tell *from the documentation*?

For another example, is *foo**bar**ugh* supposed to map to
emfoostrongbar/strongugh/em or to
emfoo/emembar/ememugh/em?
Again, I'm not asking what does this or that *program* do,
I'm asking can you tell from the documentation what they
*ought* to do?

If there is an unambiguous specification of Markdown somewhere
(specification; not program), I would be glad to see it.



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


Re: [Haskell-cafe] Haskell is a declarative language? Let's see how easy it is to declare types of things.

2013-04-03 Thread Richard A. O'Keefe

On 4/04/2013, at 5:59 AM, Tillmann Rendel wrote:
 As I understand it, in ML, it seemed to be a clever idea to not have type 
 signatures at all.

Wrong.  In ML, it seemed to be a clever idea not to *NEED* type signatures,
and for local definitions they are very commonly omitted.
But you can certainly HAVE type signatures, and for modules
('structures') it is normal to have them in the interfaces ('signatures').

signature SOME_SIG =
   sig
  val f : int - int list - int
  val a : int
   end

structure Some_Struct : SOME_SIG =
   struct
  fun f i [] = i
| f i (x:xs) = f (i+x) xs

  val a = 42
   end

What ML does not have is type *quantifiers*.

For that matter, you could say that ML has one type class: Eq.


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


Re: [Haskell-cafe] A Thought: Backus, FP, and Brute Force Learning

2013-03-25 Thread Richard A. O'Keefe
I should mention that both functional programming in general
and Backus's FP _have_ been influenced by APL, which, while
imperative, strongly encourages algebraic combination of
small functions and had (a fixed set of) higher-order operators.

As for Brute Force Learning by reading imperative code,
I have to say that you _can_ learn a lot that way, but there is
an abundance of imperative code which is utterly opaque.
Come to think if it, I've just taken two days to write 53 lines
of imperative code which requires four more pages to explain
why it exists and why it looks the way it does.  In a functional
language, it would be 2 fairly obvious lines, and I am _not_ kidding.


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


Re: [Haskell-cafe] A Thought: Backus, FP, and Brute Force Learning

2013-03-24 Thread Richard A. O'Keefe
It's Backus, people.  He was never the god of wine.

I cannot detect any trace of Backus's FP in Haskell at all.
FP is strict. Haskell is not.
FP is typeless.  Haskell is highly typeful.
FP does not name formal parameters.  Haskell often does.
FP has roots in APL.  Haskell doesn't.

I don't see any trace of Backus's FP in ML, Clean, or F# either.

The idea of writing programs by composing lots of small
functions is common to them both, but the idea of
combinators preceded them both.

As for
Def Innerproduct = (Insert +) o (ApplyToAll x) o Transpose
the idea is that this ought to be *easier* to understand than
an imperative loop because all of the parts are separated out
instead of being graunched up together.

inner_product :: Num a = ([a],[a]) - a

inner_product = foldr1 (+) . map (uncurry (*)) . uncurry zip

_is_ expressible in Haskell, although

inner_product :: Num a = [a] - [a] - a

inner_product = sum . zipWith (*)

would be more idiomatic.  But this is not because of any influence
from FP, but because Haskell has function composition and higher
order functions.


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


Re: [Haskell-cafe] Specialized Computer Architecture - A Question

2013-03-18 Thread Richard A. O'Keefe

On 19/03/2013, at 9:31 AM, OWP wrote:

 If I may ask, I'm not quite sure what O(2^n) and O(1) are?

Check any data structures and algorithms textbook.

Reverting to the original topic, THIS is the age of specialised
machines.  A lot of the chips out there are not just a CPU but
a SoC (System on a Chip).  Start with the ARM1176JZF-S chip whose
manual I currently have open.
 - sorta kinda RISCish ARM instruction set processor
   + including SIMD DSP/graphics support
 - native hardware execution of (most) Java bytecodes
   (This is ARM's Jazelle extension.)
 - vector floating point co-processor
You can get other chips with ARM cores and a mix of
 - analogue-digital converters, comparators, Flash controllers,
   Ethernet controllers, USB controllers, other interface
   controllers, hardware encryption (especially in ARM v8),
   more kinds of timers than you knew existed, hardware random
   number generation, 
You can even get ARM chips with on-board FPGAs.

Of course SoC systems are not limited to the ARM architecture.
SPARC T4 chips have Crypto Instruction Accelerators … [that] …
enable high speed encryption for over a dozen industry standard
ciphers plus random number generation and high speed 10 GbE
networking directly on … the silicon and two PCI Express controllers.
SPARC systems offered, and still do offer, special hardware support
for dynamic programming languages in which immediate integers have
tag 00 in the bottom 2 bits.  However, when they went 64-bit, they
didn't bother to extend that to 64-minus-2-bit integers.

And of course there are Intel and AMD chips with all sorts of extra
hardware support for all sorts of things.  Notably, people are
integrating GPUs onto the same chip as the CPU.  (Where are the APL
compilers that can take advantage of this?  It's the perfect
APLlication for the language!)

The key point is that cpu designers/vendors take existing workloads
of commercial significance and figure out how to optimise that.  If
a heavy-duty web server, or a high end gaming system, or a mobile
phone, c could clearly benefit from some kind of acceleration,
someone will get it.  If Javascript had a common abstract instruction
set, there'd be hardware acceleration for that.

Haskell programs are not yet a workload of commercial significance.

Sadly.


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


Re: [Haskell-cafe] Overloading

2013-03-12 Thread Richard A. O'Keefe
Carlos Camarao wrote:

 Sorry, I think my sentence: 
To define (+) as an overloaded operator in Haskell, 
  you have to define and use a type class. 
is not quite correct.  I meant that to define any operator in Haskell you have 
to
 have a type class defined with that operator as member. 

No.  Operators and type classes are entirely orthogonal in Haskell.
For example, the list concatenation operator (++) is not defined in
any type class.  It could be.  Either the `mplus` of
MonadPlus or the `mappend` of Monoid would make sense.  But it
happens not to be.

 Yes, but the requirement of using the predefined (+) is an extra
 requirement (I would call (+) in Haskell not a predefined operator,
 but an operator whose type is defined in a class (Num) which is in the
 Prelude). A Haskell programmer can still define versions of (+) where
 the arguments are of two different types and the result is a third
 (he cannot though use the two type classes, and thus neither instances
 of these two type classes, in a program).

I wish we could argue over semantics instead of vocabulary.
By calling the (+) of Num predefined I meant nothing other than
it is _defined_ in the Haskell report before (_pre_) you or I add
any code of our own.  We agree on the facts.

I don't call it an extra requirement.  The original context was
very clearly that in C++ where you have int+int, int+double,
double+int, double+double, char*+int, int+char* and so on all
predefined, you can *also* add your own date+period *without*
hiding the predefined versions.  And _that_ is overloading.  If the
question is whether Haskell can do overloading, _that_ is what has
to be achieved:  you can add a *new* interface date+period *without*
hiding the ones that were already defined before you started coding.

The interesting challenge here is that we should have

Date   + Period - Date  Date   - Period - Date
Period + Date   - Date  Period - Date   - ILLEGAL
Period + Period - DeriodPeriod - Period - Period
Date   + Date   - ILLEGAL   Date   - Date   - Date

and _also_ (remember we are trying to beat C++ here) Int +/- Int - Int.

I suspect that this can be done using type-level programming (so that
Date + Date and Period - Date _begin_ to type check but then violate
a type constraint) but that's where my Haskell skills are most risible.



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


Re: [Haskell-cafe] Overloading

2013-03-11 Thread Richard A. O'Keefe

On 12/03/2013, at 3:15 AM, Carlos Camarao wrote:

 On Sat, Mar 9, 2013 at 5:33 PM, Peter Caspers pcaspers1...@gmail.com wrote:
 
 Hi,
 
 I just started playing around a bit with Haskell, so sorry in
 advance for very basic (and maybe stupid) questions. Coming from
 the C++ world one thing I would like to do is overloading
 operators. For example I want to write (Date 6 6 1973) + (Period 2
 Months) for some self defined types Date and Period. Another
 example would be (Period 1 Years) + (Period 3 Months).
 
 Just defining the operator (+) does not work because it collides
 with Prelude.+. I assume using fully qualified names would work,
 but that is not what I want.
 
 
 Hi. To define (+) as an overloaded operator in Haskell, you have to define
 and use a type class.

Stop right there.  Overloading in the C++ sense is ad hoc polymorphism
where the signatures of the various definitions need not resemble each
other in any way.  Haskell just plain does not have anything like that.
(+) in Haskell is *not* overloaded; it has several implementations and
allows you to define as many more as you want.  But they all conform to
the *SAME* interface.  This is much more like OO inheritance.

In particular, C++ will let you define versions of + where the arguments
are of two different types and the result is a third.  You cannot provide
such an implementation for Haskell's predefined (+).
 
 Furthermore, Haskell supports a more powerful form of overloading than
 (any other language I know, including) C++: context-dependent
 overloading. This means that the type of an expression (f e), and thus
 of f, can be determined at compile-time (inferred) based on the
 context where (f e) occurs, not only on the type of the
 argument (e) of the function's call.

Ada has had this since Ada 81.  The design goal that forced it was
the wish to allow the same identifier to be used as an enumeral in
more than one enumerated type, so that you could do

   type Colour is (Red, Green, Blue);
   type Fruit_State is (Green, Ripe, Rotten);
   X : Colour := Green;
   Y : Fruit_State := Green;

and in particular, since character literals like 'X' are allowed as
enumerals in Ada, they wished to be able to write

A: EBCDIC_Character := 'X';
B: ASCII_Character  := 'X';

and have A and B be different bytes.  The difference is that Ada
*does* do this sort of thing using overload resolution and Haskell
*doesn't*.

 
 For example, you _could_ in principle use (d+p==d) and (d+p==p), 
 with d::Date, p::Period, and instances of (+) with types 
 Date-Period-Date and Date-Period-Period, if you wish…

Prelude :type (+)
(+) :: Num a = a - a - a

The predefined (+) in Haskell requires its arguments and its result
to be precisely the same type.

I think you had better justify the claim that Date+Period - Date and
Date+Period - Period are possible at the same time by showing us
actual code.


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


Re: [Haskell-cafe] Overloading

2013-03-11 Thread Richard A. O'Keefe

On 12/03/2013, at 10:00 AM, MigMit wrote:

 
 On Mar 12, 2013, at 12:44 AM, Richard A. O'Keefe o...@cs.otago.ac.nz 
 wrote:
 
 Prelude :type (+)
 (+) :: Num a = a - a - a
 
 The predefined (+) in Haskell requires its arguments and its result
 to be precisely the same type.
 
 I think you had better justify the claim that Date+Period - Date and
 Date+Period - Period are possible at the same time by showing us
 actual code.
 
 Ehm...
 
 import Prelude hiding (Num)
 class SumDP a where (+) :: Date - Period - a
 instance SumDP Date where date + period = your_implementation_here
 instance SumDP Period where date + period = and_here

Notice the difference?
I said that THE PREDEFINED (+) in Haskell requires its arguments
and its result to be precisely the same type.

This example is not the predefined (+); it's another variable
entirely that happens to have the same short name and cannot
also add integers.



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


Re: [Haskell-cafe] Overloading

2013-03-10 Thread Richard A. O'Keefe

On 11/03/2013, at 12:10 AM, Peter Caspers wrote:

 thanks, this was the core of my question. So by example, if I define a Date 
 type as
 
 data Date = Date Int deriving Show
 
 representing a date by its serial number and want two constructors 
 (conditions are only examples here)
 
 -- smart constructor with serialNumber
 date serialNumber
 | serialNumber  0 = Date serialNumber
 | otherwise = error (invalid serialNumber  ++ show serialNumber)
 
 -- smart constructor with day month year
 date2 day month year
| month = 1  month =12 = undefined
| otherwise = error (invalid month  ++ show month)
 
 there is no way of naming both functions date (instead of date2 above, which 
 compiles), right ?

Right.
 I still think the basic reason is that
 
 date 5
 
 would then either refer to the first constructor (i.e. representing a date 
 with serial number 5) or a partial application of the second
 constructor (i.e. representing a function taking month and year and returning 
 the date 5th month, year).

I am having real trouble understanding why you think this.
Yes, for an *untyped* language, date 27 would not know whether
to return a date or a closure.  But Haskell is *not* an untyped
language.  The one-identifier-one-visible-interface rule is about
making a practical type inference algorithm.

I'm also having some trouble understanding why negative serial
numbers would be illegal.  Dates are a Z-torsor; to convert
integers to dates you have to choose an arbitrary origin.
My Dershowitz-and-Reingold-inspired Smalltalk calendar library
lets you use Julian day number (shifted by 0.5), modified Julian
day number, rata die, and ahargana.  I've been thinking of allowing
a fifth origin: COBOL's 0=31-Dec-1600.  serialNumber is a bad
name because the origin is arbitrary and the name does not reveal
what the origin is.

You can easily write

date :: Either Int (Int Int Int) - Date

date (Left days_since_epoch) = Date days_since_epoch
date (Right (year,month,day))
  | 1 = month  month = 12  1 = day 
day = days_in_month year month
= …
  | otherwise = error (bad date)

Or even set up your own interface type:

import System.Time  -- to get Month; pity Data.Time doesn't offer that.

data Date_Presentation
   = Julian_Day_Number Int
   | Modified_Julian_Day_Number Int
   | Rata_Die Int
   | Ahargana Int
   | Days_Since_COBOL_Epoch Int
   | Gregorian Int Month Int
   | Julian Int Month Int
   | Revised_Julian Int Month Int -- more accurate than Gregorian 

date :: Date_Presentation - Date

date (Julian_Day_Number j) = …
…
date (Revised_Julian y m d) = …

You will notice that this list offers 5 date presentations that
use a single number and three that use two numbers and a month name.
Overloading is no help with that!

 If this is the case, what would be the natural Haskell way of organizing the 
 smart constructors ? Just number them as above ? Or naming them
 dateFromSerialNumber, dateFromDayMonthYear ?

As noted above, there is NO unique serial number for a date
and NO unique day/month/year representation either.

Smalltalk-80 introduced baStudlyCaps namesThatIsNamesWithInternalCapitals
because it was implemented on a machine that used the ASCII 63
left arrow and up arrow instead of the ASCII 67 underscore and caret.
So it used the codepoint we associate with underscore for the assignment
symbol.  In C and C++ and SML and Haskell, we are allowed to use
underscores.  ThereisnoneedtorunyourwordstogetherOrUseInternalCaps.
Nobody_will_shoot_you_for_writing_readably.

You should probably take advantage of the module name and call your
functions
Date.from_julian_day_number :: Int - Date
Date.from_gregorian :: Int - Month - Int - Date

 Or would you do it differently from the start ?

One question is support for different calendars.

I would probably have a My_Date module that just offers
julian day number, modified julian day number, ahagarna,
rata die, and maybe a couple of other epochs.  I would
create nested modules My_Date.Gregorian, My_Date.Julian,
My_Date.Revised_Julian, My_Date.Mayan, and so on, so that
a new calendar could be supported by just plugging in a
new module, not by changing anything.

For something without so many alternatives, I might make a different choice.



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


Re: [Haskell-cafe] performance question

2013-02-14 Thread Richard A. O'Keefe
Just to play devil's advocate:
  100% agreed that there are better things to do in Haskell _source code_ than 
regexps.
  The thing about regexps is that they can be accepted at run time as _data_.
  This means, for example, that they can be put in whatever you use for 
localisation.
  See for example YESEXPR/NOEXPR in langinfo.h


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


[Haskell-cafe] [m..n] question

2008-09-21 Thread Richard A. O'Keefe

Erlang's equivalent of [m..n] is lists:seq(M, N),
which is currently defined to raise an exception when N  M.
In particular, lists:seq(1, N) returns a list of length N
when N  0, but not when N = 0.
I'm currently arguing that lists:seq(1, 0) should be [],
not an exception.  Oddly enough, I'm being beaten over the
head with Haskell, of all things.

In Haskell,
The sequence enumFromTo e1 e3 is the list [e1,e1+1,e1+2,...e3].
 The list is empty if e1  e3.

It is being claimed that the reason for this is that exceptions
are problematic in Hasell, so the Haskell designers went out of
their way to make this function total whether it made sense or not.

I am currently suggesting that it's to keep the specification
(for integers) simple:
[m..n] is the set of integers x such that m=x=n,
 listed in ascending order.
There's also the nice equivalence between
[m..n] and takeWhile (= n) [m..].
Unfortunately, no such abstract characterisation of [m..n] is
mentioned in the report, and the takeWhile connection is
inferred from numericEnumFromTo.

Does anyone remember why the definition of enumFromTo is the way it is?

--
If stupidity were a crime, who'd 'scape hanging?







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


Re: [Haskell-cafe] Re: Float instance of 'read'

2008-09-17 Thread Richard A. O'Keefe


On 18 Sep 2008, at 3:20 am, Mauricio wrote:

Agree about the answer, not about the question. The
correct one would be is it possible to change haskell
syntax to support the international notation (not any
locally sensitive one) for decimal real numbers? Would
a change in 'read' be a good first step?


For some sense of possible, the answer is clearly yes.
However, it is perhaps misleading to call commas
THE international notation.  The plain fact of the
matter is that whatever any standards body may say,
there are MANY notations for numbers.  You might as
well ask is it possible to change Haskell syntax to
support only the *real* Arabic digits ... for ...
numbers.  The Arabic script is used in many countries,
so it's international.  I don't read Arabic letters at
all, but to me numbers written in Arabic script are no
weirder than numbers using commas instead of dots.

I would draw readers' attention to
http://engineers.ihs.com/news/2006/nist-decimal-international.htm
which says that
(1) China, India, and Japan use decimal points, not commas.
(2) There was a resolution of the CGPM in 2003
endorsing the use of the point on the line as a decimal sign.
(3) In June 2006, ISO agreed to allow the use of dots as decimal
points in international standards.

As it happens, the decimal point character I greatly prefer is
the traditional British raised dot, but I can live with a low dot.

I am 100% behind internationalised input and output,
but allowing commas in numbers inside programming languages
that already use commas for other purposes is, let's be polite,
not a terribly good idea.  You could probably get away with it
in Lisp, but how many numbers are there in (1,2,3)?

One thing that definitely is missing from Haskell numbers, and
which I greatly miss, is a thousands separator.  Ada got around
the dot/comma/apostrophe/whatever issue for thousands separators
by using the underscore.  For an unsigned decimal integer,
this means allowing [0-9](_?[0-9])* instead of [0-9]+.  It works
really well, despite not being ANYBODY's cultural convention.




I know this looks difficult, but I'm sure it deserves at
least some thinking. We have previous examples for
less important issues: ghc does accept Windows end
of line conventions, the minus and sign needs special
syntax, and '.' can be used as decimal separator even
if it's use as function notation.

Best,
Maurício

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




   Auto Generated Mail  
Footer If this email is requesting your  
password then it is a HOAX.

   DO NOT reply to the email.
  Validate this footer at the
Otago University web site keyword search: information security phish






--
If stupidity were a crime, who'd 'scape hanging?







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


Re: [Haskell-cafe] Re: Python's big challenges, Haskell's big advantages?

2008-09-17 Thread Richard A. O'Keefe

It may be of interest that although Erlang has been doing
lightweight concurrency for 20 years,
 - you can choose whether you want to use an SMP version that
   has as many schedulers as there are cores (plus internal
   locking as needed) or a non-SMP version with one scheduler
   (and no internal locking); both versions are standard and
   it's only a performance issue, not a semantics issue
 - performance sometimes goes one way, sometimes the other
 - there was a one UNIX process per Erlang process
   implementation; I have a copy.  The community interest in
   it was, shall we say, massively underwhelming.

It might also be interesting to note that the experimental
operating system K42 from IBM does _all_ user-visible
threading in user-land.  This includes thread switching and
even I/O blocking and unblocking; all done in user-land.

I don't think we've begun to explore all the options yet.

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


Re: [Haskell-cafe] ask

2008-09-14 Thread Richard A. O'Keefe


On 15 Sep 2008, at 12:51 pm, Daniel Fischer wrote:


Am Montag, 15. September 2008 02:24 schrieb Cetin Sert:

Hi why do I get?


Buffering. For compiled programmes, stdin and stdout are line- 
buffered by

default, so the output doesn't appear until the program finishes.
Either put
hSetBuffering stdout NoBuffering
at the top of main or, better IMO,
insert a
hFlush stdout
into ask before the readLn.
And in eval, putStrLn would be better, I think.


Is this the problem we've had before, where the example in the
Haskell 98 Report could not possibly work unless Haskell followed
the same rule as C (read from stdin *automatically* flushes stdout),
and the example works in several other Haskell systems, but not in
GHC?  Or is this a different problem?

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


Re: [Haskell-cafe] Re: Field names

2008-09-10 Thread Richard A. O'Keefe


On 11 Sep 2008, at 3:54 am, Brandon S. Allbery KF8NH wrote:
I think that only counts as the origin of the idea; isn't :-prefixed  
infix constructors a ghc-ism?


Haskell 98 report, page 10:
An operator symbol starting with a colon is a constructor.

(I seem to have four copies of the report on my Mac...)




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


Re: [Haskell-cafe] Can you do everything without shared-memory concurrency?

2008-09-08 Thread Richard A. O'Keefe

I think the demonstration is in Hoare's book on co-operating
sequential processes, but if you have pure processes and
message passing, you can simulate conventional variables.
Here's an Erlang version:

variable_loop(State) -
receive
{ask,Sender} - Sender!{self(),State}, variable_loop(State)
  ; {tell,New_State} - variable_loop(New_State)
end.

new_variable(Initial_State) -
spawn(fun () - variable_loop(Initial_State) end).

fetch(Variable) -
Variable!{ask,self()},
receive {Variable,State} - State end.

store(Variable, New_State) -
Variable!{tell,New_State}.

new_array(Size, Initial_State) -
list_to_tuple([new_variable(Initial_State)
  || Dummy - lists:seq(1, Size)]).

fetch(Array, Index) -
fetch(element(Index, Array)).

store(Array, Index, New_State) -
store(element(Index, Array), New_State).

The simulation of (shared) mutable variables and arrays in pure
CSP is very similar.  This pretty much _has_ to be possible in
any language that has concurrent processes that can communicate
in some fashion.  There are also quite elementary ways to
simulate locking.  So we can solve any concurrent problem that,
say, C++ with Intel's TBB library, or Java with java.util.concurrent,
or any other such language can solve.  We can even get ourselves
just as far into extremely serious trouble as we can using those
languages, it's just that we don't _have_ to.

--
If stupidity were a crime, who'd 'scape hanging?







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


Re: [Haskell-cafe] Can you do everything without shared-memory concurrency?

2008-09-08 Thread Richard A. O'Keefe


On 9 Sep 2008, at 8:15 am, Kyle Consalus wrote:


Anyway, for the time being I believe there are operations that can be
done with shared memory
that can't be done with message passing if we make good performance
a requirement.


One of our people here has been working on Distributed Shared Memory
for some years.  It's a programming model where you write AS IF you
had shared memory, but you really don't.  He actually uses plain C
with a library, but I've got a student project to wrap some syntax
around that.

typedef struct Foo { ... variables ... } Foo;
typedef struct Bar { ... variables ... } Bar;
shared Foo foo;
shared Bar bar;

shared (const *f = foo) {
... here we have read access to f-variables ...
}
shared (*b = bar) {
... here we have read-write access to b-variables ...
}

Underneath, it's message passing.  When you get a view on a
shared region, a copy is fetched from the cheapest source that has
a current copy.  When you release a write view, you become the
holder of the only current copy.  Compressed differences are
sent around the local net.  Zhiyi Huang's library is called VODCA.
There's a plug-compatible version developed by his colleagues in
China called Maotai, so the _same_ code can be run on a multicore
system or on a network of workstations.  The trick is to choose the
chunk size of your problem so that computation and communication
costs are in the right balance.  This certainly seems to be adequate
for numerical software, raytracing, game playing, ...

One issue is that real shared memory comes at a price that most
people don't know they are paying.  We wouldn't need MOESI
protocols or the related bus traffic if there were known to be
no sharing, and one of the things that gets in the way of
massive multicore is keeping caches coherent.  No shared memory
= no coherence problem = no extra bus traffic = faster.

--
If stupidity were a crime, who'd 'scape hanging?







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


Re: [Haskell-cafe] Pure hashtable library

2008-08-28 Thread Richard A. O'Keefe


On 28 Aug 2008, at 9:07 pm, Jules Bean wrote:
Insert for Data.Sequence is log(i) where i is the position of the  
insertion; clearly bounded by log(n). toList is O(n) and index is  
(at worst) log(i).


I think the corresponding operations with tries are log(n),


Let the key you want to insert have length L.
Then insertion into a trie is O(L), independent of the size of the  
collection.

If the alphabet the key's elements are drawn from is large,
you can use a Ternary Search Tree, and insertion is
then O(L.lg B) where B is the branching factor.
There are fast Trie construction algorithms which are linear
in the total size of the collection, \sum_{i=1}^{n}L_i.

The worst case for Data.Sequence is where keys mostly vary at
the end, in which case comparisons take O(L) time, and the
cost is O(L.lg n), where n is usually much bigger than B.


So, it's all in the constants, isn't it?


No.


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


Re: [Haskell-cafe] Pure hashtable library

2008-08-27 Thread Richard A. O'Keefe

Someone wrote:


trie: O(len)*O(width)
hashed trie: O(len)
hash: O(len)


If width here refers to the branching factor of the trie,
it's actually O(len.lg(width)), and the width that matters
is not the *possible* number of choices but the *actual*
number.

The great problem with hash tables is devising good hash
functions.  There is a vast literature about hash tables,
but there is very little about how to design good hash
functions for anything other than numbers and maybe strings.
It would be nice to think that _had__ there been plenty of
good advice about constructing good hash functions the Java
library implementors would have taken it.  As it is, their
hashing functions for collections leave much to be desired.

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


Re: [Haskell-cafe] Haskell Propeganda

2008-08-27 Thread Richard A. O'Keefe


On 28 Aug 2008, at 8:34 am, Aaron Tomb wrote:
What type safety buys you, in my mind, is that Nothing is only a  
valid value for explicit Maybe types. In cases where you don't use  
Maybe, the null situation just can't occur. In languages with null  
pointers, any pointer could possibly be null.


This is not true of Eiffel.
The ECMA Eiffel standard has
?T  either a void reference or a reference to an instance of T
!T  a reference to an instance of T
 T  same as !T in ECMA Eiffel; used to be same as ?T

I suppose you could call the detachable type ?T an *implicit* Maybe.
Needless to say, the switch in semantics of undecorated T helped to
fork the Eiffel community...


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


Re: [Haskell-cafe] Valid Haskell characters

2008-08-25 Thread Richard A. O'Keefe


On 26 Aug 2008, at 1:31 pm, Deborah Goldsmith wrote:

You can't determine Unicode character properties by analyzing the  
names of the characters.


However, the OP *does* have a copy of the UnicodeData...txt file,
and you *can* determine the relevant Unicode character properties from  
that.


For example, consider the entry for space:
0020;SPACE;Zs;0;WS;N;
   ^^
The Zs bit says it's a white space character
(Zs: separator/space, Zl: separator/line, Zp:
separator/paragraph).

Or look at capital A:
0041;LATIN CAPITAL LETTER A;Lu;0;L;N0061;^
^^
The Lu bit says it's a L(etter) that is u(pper case).

Upper case: Lu, lower case: Ll, title case: Lt,
modifier letter: Lm, other letter: Lo, digit: Nd,
...

If memory serves me correctly, this is explained in the
UnicodeData.html file, under a heading something like
Normative Categories.


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


Re: [Haskell-cafe] Valid Haskell characters

2008-08-25 Thread Richard A. O'Keefe


On 26 Aug 2008, at 3:42 pm, Deborah Goldsmith wrote:

All characters with general category Lu have the property Uppercase,  
but the converse is not true.


It depends on what the OP wants to do with the information.
For example, Unicode Standard Annex 31,
http://www.unicode.org/reports/tr31/tr31-9.html
is defined in terms of the General Character classification,
*not* in terms of the binary properties Upper, Alpha, c.

When the Haskell report says
uniSmall - any Unicode lowercase letter
uniLarge - any uppercase or titlecase Unicode letter
it is really unclear what definition is meant: are we talking
about characters in general category Lu or Lt, or are we
talking about characters with the Uppercase property?
Since it's _identifiers_, I'd expect UAX#31 to apply, so it
should be general category.

The specification of the Char module is similarly ambiguous.
Since this is *not* about identifiers, I suppose this time
the Other_Uppercase characters might well be included.

It would be nice to have this spelled out clearly somewhere
not too far from the Report on haskell.org.



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


Re: [Haskell-cafe] lines of code metrics

2008-08-20 Thread Richard A. O'Keefe

Speaking of GdH, the web page
http://www.macs.hw.ac.uk/~dsg/gdh/
was last updated in June 2007, it says,
but the binary snapshot (Linux only) is February 2002,
and the installing GdH part says it's built using
the GHC 5.00 sources.

Is GdH dead, or is there a more up to date version
lurking somewhere else?

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


Re: [Haskell-cafe] Reader monad, implicit parameters, or something else altogether?

2008-08-18 Thread Richard A. O'Keefe

Just an idiot-level question: so these constants are subject
to revision, but *how often*?  What is the actual cost of
recompiling and using them *as* constants, compared with the
cost of rereading the stuff every time you run the program and
passing it around?

--
If stupidity were a crime, who'd 'scape hanging?







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


Re: [Haskell-cafe] whatever happened to sendFile?

2008-08-15 Thread Richard A. O'Keefe


On 15 Aug 2008, at 12:17 pm, Brandon S. Allbery KF8NH wrote:
Actually, while I'm not sure how Linux does it, on the *BSDs pipes  
are actually socketpairs.


This raises the question, which the documentation did not make clear  
to me,

whether a named pipe is a pipe.  One would hope it was, but
S_IFIFO and S_IFSOCK are different...

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


Re: [Haskell-cafe] Re: whatever happened to sendFile?

2008-08-14 Thread Richard A. O'Keefe


On 14 Aug 2008, at 10:47 am, John Meacham wrote:

There isn't a standard unix sendfile, while a few different ones have
functions called 'sendfile', they have different meanings/prototypes  
in

general.


For example, I'm typing this on an Intel Mac running Mac OS 10.5.4,
and 'man sendfile' shows
 sendfile -- send a file to a socket
and claims that it is checked runtime error if the destination is
anything but a socket.

It looks as though file - socket is the only moderately portable
case, and of course systems without can fake it by a sequence of
reads and writes.

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


Re: [Haskell-cafe] whatever happened to sendFile?

2008-08-14 Thread Richard A. O'Keefe

On 14 Aug 2008, at 6:28 pm, Ketil Malde wrote:

Isn't [sendfile()] superseeded by splice(2) nowadays?


Solaris 10:
 f% man splice
 No manual entry for splice
Mac OS X 10.5.4
 m% man splice
 No manual entry for splice
Linux 2.6.23...
 o% man splice
 ..
 one of the descriptors MUST refer to a pipe.

So of the three tolerably current UNIX systems available
to me, two of them don't have it, and the third seems to be
saying you cannot use it to move data from a file (which is
not a pipe) to a socket (which is not a pipe), which is the
use-case for sendfile().






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


Re: [Haskell-cafe] ANNOUNCE: Sun Microsystems and Haskell.org joint project on OpenSPARC

2008-07-24 Thread Richard A. O'Keefe


On 25 Jul 2008, at 10:55 am, Duncan Coutts wrote:

The problem of course is recursion and deeply nested call stacks which
don't make good use of register windows because they keep having to
interrupt to spill them to the save area.


A fair bit of thought was put into SPARC V9 to making saving and  
restoring
register windows a lot cheaper than it used to be.  (And the Sun C  
compiler

learned how to do TRO.)

It's nice to have 3 windows:
 C worldstartup
 Haskell world  normal Haskell code
 millicode  special support code
so that normal code doesn't have to leave registers spare for millicode
routines.


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


Re: [Haskell-cafe] ANNOUNCE: Sun Microsystems and Haskell.org joint project on OpenSPARC

2008-07-23 Thread Richard A. O'Keefe

On 24 Jul 2008, at 3:52 am, Duncan Coutts wrote:
[Sun have donated a T5120 server + USD10k to develop
 support for Haskell on the SPARC.]

This is wonderful news.

I have a 500MHz UltraSPARC II on my desktop running Solaris 2.10.
Some time ago I tried to install GHC 6.6.1 on it, but ended up
with something that compiles to C ok, but then invokes some C
compiler with option -fwrapv, which no compiler on that machine
accepts, certainly none that was present when I installed it.

I would really love to be able to use GHC on that machine.

I also have an account on a T1 server, but the research group
who Sun gave it to chose to run Linux on it, of all things.

So binary distributions for SPARC/Solaris and SPARC/Linux would
be very very nice things for this new project to deliver early.
(Or some kind of source distribution that doesn't need a working
GHC to start with.)


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


Re: [Haskell-cafe] Data.Complex.magnitude slow?

2008-07-20 Thread Richard A. O'Keefe

On Fri, 18 Jul 2008, stefan kersten wrote:


On 17.07.2008, at 21:46, Lennart Augustsson wrote:
If scaleFloat and exponent are implemented with bit twiddling  
they can

be quite fast.


is there a way in ghc to 'cast' between float/int32 and double/ 
int64 (without going through memory)?


I read this as

	Is there any way to take a 32-bit float in a register and end up  
with a 32-bit int

 in a register, without going through memory, in GHC?
 How about the other way around?
 How about 64-bit floats and integers?

It is rather hard to do portably in GHC what some hardware does not do.
A long time ago hardware architects decided that separating the  
integer and

floating point register files was a Good Thing.
The machine I know best is SPARC, where there are no instructions to  
move

data directly between integer registers and floating point registers.

On the other hand, there are other pressures, notably graphics.
While integer and floating point registers may be kept separate, there  
are often
vector instructions that let you operate on integers in the floating- 
point
registers.  (Such as the VIS instructions on SPARCs, which are  
technically
optional.)  Exploiting such instructions tends to be rather non- 
portable.


All things considered, I wouldn't worry about it too much:  the memory  
in
question should be at the top of the stack, so should be in L1 cache,  
so should

be pretty fast to access, and other things may be more significant.

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


Re: [Haskell-cafe] carry state around ....

2008-07-20 Thread Richard A. O'Keefe

I think it may be time for a little clarity about aoicb's.
From the Single Unix Specification:
 The aio.h header shall define the aiocb structure
  which shall include AT LEAST the following members:
int aio_fildes File descriptor.
off_t   aio_offset File offset.
volatile void  *aio_bufLocation of buffer.
size_t  aio_nbytes Length of transfer.
int aio_reqprioRequest priority offset.struct  
sigevent aio_sigevent   Signal number and value.

int aio_lio_opcode Operation to be performed.
 
The AT LEAST here means that
 - a portable program may rely on these members being present
 - a portable program MUST assume that an unknown number of
   additional members are also present
 - a portable program may freely copy such a record, but may
   only pass it to a library function if that function is
   expecting to initialise it

For asynchronous I/O, this means that
 - you can allocate an aiocb object
 - an aiocb passed to aio_suspend, aio_error,
   aio_return, or aio_cancel should have been
   filled in by aio_read or aio_write and should
   be EXACTLY THE SAME object, not a copy of it.


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


Re: [Haskell-cafe] Haskell, Microsoft, and interview questions

2008-06-26 Thread Richard A. O'Keefe


On 27 Jun 2008, at 3:11 am, Andrew Wagner wrote:
For what it's worth, a 3-dimensional kd tree really flew on this  
problem.



I did some reading up on this, and it seems interesting. It would be
need to implement something like this in Haskell, but I can't seem to
find any detailed specs on the data-structure. Got any
recommendations?


http://en.wikipedia.org/wiki/K-d_tree
is perhaps the obvious place to start.
There's a link there to Jon L. Bentley's original (1975) paper,
which is really very clear.  The key to getting an efficient
version in C was to specialise the code to the particular k that
I wanted (k=3).

Of course there are much newer data structures that can do all sorts
of things, but for simply finding the closest point in 1, 2, 3, or
4-dimensional space k-d trees are darned good.  There isn't much that
works well for high dimensions.  Last year I marked a 4th year project
that studied/evaluated a comparatively recent data structure that was
said to be good for high dimensions.  I had difficulty understanding
it, because I couldn't see where the recursive step was.  The answer
was that there wasn't one:  the algorithm worked better for high
dimensions than other trees because it turned into a simple linear
search after one partitioning step.  In effect, it was too dumb to
keep tripping over its own feet.  So _really_ don't expect k-d trees
to work well for large k.









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


Re: [Haskell-cafe] Haskell, Microsoft, and interview questions

2008-06-26 Thread Richard A. O'Keefe


On 27 Jun 2008, at 11:36 am, Adam Langley wrote:

Specialised for 2d only, but:

http://www.imperialviolet.org/binary/NearestNeighbour2D.hs


In my C code for this, specialised to 3D,
 - dimension numbers were never stored
 - no arrays were used
 - the search in x function called
   the search in y function, which called
   the search in z function, which called
   the search in x function

Here's the relevant part of my kd3.h:

typedef struct KD3_Node *kd3ptr;
struct KD3_Node {
double x, y, z;
kd3ptr left, right;
bool   present;
  payload data goes here 
};


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


Re: [Haskell-cafe] Haskell, Microsoft, and interview questions

2008-06-25 Thread Richard A. O'Keefe


On 26 Jun 2008, at 8:14 am, Andrew Wagner wrote:

6.) You have a [(WeatherStationId, Latitude, Longitude)]. Similar to
#3, write a function which will, off-line, turn this into a data
structure from which you can easily determine the nearest Weather
Station, given an arbitrary Latitude and Longitude.


I actually set something not entirely unlike this as a problem in
a 4th year OO class.  Despite telling them over and over and over
again that the Earth is not flat, and despite telling them how to
convert (Latitude, Longitude) to 3-dimensional coordinates on the
unit sphere, and despite telling them that greatest circle distance
between two points on the surface of the Earth is a monotone
function of Euclidean distance between points on the unit sphere,
so that all they had to do was to glue these pieces together,

EVERY SINGLE ONE used Euclidean distance between (Latitude,
Longitude) pairs as if they were co-ordinates on a flat 2-d plane.
And we even live near the International Date Line, which is where
this mistake goes horribly wrong.

Did they score you on coding or on geometry?

For what it's worth, a 3-dimensional kd tree really flew on this  
problem.





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


Re: [Haskell-cafe] Help with generalizing function

2008-06-23 Thread Richard A. O'Keefe


On 23 Jun 2008, at 6:30 pm, leledumbo wrote:
I've successfully create a function to return lists of N-ple that  
satisfy the

following function:
x1 + x2 + x3 + ... + xN = C
But unfortunately, it's not generic.


Why do you want it to be a tuple?  All the elements are the same type,  
so it

might as well be a list.

part 0 c | c == 0 = [[]]
part (n+1) c | c = 0 = [(x:xs) | x - [0..c],
  xs - part n (c-x)]

(WARNING: UNTESTED CODE!)
Knuth TAOCP Volume 4 has some stuff on enumerating partitions.

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


Re: [Haskell-cafe] Lambda and closures in PHP -- could someone please comment?

2008-06-22 Thread Richard A. O'Keefe

This is increasingly less relevant to Haskell, except
of course to demonstrate what a nice language Haskell is.
On 20 Jun 2008, at 11:34 pm, Jules Bean wrote:
I think where I differ on you is how to map the semantics of a C- 
like language to explicit references.


I would argue that the glyph c in a C-like language denotes the  
value of C, not the reference to it. C-like languages have, for the  
most part, value semantics, and call-by-value.


The exception of course is what C-like languages called lvalues,  
but lvalues are only really on the left of the = sign and a few  
other special positions. I think that's the exception and not the  
rule.


No, this is back to front.  C basically follows the Algol 68 idea that
the lvalue is the normative thing, and that there is an IMPLICIT  
COERCION

from a variable to its value in certain contexts.  C is full of implicit
coercions: perhaps the most famous is the one that says that in almost  
all

contexts an array is quietly coerced to a pointer to its first element.

The key observation is that an implicit coercion from a variable to its
contents is possible, whereas an implicit coercion from a value to the
variable that holds it is not.   Only the a variable really stands for
its address view is coherent.

In C, of course, if you want to capture the reference you do it  
explicitly with c.


If we can use evidence from a relative to probe such questions,
the fact that you *don't* need an explicit  in C++ (when you find a  
'reference'
to a variable, you use c, not c) strongly suggests that the  
variable stands

for location view is the more useful one.

Thankfully, Haskell saves us these perplexities.
(And replaces them with other perplexities...)

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


Re: [Haskell-cafe] Lambda and closures in PHP -- could someone please comment?

2008-06-19 Thread Richard A. O'Keefe


On 19 Jun 2008, at 5:53 pm, Jules Bean wrote:


Richard A. O'Keefe wrote:


- what you get is a reference to a variable (as you do in Scheme)
 but loop variables really are variables, not names for values,
 so lambdas created in different iterations of the same loop point
 so the same loop variable, and do not remember the value it had
 when they were created.  The proposal explains how to work around  
this.


This one trips everyone up in Javascript.


What's going on here is a nasty interaction with the semantics of loops.
In Smalltalk and Scheme (to name two languages with closures and
mutable variables), each iteration of a loop in principle creates a new
variable binding.  Scheme example:
(do ((i 0 (+ i 1))
 (l '() (cons (lambda (x) (* x i)) l)))
((= i 10) l))
is equivalent to
let f i l = if i = 10 then l
else f (i + 1) ((\x - x * i) : l)
in f 0 []
except for i and l being potentially mutable in Scheme but not Haskell.
The Smalltalk equivalent would be
(0 to: 9) collect: [:i | [:x | x*i]]
in which (a) each iteration creates a *new* i, and (b) method and
block parameters are *not* mutable, because they never are in Smalltalk.

Importing only values into closures would not work for Smalltalk.
Consider the usual implementation of Smalltalk's equivalent of 'fold:

Collection
inject: initial into: function
  |r|
  r := initial.
  self do: [:each | r := function value: r value: each].
  ^r

The mutablity of r here really isn't a problem.  Nor is the mutability
of variables _as such_ really the problem in the PHP proposal.
The problem is that it's the *same* variable every time.  If PHP
loops introduced new bindings on every iteration, this particular
problem would not exist.






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


Re: [Haskell-cafe] Lambda and closures in PHP -- could someone please comment?

2008-06-18 Thread Richard A. O'Keefe

I believe C# already has lambdas, and Java is supposed to be getting
them.  PHP is playing catchup, is all.  (Oh, and Eiffel has 'agents',
and I think I saw something about C++ Next Degeneration, and ...)
Heck, the idea has only been around in computing since the 1950s...


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


Re: [Haskell-cafe] Lambda and closures in PHP -- could someone please comment?

2008-06-18 Thread Richard A. O'Keefe


On 18 Jun 2008, at 4:36 pm, Karoly Negyesi wrote:
(a) I would *never* want to use an implementation of closures like  
that.

Could you elaborate on a) ?


It wasn't me who wrote it, but consider
- non-local variables are *not* captured unless you explicitly
  hoist them into the lambda expression using the 'lexical' keyword.
- references to non-local variables that are not so hoisted are
  not syntax errors, they just quietly do something else.
- ordinary functions do not act as if defined by lambda expressions;
  'lexical' is required in lambdas and forbidden in functions.
- ordinary functions do not act as if defined by lambda expressions;
  the latter can outlive their lexical scope, the former can't.
- what you get is a reference to a variable (as you do in Scheme)
  but loop variables really are variables, not names for values,
  so lambdas created in different iterations of the same loop point
  so the same loop variable, and do not remember the value it had
  when they were created.  The proposal explains how to work around  
this.


All of this boils down to something in which you *can* with care do
the things you expect to do with closures, but the language gently
leads you to the edge of the Pit and the compiler just smiles quietly
as you fall over.






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


Re: [Haskell-cafe] blas bindings, why are they so much slower the C?

2008-06-18 Thread Richard A. O'Keefe


On 19 Jun 2008, at 4:16 am, Anatoly Yakovenko wrote:

C doesn't work like that :).  functions always get called.


Not true.  A C compiler must produce the same *effect* as if
the function had been called, but if by some means the compiler
knows that the function has no effect, it is entitled to skip
the call.  In particular, the C compiler I normally use offers
these pragmas, amongst others:

#pragma does_not_write_global_data (funcname [, funcname])
#pragma no_side_effect(funcname[, funcname])

So with a declaration like

extern double cblas_ddot(
int,
double const *, int,
double const *, int);
#pragma no_side_effect (cblas_ddot)



the compiler would be completely within its rights to discard
any call to cblas_ddot() whose result was not used.  (As it
happens, it didn't, but it would have been allowed to.)
If using gcc,

extern double cblas_ddot( ... as before ...)
__attribute__ ((const));

seems to have the same effect, certainly the test case I tried
did in fact completely eliminate a call to cblas_ddot() when
so declared.

Since the malloc() results pointed to uninitialised memory,
the C compiler was entitled to do anything it pleased anyway.

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


Re: [Haskell-cafe] 1/0

2008-06-16 Thread Richard A. O'Keefe


On 17 Jun 2008, at 11:07 am, Evan Laforge wrote:


So, I know this has been discussed before, but:


1/0

Infinity

0/0

NaN

... so I see from the archives that Infinity is mandated by ieee754
even though my intuition says both should be NaN.


Other people have other intuitions.  It may be that your intuition
is telling you that neither result should be an ordinary number,
and if that's what it's really telling you, it's right: the C
function isfinite(x) is true of all signed zero, subnormal, or
normal x, false of signed infinities and NaNs.

 Every other language throws an exception, even C will crash the

program,


Not true.  C99 *definitely* allows both infinities and NaNs (see
Annex F of the C99 standard) and C89 practice also allowed it.
Some C89 systems required you to use signal() with SIGFPE to
turn IEEE extended results into exceptions; others required you
to use signal() to disable this; others used yet other means.

The Scheme systems I tried turn (/ 1.0 0.0) into a printed
representation of IEEE infinity.  Of the Prolog systems I checked,
some did and some didn't.  The Standard ML system I tried gave
inf as the response to 1.0/0.0.

Basically, with any programming language implementation that
truthfully claims conformance to IEEE 754 or a successor standard,
x/0 MUST NOT crash unless your program explicitly asks for such
behaviour.  As for programming language implementations that do
not make such a claim, who knows what they will do?

Since integers do not have the special IEEE values, conversion
of IEEE values to integral values really ought to be checked.
(Of course, in C what you typically get is garbage, but that can
be put more generally...)


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


Re: [Haskell-cafe] 1/0

2008-06-16 Thread Richard A. O'Keefe

Since Haskell-Café often strays into mathematics,
this may not be too far off topic.

On 17 Jun 2008, at 2:29 pm, Evan Laforge wrote:

Yeah, on reflection, I think my intuition derives from me asking a
math teacher back in high school isn't n/0 infinity? after looking
at a graph, to which he said no, it's undefined, you can only say it
approaches infinity in the limit, but it isn't infinity.


Let's put this kindly:  it is POSSIBLE that your maths teacher knew
what he was talking about and was just telling what the Science of
Discworld authors call lies-to-children.  It is certainly likely
that it didn't occur to him that you might transfer what he said
about the mathematical real numbers to a rather different algebraic
system, IEEE floats.

The usual real numbers R form an ordered field.
*In that structure*, n/0 is undefined.
But there is another algebraic structure which includes all
the real numbers plus one more: infinity.
It's call the real projective line.
See http://en.wikipedia.org/wiki/Real_projective_line
In that structure, n/0 is perfectly well defined, and is indeed
infinity.  That structure has all the properties you really need
to do calculus, but isn't a field and isn't ordered.  However,
whenever an operation on elements of R is defined, the
analogous operation on the corresponding elements of \hat R is
defined and has the corresponding value.

Basically, you can define operations any way you want as long as
you are willing to live with the consequences.  For example, it
turns out to be possible to define an alternative arithmetic in
which (-x)*(-y) = -(x*y) for positive x, y.  The price is that
it doesn't satisfy all the usual axioms, though it does satisfy
other possibly useful ones that the usual systems don't.

In an analogous way, the IEEE designers decided that it would be
useful to have +/- epsilon instead of 0 and +/- (1/epsilon)
instead of infinity, but then decided that the ordering operations
should identify -epsilon with +epsilon, so the result still isn't
quite a proper total order, even ignoring NaNs.  (What happens if
you sort a list of mixed +0.0 and -0.0?  What, if anything,
_should_ happen?)  They obtained the benefits they wanted, at the
price of making the resulting structure less like R.  But then,
floating point numbers never were _very_ much like R to start with.
It's not clear to me that *R offers anything more than a heuristic
analogy to IEEE arithmetic.  For one thing, *R is ordered.

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


Re: [Haskell-cafe] So how do people pronounce 'cabal' around here?

2008-05-28 Thread Richard A. O'Keefe


On 28 May 2008, at 1:04 pm, Dan Piponi wrote:


In particular, which syllable gets the stress, and what are the
lengths of the two vowels? Couldn't find anything in the FAQ
(http://www.haskell.org/haskellwiki/Cabal/FAQ).


I've always pronounced it k'BAHL, but was surprised to find that
the OED (http://dictionary.oed.com/cgi/entry/50030715?
query_type=wordqueryword=cabalfirst=1max_to_show=10
sort_type=alpharesult_place=1search_id=XrC0- 
le6sHc-11893hilite=50030715)

only countenances a short second syllable:
(kinline: schwa.gifinline: sm.gif
bæl)  [a. F. cabale (16th c. in Littré), used in all the English senses,
ad. med.L. cab(b)ala (It., Sp., Pg. cabala), CABBALA, q.v. In 17th c.
at first pronounced inline: sm.gif
cabal (whence the abridged CAB n.5); the current
pronunciation was evidently reintroduced from Fr., perh. with sense 5  
or 6.]





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


Re: [Haskell-cafe] RealFloat constraint on Complex type

2008-05-20 Thread Richard A. O'Keefe


On 21 May 2008, at 9:25 am, Conal Elliott wrote:
I think the practice of constraint in type definitions is generally  
discouraged,


Is this true?  If so, why?
If I have a data type that simply doesn't make sense unless some of the
type variables belong to certain classes, _shouldn't_ that be stated
clearly in the declaration rather than hidden elsewhere?

--
I don't want to discuss evidence. -- Richard Dawkins, in an
interview with Rupert Sheldrake.  (Fortean times 232, p55.)






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


Re: [Haskell-cafe] Re: Richer (than ascii) notation for haskell source?

2008-05-15 Thread Richard A. O'Keefe

On 15 May 2008, at 8:33 pm, Yitzchak Gale wrote:

The point is that it is always best to keep language syntax
as simple as possible, for many reasons. In the case of Unicode,
that means staying as close as possible to the spirit of Unicode and
minimizing our own ad hoc rules.


In particular, Unicode has explicit guidance about what an
identifier should be, in UAX#31:
http://www.unicode.org/reports/tr31/tr31-9.html

I've only recently started slogging my way through the
capital-city-telephone-book-size Unicode 5.0 book.  (I was
tolerably current to 4.0)  Imagine my stress levels on
discovering that Unicode 5.1 is already out, with another
1,624 newly encoded characters, including a capital letter
version of ß.  It is deeply ironic that one of the things
that keeps changing is the stability policy.  Another of the
things that has changed is UAX#31.


Adding one more
keyword is way simpler than adding a bunch of complex
rules to the lexer.


Um, there's no way a Haskell lexer is going to comply with
the Unicode rules without a fair bit of complexity.  The
basic idea is simply id startid continue*, but there
are rules about when ZWJ and ZWNJ are allowed.  The real
issue here is Unicode compliance, and the Unicode rules say
that a mixture of scripts is OK.  Er, it's not actually
that simple.  They do recommend that the scripts in table 4
_not_ be allowed in identifiers, so if you fancied writing
some of your identifiers in Shavian, you may or may not be
out of luck.  (Just why a Coptic priest who is also a
coder should be discouraged from using the Coptic script in
his programs escapes me.)


A lot less moving parts to break.
Especially if those lexer rules are not so consistent with
built-in Unicode concepts such as letter and symbol, glyph
direction, etc.


UAX#31 definitely allows identifiers with any mixture of
left to right and right to left characters.  The *intent* is
that anything even remotely reasonable should be accepted,
and should keep on being accepted, but of course the devil
is in the details.





So I think the best and simplest idea is to make
the letter lambda a keyword.


The lambda that people actually *want* in Haskell is in fact
the mathematical small letter lambda, not the Greek letter.
UAX#31 explicitly envisages mathematically oriented programming
languages that make distinctive use of the Mathematical Alphanumeric
Symbols.  I don't think there can be much argument about this
being the right way to encode the symbol used in typeset versions
of Haskell.  There are three arguments against using it routinely:
 (a) It is outside the 16-bit range that Java is happy with,
 making it hard to write Haskell tools in Java.  But then,
 about 40% of the characters in Unicode are now outside the
 16-bit range that Java is comfortable with, which is just too
 bad for Java.  Haskell tools should be written in Haskell,
 and should cope with 20-bit characters.  (I used to say 21-
 bit, but Unicode 5 promises never to go beyond 16 planes.)
 (b) It is outside the range of characters currently available in
 fonts.  A character you cannot type or see isn't much use.
 Implementations *will* catch up, but what do we do now?
 (c) People *can* type a Greek small letter now, and will not be
 interested in making fine distinctions between characters that
 look pretty much the same.  So people will *expect* the Greek
 letter to work, even if a pedant like me says it's the wrong
 character.

Of course, we could always take an upside down lambda and put some
bars through it and use ¥ for lambda.  (Pop quiz: why would some
people not be surprised to see this instead of \ ?)  [It's a joke.]

All of this seems to leave Greek small letter lambda as a keyword
as being the simplest solution, but it's easy to predict that it
will cause confusion.


True, you need a space after it
then. You already need spaces between the variables after the
lambda, so anyway you might say that would be more consistent.


Who says there is more than one variable?
\(x,y,z)- doesn't have any spaces.
\x - \y - \z - needs spaces, but that's because
-\ is a single token, not because of the identifiers.

--
I don't want to discuss evidence. -- Richard Dawkins, in an
interview with Rupert Sheldrake.  (Fortean times 232, p55.)






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


Re: [Haskell-cafe] Richer (than ascii) notation for haskell source?

2008-05-14 Thread Richard A. O'Keefe

On 15 May 2008, at 7:19 am, Brandon S. Allbery KF8NH wrote:
Unfortunately, while I thought there was a distinct lambda sign that  
wasn't the lowercase Greek letter, there isn't.  (That said, I don't  
see why it couldn't be a keyword.  You'd need a space after it.)


There are three lambda letters: lower and upper case Greek, and  
Ugaritic (U+1038D).

But there are also mathematical symbols:

U+166CC mathematical bold small lamda (sic.)
U+1D706 mathematical italic small lamda (sic.)
U+1D740 mathematical bold italic small lamda (sic.)
U+1D77A mathematical sans-serif bold small lamda (sic.)
U+1D7B4 mathematical sans-serif bold italic small lamda (sic.)

These things are visually letters, but as mathematical symbols
they should not combine into words.  Except that to my surprise, nay,  
to my
utter astonishment, the Unicode 5.1 character data base classifies  
them as

letters just like the letter e.

At least to give editors a fighting chance of matching their concept  
of a

word with Haskell tokens, it might be better to use nabla instead of
lambda.  Other old APL fans may understand why (:-).  Alternatively,  
didn't
Church really want to use a character rather like a down tack, and  
have to
squish it to get a letter his printer was happy with?  Nah, nabla for  
me.


--
I don't want to discuss evidence. -- Richard Dawkins, in an
interview with Rupert Sheldrake.  (Fortean times 232, p55.)






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


Re: [Haskell-cafe] Richer (than ascii) notation for haskell source?

2008-05-14 Thread Richard A. O'Keefe


On 15 May 2008, at 2:34 pm, Brandon S. Allbery KF8NH wrote:
Hm.  Newer Unicode standard than the version supported by OSX and  
GNOME, I take it?  That's not so helpful if nobody actually supports  
the characters in question.  (My Mac claims 166CC is in an  
unassigned area, and no supplied font has the others.  It does at  
least acknowledge that the others should exist and are letters.)


Whoops.  Sorry, typo.  166CC should have been 1D6CC.

I was actually looking at the Unicode 5.1 character data base,
but the copy I keep on my own machine is the 4.0.0 version,
and those mathematical symbols were there back in 4.0.0.

I still suspect it would not be outside the pale to make λ a  
keyword.  We already have several, after all.


I'd rather not have to write \x as λ x with a space required after the  
λ.

I suspect that λ is the lambda-symbol iff it is not preceded by any
identifier character and is not followed by a Greek letter might work.

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


Re: [Haskell-cafe] Re: GHC predictability

2008-05-13 Thread Richard A. O'Keefe


On 14 May 2008, at 8:58 am, Andrew Coppin wrote:
What I'm trying to say [and saying very badly] is that Haskell is an  
almost terrifyingly subtle language.


Name me a useful programming language that isn't.
Simply interchanging two for-loops, from
for (i = 0; i  N; i++) for (j = 0; j  N; j++)
to  for (j = 0; j  N; j++) for (i = 0; i  N; i++)
when marching over an array, can easily slow you down
by nearly two orders of magnitude in C.
[Hint: read What every computer scientist needs to know
about memory.]  For a real shock, take a look at what
your C++ templates are doing...

There's one big difference between Haskell and language T (my other
preferred language).  Seemingly insignificant changes in Haskell can
kill performance, but seemingly insignificant changes in language T
can take you into territory the library designers never thought of
where there are lions, tigers, and bears in abundance.  Unexpectedly
slow is better than inexplicably buggy.


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


Re: [Haskell-cafe] Re: Interesting critique of OCaml

2008-05-11 Thread Richard A. O'Keefe

On 9 May 2008, at 6:59 am, Donnie Jones wrote:


I pasted a copy of the article below for those that cannot access  
the site.Why Ocaml Sucks
Published by Brian at 6:49 pm under Functional Languages: Ocaml,  
Haskell




. An even better idea [for 'printf'] might be some variant of  
functional unparsing.




There's a link to http://www.brics.dk/RS/98/12/.  I spent a bit of  
time last week
playing with the code in that paper.  Some of the basic ideas are  
nice; the idea
that 'formats' are functions and concatenation of formats is  
composition of
functions was particularly nice.  But seeing it with Haskell eyes, the  
idea of
building strings up using cascades of (basically) \s x - s ++ f x,  
where s is a
byte string, not a list, and ++ is concatenation of byte strings,  
seemed obviously
wrong.  I replaced it by \sl x - f x : sl, with the final step (in an  
already
existing interface function) being to reverse all the stringlet and  
concatenate
them in one big step.   I was gratified, but the very reverse of  
surprised, to get
a substantial speedup.  (A factor of over 100 for a small but non- 
trivial test,
using SML/NJ.)  In effect, thinking in terms of shows paid off  
handsomely.


Haskell-think wins again!

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


Re: [Haskell-cafe] Maybe a, The Rationale

2008-05-11 Thread Richard A. O'Keefe

On 12 May 2008, at 1:52 am, Brandon S. Allbery KF8NH wrote:
My real point was that in the C programming culture it was/is far  
too common to use an in-band value; that is, one that could be  
confused with or treated as a valid response:  null pointers,  
stdio's EOF (= -1).


Here I must disagree.  I've hacked character-level I/O in lots of  
programming languages (the
last time I counted I'd used more than 100), and C was the first  
language I ever met that
made it easy, precisely BECAUSE the perfectly normal there are no  
more characters situation

was handled the same way as every other outcome.

 This just causes problems because code is almost encouraged to  
ignore the special cases.

 For example, the ctype macros have to support being passed EOF.


So they do, but it is elementary to do so.  The only reason there is  
anything even
remotely unusual there is that the *same* functions are used in C for  
*character* input
and *byte* input.  I'll grant you that you probably don't want to  
process binary input
using quite the same quasi-FSA code that you want for characters.   
Since C uses NUL for
terminating strings, and since ASCII made it clear that NUL was never  
ever *supposed* to
appear in text, NUL would have been the perfect choice for character  
EOF, and in that
case there would never have been anything odd about having the ctype  
macros handle it.


I've been writing some Smalltalk recently, which uses a Pascal-like  
convention

aStream atEnd   test for EOF
  ifTrue: [self handleEOF]
  ifFalse: [self handleCharacter: aStream next]
and the EOF tests clutter up the code inordinately and make it so  
painful that C

starts looking good again.

The C approach here has several benefits:
 - you can *postpone* checking for EOF until after you have checked for
   other things; since EOF is seldom or never what the code is mainly
   *about* this is good for clarity
 - if you want to know is the next character one of these you have  
only
   two cases to deal with at that point (yes and no), not three (yes,  
no,
   and you-idiot-you-forgot-to-test-for-EOF-first-and-testing-for-EOF- 
is-
   the-most-important-thing-anybody-could-be-interested-in-when- 
reading).


 Maybe types force you to deal with it, while simultaneously  
providing convenience functions to help you deal with it.


I readily grant that Maybe is a wonderful wonderful thing and I use it  
freely and

voluntarily.  BUT it should not dominate the code.

Consider Haskell's getChar and hGetChar.  They DON'T return Maybe  
Char; they
raise an exception at end of file.  You have to keep testing isEOF/ 
hIsEOF before

each character read, as if we had learned nothing since Pascal.
Arguably, maybeGetChar :: IO (Maybe Char) and hMaybeGetChar :: Handle - 
 IO (Maybe Char)
would be a good idea, at least then one could easily set up some  
combinators to

deal with this nuisance.




--
brandon s. allbery [solaris,freebsd,perl,pugs,haskell] [EMAIL PROTECTED]
system administrator [openafs,heimdal,too many hats] [EMAIL PROTECTED]
electrical and computer engineering, carnegie mellon university 
KF8NH



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



--
I don't want to discuss evidence. -- Richard Dawkins, in an
interview with Rupert Sheldrake.  (Fortean times 232, p55.)






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


  1   2   >