Re: [Haskell-cafe] US Patent for the idea of using Haskell to implement UAX #9

2010-04-17 Thread Brian Hulley

Daniel Fischer wrote:

Am Freitag 16 April 2010 20:50:25 schrieb Brian Hulley:

revealed a link to a US Patent (7120900) for the idea of implementing
the Unicode Bidirectional Algorithm (UAX #9
http://www.unicode.org/reports/tr9) in Haskell, making use, as far as I
can tell, of nothing more than the normal approach any functional
programmer would use, namely separation of concerns etc.


In which case the patent should be null and void since obvious ideas aren't 
patentable, AFAIK.

But of course, IANAL, you never know what jurists think a law means, ...


Hi Daniel,
Thanks for your reply.
The main problem for me is just the fact that the legal system in itself 
is, as Charles Dickens wrote in The Old Curiosity Shop (Chapter 37):


... an edged tool of uncertain
application, very expensive in the working,
and rather remarkable for its properties of
close shaving, than for its always shaving
the right person.

I just think somehow we should be free to write any programs we want 
just like composers can compose music, (as long as we don't just copy 
other people's actual copyrighted *code* without their permission of 
course).


After all, there is no reason why people couldn't just keep their ideas 
a secret if they don't want others to use them: at least it wouldn't 
spoil things for everyone else. Companies could even charge for *access* 
to these secrets and people could sign NDAs, but this isn't the same as 
being allowed to actually own an idea itself.


The current situation is a bit like a supermarket throwing oranges and 
apples at passers-by, then forcing people to pay if they were hit...


In any case after signing the petition I'm going to just try and forget 
about the problem! ;-)


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


Re: [Haskell-cafe] Re: US Patent for the idea ...

2010-04-17 Thread Brian Hulley

jerzy.karczmarc...@info.unicaen.fr wrote:

Brian Hulley reports a search similar to :


   haskell unicode bidirectional



Comment irrelevant to Haskell, sorry.
Everybody does his/her various jobs. But I lost all respect due to people
who work in the US Patent Office, when I saw the patent 6,025,810, a patent
for an antenna which sends signals faster than light, using some mysterious
new dimension. Or the U.S. Patent 6,960,975 for an anti-gravity device.
It seems that although it is illegal to break some local regulations, the
idea of breaking fundamental physical laws remains perfectly legal. (In
some countries...)
Somebody finally decided to ridiculise the system. If you want a good 
laugh,

see the patent 6,368,227. The search site is here:
http://patft.uspto.gov/netahtml/PTO/srchnum.htm
Best regards.
Jerzy Karczmarczuk
...


Hi Jerzy,
Yes that one is very funny.
Also the existence of the other patents just show how ridiculous the 
system is.


So thanks, that humour has helped me get back down to earth and away 
from all kinds of fruitless imaginations about the state of the world. I 
think my mind is best suited to functional programming *only*... ;-)


Cheers, Brian.

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


Re: [Haskell-cafe] Re: US Patent for the idea ...

2010-04-17 Thread Brian Hulley

Murray Gross wrote:

On Sat, 17 Apr 2010, Brian Hulley wrote:


see the patent 6,368,227. The search site is here:
http://patft.uspto.gov/netahtml/PTO/srchnum.htm
Best regards.
Jerzy Karczmarczuk
...


It's really almost not fair to cite that particular patent, since, if I
recall the story correctly (I may be wrong in small detail, but I am 
sure of the general picture), that patent was filed by an attorney as a 
demonstration to his son how the system works. It was never filed as a 
serious patent. Yes, it may show how poorly the examiners are doing 
their job, but I think this particular patent really doesn't reflect on 
the poor service we are currently receiving from the entire patent 
system--I would like to think that the examiner knew perfectly well that 
this patent was not serious and was willing to play along.


Hi Murray,
Point taken about patent 6,368,227.
I think in all fairness to examiners that in a way they have an 
impossible job due to the fact that what is a clever idea to one 
programmer will be a trivial idea to another: the field is so huge and 
people have such different experiences.


Coming back to patent 6,368,227 one could perhaps look past the humour 
and see it as a kind of indication of what the patent system is trying 
to do to humanity. I just mean to see this dispassionately as an image, 
and by trying to do I'm just anthropomorphizing what I see as a purely 
structural phenomenon that in itself is like a force of nature, that 
emerges from the inevitable incompleteness of people's understandings 
even if each person individually is trying to do what they feel is right.


In terms of a way forward for research companies I think there is a lot 
of well-paid work to be found in designing and implementing useful 
libraries of functionality, and then licensing them for inclusion in 
other programs.


After all, end users want a real implementation not just an idea, and it 
is surely much easier to trade implementations rather than to try to 
trade the rather nebulous concept of ideas.


This would allow programmers full freedom to implement whatever they 
like together with the clear advantage of being able to license well 
designed third-party libraries: we'd have total clarity and freedom.


Anyway I've said enough about software patents so I'll leave the 
discussion here and reiterate that all I want is for people to be able 
to write programs without a Sword of Damocles hanging over their heads.


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


[Haskell-cafe] US Patent for the idea of using Haskell to implement UAX #9

2010-04-16 Thread Brian Hulley

Hi everyone,
It's been a long time since I last posted to this list since I'm 
currently working on something that is not directly Haskell-related, but 
it still relates to functional programming in general.


Anyway imagine my surprise when an innocent search for some keywords (I 
can't remember the exact ones but the following gives similar results)


   haskell unicode bidirectional

revealed a link to a US Patent (7120900) for the idea of implementing 
the Unicode Bidirectional Algorithm (UAX #9 
http://www.unicode.org/reports/tr9) in Haskell, making use, as far as I 
can tell, of nothing more than the normal approach any functional 
programmer would use, namely separation of concerns etc.


The link is http://www.freepatentsonline.com/7120900.html though I think 
it would be better if they had just called the website free handcuffs 
online because that is what it amounts to when people succeed in 
preventing others from using ideas, especially ideas everyone would 
easily think up by themselves.


Before going further I would like to explicitly state that I would not 
wish to cast any aspersions upon the people or companies involved in 
this patent, since it is all too clear to me that these people have 
acted in a perfectly legal way and are just doing their various jobs: in 
other words it's an I'm a lumberjack and I'm ok... kind of scenario: 
everyone probably thinks of themsevles as being a perfectly nice 
upstanding person, and if I met any of them face to face I'm sure I 
would find that they are *indeed* really nice friendly people who 
believe that they are doing absolutely the right and logical thing.


In fact many nice people I myself have talked to about my own ideas 
immediately suggest that I should obviously patent them: it takes a 
long time to explain to them why this would not actually further my 
goals at all, and it is difficult for them to understand my explanation 
because the problem is rather too subtle for people who have not already 
been thinking along these lines for a while.


However all this does not affect the problem that this patent acts as a 
brick in the general structural evil in our world today: anyone who is 
trying to create a programming language environment that is accessible 
to people who use right-to-left languages is now between a rock and a 
hard place when it comes to implementing UAX #9, the standard Unicode 
algorithm for implementing the Unicode semantics of bidirectional text.


In this particular case, I expect (but I'm not a lawyer so please don't 
take this as solid advice: it's just a hope) that a workaround for 
Haskell programmers would be to discard their natural desire to use a 
functional approach and instead just implement UAX #9 verbatim using the 
ST monad. (The patent also tries to extend itself to other functional 
languages so caution is needed all round.)


But although the above workaround *might* be legal in this particular 
instance it seems to me that as programmers we must not just let our 
craft be dominated by the psychopathic tendencies of certain elements in 
society that work hard to try to squash the ``normals'' into a life of 
brutal misery while they rampage ruthlessly about with a biological 
inability to experience empathy for other human beings. (www.ponerology.com)


The memetic virus of psychopathy is rapidly spreading throughout human 
civilization and most people are not conscious enough of the elements 
that are contributing towards their own behaviour, thus ignoring the 
fact that the rice they eat for supper might have been picked by a tiny 
little girl in China with bleeding fingers or the carpet they walk on 
may have been made by a little 8 year old boy slave chained all day to a 
loom in a shed in India.


To this end I humbly appeal to everyone here to please help in the fight 
against software patents, so that we can begin the huge task of 
reclaiming our world for real people who understand that true meaning in 
life comes from extending our feeling of self into the world beyond our 
own body:


  http://petition.stopsoftwarepatents.eu/
  http://ffii.org

Thanks a lot for reading this,
Brian. [expecting to be crucified, but if it helps just one little girl 
or boy it will be worth it!]


Disclaimer: this email is entirely my responsibility and I am not acting 
on behalf of any of the above web sites.


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


Re: [Haskell-cafe] Looking for a more functional way to do this

2008-08-06 Thread Brian Hulley

Jefferson Heard wrote:

Adrian, my understanding is that it's not that simple, because I need
to preserve the state between calls to GLUT's callbacks, which all
return IO ().

2008/8/6 Adrian Neumann [EMAIL PROTECTED]:

There is the State Monad...




data ProgramState  = ProgramState {
   some_associative_data :: Map String String
 , position :: GL.Vector3 Float
 , look_at :: GL Vector3 Float
 , selectables :: Map GLuint NamedObject
 }

render :: IORef ProgramState - IO ()


You might find it easier to think in terms of a Reader monad where each 
component of your ProgramState above is now a separate IORef.


Then you can just use a function:

mkCallback :: ReaderT ProgramStateRefs IO () - IO ()

to create the necessary callbacks for GLUT, and there is no need to 
interleave any state between calls (since it's all kept in the IO monad 
directly).


Eg:
  data ProgramStateRefs = ProgramStateRefs
{ some_associative_data :: IORef (Map String String)
, ...
}

  main = do
r - createProgramStateRefs
let
  mkCallback :: ReaderT ProgramStateRefs IO a - IO a
  mkCallback (ReaderT r_ma) = r_ma r
GLUT.renderCallback $= mkCallback onRender
...

  onRender :: ReaderT ProgramStateRefs IO ()
  onRender = do ...

You can then go further and use phantom types to build specialized 
monads by newtyping the (ReaderT ProgramStateRefs IO) to limit the 
operations possible in each callback (e.g. to prevent calls to rendering 
methods inside a keyboard handler etc) though at some point there is a 
tradeoff between how much you really need to enforce statically and how 
much time you have to devise suitable schemes of phantom type parameters 
to enforce it.


(Disclaimer: the above code is untested and may contain errors ;-) )

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


Re: [Haskell-cafe] Capitalization and associated type families

2008-08-05 Thread Brian Hulley

Jonathan Cast wrote:


It's weird.  ML-derived languages are functional languages at the value
level (and have regular lambda-bound variables in consequence), but are
logical languages at the type level (and have logical variables in
consequence).  So ordinary lambda-bound variables, like in ML-style
functors (parametrized modules) act more like type constants than like
type variables.


Thanks - the above seems to be a promising avenue of thought to arrive 
at clarity regarding case distinctions at the type level, and I can see 
here the basis for a good argument of why there would actually be no 
inconsistency regarding the use of capitals for module type members and 
lowercase for the class parameters. Perhaps this is also the root of the 
difference between associated type synonyms and class params.


Ie at the type level, uppercase == functional variable (aka constant) 
and lowercase == logic variable...


The type level now seems to me to be quite significantly more 
complicated than the value level due to the mixing of functional and 
logic programming, not to mention that at the type level variables in 
an outer scope become constants in an inner scope as far as pattern 
matching is concerned whereas for value patterns variables are always 
fresh and never scoped (over other patterns).


Therefore I've decided to deal with the issue of case at each level 
separately since it seems immediately clear that the case distinction at 
the value level, as in Haskell/OCaml/Moby, is obviously good due to the 
foolproof nature of value patterns you pointed out, whereas at the 
type level it may also be good but I'll need a few more months to think 
about it... ;-)


Cheers,
Brian.

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


Re: [Haskell-cafe] Capitalization and associated type families

2008-08-05 Thread Brian Hulley

Tillmann Rendel wrote:

Brian Hulley wrote:


class Foo a where

f :: a - b - (a, b)

Here there is no capitalization distinction in the type of (f) but the 
implementation can still insert the forall b. since (a) is already 
in scope. Therefore similarly, if type constructors like List were 
instead written using lowercase, since they would already be in scope 
it would be clear even without explicit quantifiers that (a) and (b), 
but not (list), were to be quantified in the type of (map) (assuming 
of course that there was no top level data decl for (a) or (b)).


So adding b to the export list of an imported module would change the 
type of f?


Yes, if the module in which the above class decl were defined imported a 
data type (b) from some other module (or defined it elsewhere in the 
same module) then (f)'s type would change. (Of course at the moment this 
can't happen because (b) is lowercase so it can't be introduced by 
data/type decls or imported/exported.)


The type of (f) would also change if Haskell were extended to support 
nested classes:


class Bar b where
class Foo a where
f :: a - b - (a, b)

But as Jonathan pointed out this behaviour is not really all that ideal 
since even in Haskell at the moment a simple spelling mistake could 
cause silent quantification instead of an error (which is perhaps the 
main justification for why constructors introduced by data/type decls 
must currently be capitalized -- unfortunately there is no corresponding 
protection when writing types inside class decls):


class Zap a where
g :: a - 
^ oops!
Cheers -
Brian.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] Capitalization and associated type families

2008-08-04 Thread Brian Hulley

Hi,
I'm familiar with the capitalization rules for identifiers in Haskell 
and know that they are very useful and practical e.g. by allowing 
variables to be distinguished from constants in patterns etc.


However I'm trying to understand on a much deeper level whether or not 
they can really be justified and indeed if there is a danger that they 
can lead to inconsistency in the light of future extensions to the language.


For example, why is there any distinction between a type variable and 
a type constant?


To make this clearer consider the type of (map):

(a - b) - List a - List b

(ignoring the special [] syntax for list types which would just confuse 
the issue here).


With explicit quantifiers, we'd write:

forall a b. (a - b) - List a - List b

Now this begs the question: why does List need to start with a 
capital? (supposing that quantifiers were always written explicitly)


The same distinction between constants and variables is also used in 
predicate logic e.g.


On(x, Table)  Colour(x, Red)

but similarly the above could surely be written just as easily by:

exists x. on(x, table)  colour(x, red)

where (on), (table), (colour), and (red) are just considered to be 
variables that have already been introduced (by some enclosing scope) 
instead of having to think of them as constants and make a distinction 
between constant and variable.


Anyway to get to the point of this post what I'm really trying to find 
is some explanation of why there is the concept of constant as opposed 
to variable or whether this concept is now redundant in the light of 
lexical scoping/ explicit quantification?


Somewhat related to this issue is the syntax of associated type 
families. For example in section 5.2.2 of 
http://www.haskell.org/haskellwiki/GHC/Indexed_types there is the example:


class C a b where
data T a

which raises in my mind several questions:

1) Why is (T) given a parameter? I.e. why does an associated type 
declared inside a class decl not automatically get all the parameters of 
the class passed to it so that one would just write:


class C a b where
data T
f :: T - T
===
data family T a b
class C a b where ...
f :: T a b - T a b

2) Compare:

class C a b t | a b - t
with
class C a b where
data T

In other words, why is (T) a constant when it is declared inside the 
class but a variable when passed as a parameter?


Is the fact that (T) needs to be given a parameter even when it is 
declared inside the scope of the class type parameters the result of 
needing to fulfill the idea of constant vs variable?


3) In the syntax:

class C a b
data T a

it seems rather odd that the a in T a should be related to the a 
in C a b since one might expect that the name chosen for a parameter 
should be local to the data decl.


Apologies for such a rambling post. I've spent literally at least 6 
months scouring the internet trying to find a real discussion about 
capitalization rules because I'm trying to answer the following 
question: if I make use of a similar capitalization rule in my own 
language, can I guarantee that this rule will not lead to an 
inconsistency at some future point? Ie is there a real rock solid 
theoretical basis for making a distinction between constants and 
variables that holds even in the presence of lexical scoping?


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


Re: [Haskell-cafe] Capitalization and associated type families

2008-08-04 Thread Brian Hulley

Jonathan Cast wrote:

On Mon, 2008-08-04 at 19:51 +0100, Brian Hulley wrote:
For example, why is there any distinction between a type variable and 
a type constant?


forall a b. (a - b) - List a - List b

Now this begs the question: why does List need to start with a 
capital? (supposing that quantifiers were always written explicitly)


AFAIK, it doesn't; the variable/constant distinction is just there to
let the implementation put the foralls in for you.


Hi Jonathan - thanks - this confirms what I've been thinking. However 
consider:


class Foo a where

f :: a - b - (a, b)

Here there is no capitalization distinction in the type of (f) but the 
implementation can still insert the forall b. since (a) is already in 
scope. Therefore similarly, if type constructors like List were 
instead written using lowercase, since they would already be in scope it 
would be clear even without explicit quantifiers that (a) and (b), but 
not (list), were to be quantified in the type of (map) (assuming of 
course that there was no top level data decl for (a) or (b)).



 Similarly, if we had
explicit foralls on equations, we could say

forall n x xn. drop (n+1) (x:xn) = drop n xn

but

forall n. drop n nil = nil

and it would be perfectly clear that `nil' in the latter case was a
constructor.


Actually I quite like the above because it shows that pattern matching 
can be understood in terms of universally quantified predicates.


Regarding the verbosity, patterns are something of a special case since 
variables (that are introduced in the pattern) can only occur once and 
there is no need to have higher rank quantification in value patterns 
(disregarding explicit tests for _|_). Therefore special syntax could be 
used to make the above shorter e.g. borrowing the '?' from Felix 
(http://felix.sourceforge.net/doc/tutorial/introduction/en_flx_tutorial_top.html 
 (section 2.11/2.17 etc)):


drop (?n + 1) (_ : ?xn) = drop n xn
drop ?n nil = nil

(where glued prefix binds tighter than application).



Of course, if you want to introduce this rule, you'd better start out
with it and be consistent --- require every variable to be explicitly
brought into scope.  I think you'd find it pretty annoying after trying
to program in your new language for a while, though.



I agree that there are many good points in favour of Haskell's use of a 
case distinction, not the least being that it gives definite guidance on 
when to use lower or upper case identifiers and therefore avoids the 
mess you find in C++ programs where every programmer has their own 
private conventions which can lead to confusion and useless debate.


However it still seems to me that the case distinction, at least on the 
level of type constructors, becomes problematic and possibly 
inconsistent especially if I consider the effects of trying to 
incorporate something like the ML module system as well as type classes. 
(For example the Moby language (http://moby.cs.uchicago.edu/ ), a 
possible successor to SML, uses capitalization for type constructors 
similar to Haskell which means that type parameters in functor 
applications must be uppercase, which conflicts with the use of 
lowercase type params for classes which are a special kind of functor... 
(Moby itself doesn't encounter any difficulty since it doesn't have type 
classes)).


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


Re: Module system, was Re: GHC source code improvement ideas

2008-01-06 Thread Brian Hulley

Johannes Waldmann wrote:

Brian Hulley wrote:

In the long term, Haskell needs a better module system IMHO [...] 


I agree with the symptoms that were described, but I draw a different
conclusion.

We don't need to change the language - we need better tools (IDEs)
that operate not at the textual level, but use the annotated syntax tree,
including knowledge on fully qualified names and types.


Hi Johannes,
I agree that better tools would be a good thing, and could improve the 
programming experience considerably, but I still think that an improved 
module system design would be an orthogonal benefit.


Best regards, Brian.

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Module system, was Re: GHC source code improvement ideas

2008-01-04 Thread Brian Hulley

Ian Lynagh wrote:

On Fri, Jan 04, 2008 at 08:34:22AM +, Simon Peyton-Jones wrote:

|   4. A more radical change would be introducing hierarchical modules.



It's a pity that GHC.* is already used in base. I'm not sure what the
best thing to do is in the short term.



How about Language.Haskell.Compiler.GHC.*

In the long term, Haskell needs a better module system IMHO, since the 
problem at the moment is that having to write the full hierarchical name 
in each module means that you need to know in advance, before you've 
even started writing a program, where each module will fit into the 
global namespace, which makes it extraordinarily difficult to do 
exploratory programming or bottom-up development, and the need to write 
so many import directives in each module makes it extremely painful not 
to mention overly hard-wired.


A good direction IMHO is the way SML structures are grouped using 
CM.make (SML/NJ) or MLBasis (MLton and others), so that there are no 
import directives at all: a separate group definition determines what is 
in scope, and compilation proceeds by chasing these group definition 
files rather than chasing modules.


Translating this into Haskell, the module syntax could be simplified and 
other modules could be nested and aliased within a module, so that it is 
easy to create different hierarchical views of the modules which are in 
scope to suit the particular module being written or clients of that module:


-- Leaf.hs
module Leaf where
module String where
open Data.ByteString.Char8
type T = ByteString

module Map = Data.Map

module Util where
foo :: Int - Int
foo i = i

--Other.hs
module Other where
bar :: Int - Leaf.String.T
bar = Leaf.String.pack . show . Leaf.Util.foo

Note that here there is no need for any import directives, since the 
modules which are in scope when Leaf.hs is compiled would be determined 
by whatever group Leaf.hs is part of (with respect to that particular 
program), which would be defined in a separate file:


--MyBasis.hsg
local $Haskell/StdBase.hsg

Leaf.hs
Other.hs

Within the .hsg files, groups and modules are referenced by filename, 
and is just a simple list of components that are required and/or 
exported by the group. In the .hsg file above, MyBasis will export the 
contents of Leaf.hs and Other.hs, which are compiled in an environment 
augmented by StdBase (which is not itself exported by MyBasis).


(See CM.make and the MLBasis system for more details - in particular, 
for any given program a module may appear in only one group, but the 
same module may appear in different groups in different programs thus 
facilitating easy exploratory programming and re-organization without 
breaking previous programs.)


This can be taken further to get an even more powerful system by using 
parameterized traits and explicit instantiation for modules:


trait T a b where
foo :: a - b

bar :: Int - Int
bar i = i + 1

module M where
include T Int String
foo = show . bar

Here, the body of a module is always a trait, and the above is 
equivalent to:


trait T a b = tra
foo :: a - b

bar :: Int - Int
bar i = i + 1

module M = new tra
include T Int String
foo = show . bar

which makes it more explicit that conversion of the contents to actual 
code (ie linking, allocation/identity/initialization of CAFs and foreign 
objects, generativity of data types etc) happens only in the module decl.


The great thing about making instantiation explicit is that traits are 
pure functional values and so can easily be combined with no side 
effects, whereas modules may in general contain mutable state eg to 
interface with some external C library and thus are 
objects-with-identity. Thus the separation solves the whole problem of 
applicative vs generative functors in ML, as well as solving the problem 
of mutually recursive structures (functors become a redundant concept 
because you can always start with including a trait then overriding some 
decls with more instantiated (here used in a different sense) decls 
and/or traits).


Last but not least, a trait could also be used similarly to a signature, 
except that definitions in the trait can be considered to be default 
implementations. Therefore in this scenario the body of a class or 
instance decl is just a trait and so could be composed using other 
traits etc. (Each instance decl instantiates the trait given in the body 
merged with the trait given in the class leading to a possibly 
parameterized module.)


Anyway these are some of the directions I am currently working on for my 
new 

Re: Module system, was Re: GHC source code improvement ideas

2008-01-04 Thread Brian Hulley

Brian Hulley wrote:

Ian Lynagh wrote:

On Fri, Jan 04, 2008 at 08:34:22AM +, Simon Peyton-Jones wrote:

|   4. A more radical change would be introducing hierarchical modules.



Sorry I quoted what Simon PJ replied to not what he wrote so I should 
have written:


 Ian Lynagh wrote:

  On Fri, Jan 04, 2008, Twan van Laarhoven wrote:
4. A more radical change would be introducing hierarchical modules.

Though this is again not quite right since Ian did not write line 3...

Apologies to Simon PJ and Twan (and now also to Ian) for mis-quoting ;-)

Brian.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Dynamic choice of reverse implementation

2007-09-28 Thread Brian Hulley

Krzysztof Kościuszkiewicz wrote:

Fellow Haskellers,

I wanted to experiment a bit with lists and sequences (as in Data.List and
Data.Sequence), and I got stuck. I wanted to dynamically select processing
function depending on cmdline argument:

  

main = do
args - getArgs
let reversor = case args of
[sequence] - reverseList
[list] - reverseSeq
_ - error bad args
input - getContents
let output = reversor $ lines $ input
mapM_ putStrLn output



In my oppinion reversor would have type

  

reversor :: (Foldable f) = [a] - f b



  


No, this is the wrong type. To find the correct type, if you look at the 
type of the input argument in your code it will be the result of 
(lines), so from ghci:


Prelude :t lines
lines :: String - [String]
Prelude

Therefore (reverseor) has type [String] - ???
Now for the output type, you are using (output) as an input to (mapM_ 
putStrLn). (mapM_) takes a list and uses its argument to do something to 
each element of the list. So, since the input to (putStrLn) is (String), 
the input to (mapM_ putStrLn) is ([String]).

Therefore

   reversor :: [String] - [String]

So reverseList is just Data.List.reverse as you've got it (though 
presumably you meant to write [list] - reverseList and not reverseSeq).


For using Data.Sequence to implement reversor, all you need to do is 
first convert [String] to Seq String, reverse the sequence, then convert 
back from Seq String to [String].


Hope this helps,
Brian.



but I couldn't get this to work. I've tried typeclass approach:

  

class (Foldable f) = Reversor f where
reverse' :: [a] - f a

instance Reversor ([]) where
reverse' = Data.List.reverse

instance Reversor ViewR where
reverse' = viewr . foldr (|) empty 


reverseList = reverse' :: (???)
reverseSeq  = reverse' :: (???)



but now in order to differentiate between reverse' functions I'd
have to provide different type annotations, and then reversor won't
typecheck...

Similar problem surfaced with this try:

  

data Proc = SP | LP
reverseList = reverse' LP
reverseSeq = reverse' SP

reverse' :: (Foldable f) = Proc - [a] - f a
reverse' LP = Data.List.reverse
reverse' SP = viewr . foldr (|) empty



So now I'm looking for some suggestions how should I approach the
problem...

Regards,
  

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


Re: [Haskell-cafe] Dynamic choice of reverse implementation

2007-09-28 Thread Brian Hulley

Brian Hulley wrote:

Krzysztof Kościuszkiewicz wrote:

So the type of mapM_ used in the code is
(Foldable t, Monad m) = (a - m b) - t a - m ()

I'd like to keep the generic Foldable t there when m is specialized 
to IO.

I thought this would allow type of reversor to be specialized to
(Foldable f) = [String] - f String
  ... I'd like to avoid [a] - something - [a]


Yes this type should be fine.


I should have said though that in your code, because one arm of the case 
construct returns Data.List.reverse, the type of reversor is fixed to 
[a] - [a].


The other arm of the case construct could make use of a more general 
function eg


   reverseFoldable :: (Foldable f, Foldable g) = f a - g a

but it would only be used at f == [], g == [].

So in terms of the command line test harness, I think the only way is to 
explicitly choose the foldable you want to try out eg by using 
(Foldable.toList . Seq.reverse . Seq.fromList) etc.


An alternative might be to just write some different implementations of 
reverse functions in a module then load the module into ghci to test 
them out interactively so their types don't get unified with each other.


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


Re: [Haskell-cafe] Dynamic choice of reverse implementation

2007-09-28 Thread Brian Hulley

Krzysztof Kościuszkiewicz wrote:

So the type of mapM_ used in the code is
(Foldable t, Monad m) = (a - m b) - t a - m ()

I'd like to keep the generic Foldable t there when m is specialized to IO.
I thought this would allow type of reversor to be specialized to
(Foldable f) = [String] - f String
  
... I'd like to avoid [a] - something - [a]


Yes this type should be fine. To implement reversor though you'd still 
need to first convert from the concrete list to whatever foldable you're 
using, before reversing the foldable, or implement something more 
general eg:


reversor :: (Foldable f, Foldable g) :: f a - g a

Of course with lazy evaluation + compiler optimizations the lists in [a] 
- something - [a] should be erased at compile time... ;-)


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


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-27 Thread Brian Hulley

Sam Hughes wrote:

Brian Hulley wrote:

... For example, with the prefix definition of a function with 
multiple clauses, the function name at the start of each clause is 
already lined up since it must appear at the margin of the current 
layout block ...


Or you could have everything be backwards, and use an editor that 
right aligns things.



   (a - b) - [a] - [b] ::  map
[] = [] _ map
x f : xs f map = (x:xs) f map



There is still a reversal here between the order of arguments in the 
type signature and the order in the clauses.


Henning Thielemann wrote:



Curried functions like

f :: a - b - c

suggest a swapped order of arguments for (-), since 'f' must be 
called this way


b a f

Maybe it should be

f :: c - b - a




Which would fix this reversal. However there are 2 other kinds of 
reversal with postfix notation:
1) Declarations start with a keyword followed by some content whereas 
function definitions start with the args followed by the function name
2) Special constructs like case or let have to start with the 
keyword (so the parser knows what kind of thing it is supposed to parse 
next and so that the editor knows how to highlight what the user is 
typing before the user has finished typing the whole construct), again 
making a reversal between built-in constructs and constructs you can 
define using higher order functions (eg consider if as a user-defined 
construct in a postfix language)


I've come to the conclusion that whereas postfix notation is extremely 
neat for simple stack-based languages like Forth and PostScript it would 
not play well with languages which have a structured syntax since 
structured syntax + left to right reading order implies each syntactic 
element must start with a head followed by content appropriate to that 
element, or else recursive descent parsing and/or as-you-type 
grammatical highlighting would be impossible, and therefore in terms of 
function application, the head must of course be the function itself 
hence Prefix is the only solution.


Jonathan's comparison to natural languages made me think of it this way:

   x `plus` y   ===  [Subject] [Verb] [Object]

   x .plus(y) === [Subject] [Verb Object]

   plus y x === [Verb Object] [Subject]

   plus x y === [Verb Subject] [Object]

which illustrates why infix notation feels natural (corresponds to SVO 
in English etc), why OOP notation feels natural, why prefix notation is 
natural for a functional language (since we are interested primarily in 
the transformation not the things being transformed hence we put [VO] 
first), and why the desuraging of infix in Haskell/ML is quite simply 
just wrong, since the object is now separated from the verb.


ok wrote:

Binary operators have two arguments.  That's why sections are needed.


What's wrong with just using (flip)?




I am a bear of very little brain, and I would find it VERY confusing
if the order of arguments in an operator application did not match
the order of arguments in a function call.  I can live with
x @ y = (op @)(x, y)(* SML *)
x @ y = (@) x y-- Haskell
but making the orders different would guarantee that I would *always*
be in a muddle about which argument was which.  Living with
inconvenient argument orders is vastly easier than with inconsistent 
ones.


If you inwardly parse x @ y as [x] [@ y] then the prefix notation is 
naturally formed just by putting the specialized verb before the 
subject instead of after it ie [@ y] [x].
Therefore I think this desugaring, though different from the usual one, 
would seem natural as soon as the reason for it was understood (of 
course, only if you agree with the reason ;-) ), and the great advantage 
of it is that we could write library functions without having to decide 
in advance whether or not they should be used with infix sugar.


(Regarding Henning's point about ((-) a) being needed for Reader monads 
we could define type Fun a b = a - b and then use (Fun a))


In any case, thanks to all who replied. I've found the discussion very 
illuminating and it's certainly helped a lot to clarify the issues for me,


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


[Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Hi,

I'm in the process of designing a little language inspired by Haskell 
but imperative, and have hit an issue regarding infix syntax which may 
be of interest also to anyone thinking about future revisions of Haskell 
or the problem of consistent parameter order in libraries.


I'm wondering if anyone can shed light on the reason why

   x # y

gets desugared to

  (#) x y

and not

  (#) y x

since the first desugaring always seems to lead to (#) having to be 
defined in a way that is unnatural for functional programming. This is 
why a lot of functions in the standard libraries have their arguments 
the wrong way round. For example in Data.Bits we have:


   shiftL :: a - Int - a

whereas the natural argument order for a functional language would be to 
make it so that in an application one has the verb first followed by the 
noun as in:


   shiftL' :: Int - a - a

so we could write (shiftL' 3) to denote the operation of shifting 
something left by 3 eg:


  let
   shiftLeftByThree = shiftL' 3
  in
  map shiftLeftByThree  [10, 78, 99, 102]

(This choice of argument order is explained at 
http://www.haskell.org/haskellwiki/Parameter_order )


Similarly, considering arithmetic, it would make a lot more sense to me 
to define:


   x - y === (-) y x

since the action here is take away y and the noun is x so the 
natural functional reading of (-) a b is subtract a from b.


To be consistent this would also have to apply to the use of (-) in 
types to get:


   a - b === (-) b a

Can anyone think of an example where the current desugaring of infix 
arguments gives the correct order when the function is used in a postfix 
application? (apart from commutative functions of course!)


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


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Brian Hulley wrote:

I'm wondering if anyone can shed light on the reason why

   x # y

gets desugared to

  (#) x y

and not

  (#) y x



Can anyone think of an example where the current desugaring of infix 
arguments gives the correct order when the function is used in a 
postfix application? (apart from commutative functions of course!)



Sorry I meant to write *prefix* application
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Jonathan Cast wrote:

On Tue, 2007-09-25 at 19:18 +0100, Brian Hulley wrote:
  

Brian Hulley wrote:


I'm wondering if anyone can shed light on the reason why

   x # y

gets desugared to

  (#) x y

and not

  (#) y x

  

Of course, this is all a consequence of the well-known failure of
natural language: verbs come before their objects.  It is thus natural
to write f(x), when in fact it is the object that should come first, not
the function.  Switching to a (natural) language where (finite) verbs
come at the end of sentences, where they belong, should fix this issue
in time.  Doing the same in a functional language would be ideal as
well, but might limit its use among those who speak inferior natural
languages.
  
Thanks, I must look into using postfix notation. It's used in Forth and 
Postscript and I seem to dimly recall that there is a natural language 
somewhere that also uses it but I can't remember which one.


Not only would it solve the infix/prefix dilemma, but it would also be 
consistent with a sugar for an object oriented syntax for application:


   a b c f
   a .f(b, c)

(Using a dot glued on its right and a left paren glued left to avoid 
ambiguity with unglued dot (function composition) and unglued left paren 
(unit/tuple/bracketing))


It's not so clear to me what the syntax for types should be in a postfix 
language.
Also, a problem might be that it is not so easy to use the 
multiple-clause style of function definition eg compare:


   map _ [] = []
   map f (h : t) = f h : map f t

with

   [] f map = []
   (h : t) f map = h f : t f map

since the function name is no longer conveniently at the margin of 
whatever layout block we are in so extra efforts would need to be made 
to line them up, though this is a minor issue.


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


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Ryan Ingram wrote:

My comments inlined below...

On 9/25/07, Brian Hulley [EMAIL PROTECTED] wrote:
  

  let
   shiftLeftByThree = shiftL' 3
  in
  map shiftLeftByThree  [10, 78, 99, 102]



let shiftLeftByThree = (`shiftL` 3) in ...

  
Aha! but this is using section syntax which is yet another complication. 
Hypothesis: section syntax would not be needed if the desugaring order 
was reversed.

Can anyone think of an example where the current desugaring of infix
arguments gives the correct order when the function is used in a postfix
application? (apart from commutative functions of course!)



A couple off the top of my head:

(:) :: a - [a] - [a]
  


Yes that's one that had totally slipped my mind ;-)

| :: MonadPlus m = m a - m a - m a
(how do you define correct in this case, anyways?)
  


I'm not so sure about this one eg:

first | second
(trychoice second) first

because (trychoice second) encapsulates what to do when its argument 
action fails.

Even for shift I can think of several reasons to want to use it both
ways; for example, unpacking a bitfield from a Word16:

unpack v = (getM 0 255, getM 8 1, getM 9 31, getM 14 3)
where getM = (..) . (shiftR v)

  
I suppose with some ops perhaps there is no most common way of wanting 
to use them and hence no one-true-way argument order for those ops.


Thanks for the examples,
Brian.
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Desugaring of infix operators is (always?) the wrong way round

2007-09-25 Thread Brian Hulley

Dan Piponi wrote:

On 9/25/07, Brian Hulley [EMAIL PROTECTED] wrote:

..I seem to dimly recall that there is a natural language
somewhere that also uses it but I can't remember which one.



Every permutation of [S,V,O] appears in 'nature':
http://en.wikipedia.org/wiki/Word_order.
  


Thanks for the link - I see [Subject, Object, Verb] is actually the most 
common word order.
  
Also, a problem might be that it is not so easy to use the 
multiple-clause style of function definition 


I disagree, it's easier with postfix functions. With prefix functions,
to get line-up you insert space in the middle of the line. With
postfix notation you would often insert space at the beginning of a
line, a much easier place to insert text, because there is a
keystroke, in most text editors, to take you to the beginning of a
line.

  


I don't understand what you mean. For example, with the prefix 
definition of a function with multiple clauses, the function name at the 
start of each clause is already lined up since it must appear at the 
margin of the current layout block (especially if you follow the simple 
rule of always following a layout starter token by a newline rather than 
starting a new multi-line layout block in the middle of a line), whereas 
with the postfix notation you'd need to manually line up the function 
names if you wanted the same neat look.



It's not so clear to me what the syntax for types should be in a postfix 
language.



Postfix, of course! So you'd write

data a Tree = Leaf | a a Tree
  


Sorry I meant what should the syntax of type declarations for functions 
be? For example, with prefix map (writing lists without sugar for 
clarity) we have:


   map :: (a - b) - List a - List b
   map _ Empty = Empty
   map f (PushF h t) = PushF (f h) (map f t)

The occurrence of map in the type decl lines up with the 2 occurrences 
of map in the clauses, and the types of the arguments are in the same 
order in the type as in the patterns in the clauses.


A postfix version could be:

   map :: (a - b) - a List - b List
   Empty _ map = Empty
   (h t PushF) f map = (h f) (t f map) PushF

but now the occurrences of map no longer line up and the argument 
order is reversed between the type and the value syntax.


Of course the problem disappears if you just discard multiple clause 
syntax and use:


  (list :: a List) (f :: a - b) map :: b List =
   case list of
   Empty - Empty
   h t PushF - (h f) (t f map) PushF


Confusingly, ocaml does something like this, with postfix notation for
types and prefix notation for function application.


I've never understood why {Oca, S}ML's creators decided to make life so 
difficult and confusing by introducing an arbitrary reversal between 
type and value syntax. ;-)


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


Re: Status of GHC runtime dependency on GNU multi precision arithmetic library

2007-08-16 Thread Brian Hulley

Stefan O'Rear wrote:

On Wed, Aug 15, 2007 at 06:41:53PM +0100, Brian Hulley wrote:
  
... I was 
wondering if there are any plans to remove the GNU mp library from the 
runtime

... http://hackage.haskell.org/trac/ghc/wiki/ReplacingGMPNotes
  

Thanks for the link.
... although the program 
includes code that is libre/gratis free the program is not itself free etc 
etc...



Huh? ...


I meant if you are distributing a proprietary program then you have the 
problem of trying to explain to an end-user all the intricacies involved 
with the LGPL without conveying the impression that the whole program is 
free. My impression is that someone who doesn't know anything about 
programming might have a hard time understanding the LGPL correctly.



Ian Lynagh wrote:

I'll be looking at making it optional once 6.8.1 is out of the way, but
you will need to use a GHC compiled with an alternative; you won't be
able to make a non-GMP program with a GMP GHC.
  

Thanks, that's good news.
Perhaps one option for the non-GMP version of GHC would be to have a 
large integer library written in Haskell itself, since it is useful to 
have large integers even if they are not as fast as those provided by 
GMP (eg when writing a lexer it is useful to have large integers to 
correctly lex integer literals (ie without silently truncating them to 
the capacity of an Int) but speed here is not that important).
To get high speed for stuff in external libs, perhaps some way of 
extending the foreign interface to allow direct access to the Haskell 
heap instead of always having to copy via the C heap, would be useful.



Duncan Coutts wrote:

Sounds to me like the simlest solution for you would be if GHC could use
a dynamically linked gmp.dll on Windows. That also sounds like much less
work that replacing gmp completely.
This would certainly make things easier though it doesn't solve every 
problem. For example, the LGPL requires you to give permission to people 
to reverse engineer your application, in order for them to be able to 
understand it enough to get it to work with an updated version of the 
LGPL component. Although this is perfectly reasonable imho, it leaves me 
with a problem if my application also needs to make use of eg Microsoft 
runtime components or third party proprietary statically linked 
libraries since there are parts of my program binary for which I do not 
have the authority to grant permission to reverse engineer thus it may 
not even be possible for me to comply with the terms of the LGPL.


Of course I am not a lawyer so I may have got this wrong, but since I 
can't possibly afford to hire a lawyer to look into all of this I have 
to play it safe and therefore would prefer to avoid any use of LGPL 
components in a proprietary app.


Thanks also to everyone else who replied,

Brian.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Status of GHC runtime dependency on GNU multi precision arithmetic library

2007-08-16 Thread Brian Hulley

Duncan Coutts wrote:

On Thu, 2007-08-16 at 14:22 +0100, Brian Hulley wrote:
.. For example, the LGPL requires you to give permission to people 
to reverse engineer your application... thus it may 
not even be possible for me to comply with the terms of the LGPL.



From the LGPL v3:

You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and
reverse engineering for debugging such modifications, if you
also do each of the following:
[list of stuff you have to do]

So it looks like you only have not restrict reverse engineering for the
purposes of making updated GMP libs work with your program. Since the MS
Runtime components do not interact directly with the GMP at all you
shouldn't need to grant users the right to reverse engineer those
components. Indeed it's only ghc library and rts code that would
interact with gmp.dll.
  


Thanks for suggesting that. It sounds reasonable though I tend to get a 
bit paranoid when it comes to legal things - will the FSF agree with the 
above interpretation etc.

BTW, I don't think it should be too hard to construct a notice that
indicates that portions of the work are covered by specific copyright
licences, the details of which are available. After all Microsoft have
dozens of these notices for various bits of BSD code they use and nobody
mistakes Windows for Free software.


True, but if there's any chance of just getting rid of the GMP 
altogether from a version of GHC there would be no tricky issues when it 
comes to distributing proprietary apps, thus potentially increasing 
GHC's user base, making Haskell more popular, and hopefully leading to 
more BSD3 libs being written by those new users... ;-)


Best regards, Brian.

___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Status of GHC runtime dependency on GNU multi precision arithmetic library

2007-08-15 Thread Brian Hulley

Hi,
I know this is a sensitive issue and I absolutely don't want to start 
any kind of discussion about the merits or otherwise of LGPL, but I was 
wondering if there are any plans to remove the GNU mp library from the 
runtime so that it would be possible to distribute native executables 
compiled with GHC without having to deal with the additional issues 
raised by the current inclusion of this LGPL component in the runtime. 
(Afaik everything else in ghc is under a BSD3 license.)


It's less of an issue on Linux where libgmp is dynamically linked but 
when thinking about using Haskell ghc for creating Windows apps it is 
for me a real problem, because it would mean I'd have to distribute the 
code for my app as a library along with the code as an executable, thus 
doubling the download size for my apps as well as having to include a 
license that has to explain to a possibly non-technical user that 
although the program includes code that is libre/gratis free the program 
is not itself free etc etc...


Regards, Brian.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


[Haskell-cafe] Syntax for lambda case proposal could be \of

2007-08-15 Thread Brian Hulley

Hi,
On http://hackage.haskell.org/trac/haskell-prime/wiki/LambdaCase the 
proposed syntax for lambda case is:


   case of
   alts

but this has a really bad downside for interactive editors: it doesn't 
allow one to distinguish between an incomplete construct and a completed 
construct thus removing one opportunity for an editor to alert the user 
(eg by highlighting) that there is something missing in the program text.


Therefore I propose:

   \of
   alts

which doesn't suffer this problem since the keyword of can never 
follow a '\' in the existing grammar.


However I can't edit the H' wiki, so if anyone agrees that the above 
syntax is better please could they add the above to the page.


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


Re: [Haskell-cafe] Syntax for lambda case proposal could be \of

2007-08-15 Thread Brian Hulley

Stefan O'Rear wrote:

On Wed, Aug 15, 2007 at 06:58:40PM +0100, Duncan Coutts wrote:
  

On Wed, 2007-08-15 at 10:50 -0700, Stefan O'Rear wrote:



OTOH, your proposal provides (IMO) much more natural syntax for
multi-pattern anonymous functions, especially if we stipulate that
unlike a case (but like a lambda) you can have multiple arguments; then
you could write stuff like:

sumTo0 = foldr (\of 0 k - 0
n k - n + k) 0
  

sumTo0 = foldr (\0 k - 0
 n k - n + k) 0



foo = getSomethingCPS $ \ arg -
  moreStuff

is now a syntax error (\ { varid - } matches no productions).
  

A multi-way lambda could be introduced using \\ thus:

sumTo0 = foldr (\\ 0 k - 0; n k - n + k) 0

[from a previous post]

It's not like the current language has that property; consider (map
myFunction) - is that an error or a partial application?


By construct I meant only those grammatical elements involving keywords, and 
was thinking about situations where you might for example have various syntax templates 
bound to function keys eg in Haskell the following are incomplete:

  case of
  if then else
  data where deriving

(let in could still be marked as incomplete even if it is ok according to the 
grammar since it would be weird to bother writing a let with no bindings.)

There is a similar problem with the way template haskell uses unmatched quotes 
such as 'a so it's no longer possible to determine whether this should be 
marked as an incomplete character literal or a complete TH name.

I suppose my main point is that it's useful for a syntax to have plenty of unfilled 
gaps that result in an error when written rather than filling all those gaps with 
different meanings...

Brian.

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


Re: [Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions

2007-08-13 Thread Brian Hulley

Brian Hulley wrote:

apfelmus wrote:

Brian Hulley schrieb:

   main = do
   buffer - createBuffer
   edit1 - createEdit buffer
   edit2 - createEdit buffer
   splitter - createSplitter (wrapWidget edit1) (wrapWidget 
edit2)

   runMessageLoopWith splitter

... Thus the ability to abstract mutable state gives to my mind by 
far the best solution.


I'm not sure whether mutable state is the real goodie here. I think 
it's the ability to indpendently access parts of a compound state.

  http://www.st.cs.ru.nl/papers/2005/eves2005-FFormsIFL04.pdf


This is indeed a real key to the problem.

Of course this is only one aspect of the problem...

Thinking about this a bit more, and just so this thought is recorded for 
posterity (!) and for the benefit of anyone now or in a few hundred 
years time, trying to solve Fermat's last GUI, the object oriented 
solution allows the buffer object to do anything it wants, so that it 
could negotiate a network connection and implement the interface based 
on a shared network buffer for example, without needing any changes to 
the client code above, so a functional gui would need to have the same 
flexibility to compete with the OO solution.


Another thing that would be interesting would be to have a formal 
treatment of what is supposed to happen in a gui. For example, when you 
move the mouse over a control which has become dirty (ie needs to be 
re-rendered because its state is now inconsistent), what should the 
control do? Should it respond as if the new state were already visible 
to the user, or should it interpret the mouse position according to the 
last state that was rendered, or should it just ignore all mouse events 
until the next time it gets rendered? This is not a trivial question 
because you could imagine an animated control where the user might 
naturally be following the movement, whereas when the user clicks on a 
cell in a spreadsheet when the cells to the left have now expanded due 
to a change in data thus moving the cell along (but where this updated 
model has not yet been re-rendered) the user might be irritated at the 
wrong cell being selected... It's tricky little issues like this that I 
haven't found any documentation for anywhere, and which would make a 
proper mathematical treatment of interaction with a gui very useful, 
regardless of whether it is implemented in OOP or functional style.


Anyway just a thought,

Brian.


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


Re: [Haskell-cafe] Re: Language support for imperative code. Was: Re: monad subexpressions

2007-08-12 Thread Brian Hulley

apfelmus wrote:

Brian Hulley schrieb:

   main = do
   buffer - createBuffer
   edit1 - createEdit buffer
   edit2 - createEdit buffer
   splitter - createSplitter (wrapWidget edit1) (wrapWidget 
edit2)

   runMessageLoopWith splitter

... Thus the ability to abstract mutable state gives to my mind by 
far the best solution.


I'm not sure whether mutable state is the real goodie here. I think 
it's the ability to indpendently access parts of a compound state. In 
other words, the IORef created by  buffer  is a part of the total 
program state but you can access it independently. There is a 
functional idiom for that, see also


  Sander Evers, Peter Achten, and Jan Kuper. A Functional Programming
  Technique for Forms in Graphical User Interfaces.
  http://www.st.cs.ru.nl/papers/2005/eves2005-FFormsIFL04.pdf


Thanks for this reference. This is indeed a real key to the problem. 
(Though a possible downside with compositional references might be 
efficiency as the modified sub-state needs to be injected back into a 
new composite state but perhaps the solution here would be to have 
uniqueness typing as in Clean so that these injections could hopefully 
be erased at compile time.)


I think one of the issues with Haskell is that there are so many 
features to choose from it is difficult to know how to approach a 
problem eg for streams you can have


1) A lazy list
2) A typeclass with get and pushBack methods
3) An object using an existential to wrap (2)
4) A record containing get and pushBack methods
5) A monad with get and pushBack actions
6) A simple function wrapped in a newtype:

 newtype Stream a = Stream (() - Maybe (a, Stream a))

and I tend to only discover a simple solution like (6) (which works 
equally well for both strict and lazy languages) after spending an 
enormous amount of time on 1,2,3,4,5... ;-)


- For Graphics, I want to build a graphic from smaller ones and then 
draw it. I don't want to know how drawing is implemented and what 
mutable state might be involved.
- For a GUI, I want to write down the data dependencies and a library 
converts this to a mesh of mutable state.


That's what I mean with higher level functional model.
I agree this would be ideal. A challenge I don't yet know how to solve, 
when dealing with 3d graphics, is that it seems that for efficiency it 
is necessary to consider a mesh of triangles to be an object with 
identity in order to be able to display an updated mesh (eg as the user 
drags a vertex with the mouse) in real time. This is because the 
representation of a mesh is constrained by the low level details of the 
graphics system eg vertices might need to be represented by a contiguous 
array of unboxed positions and normals, and triangles by a contiguous 
array of vertex indices, and it is too expensive to copy these arrays on 
each frame. Perhaps though this is another case where some form of 
uniqueness typing as in Clean could come to the rescue so one could write:


   createMesh :: [Vertex] - [[VertIndex]] - Mesh
   moveVertex :: Vertex - *Mesh - *Mesh

instead of

   createMesh :: [Vertex] - [[VertIndex]] - IO Mesh
   moveVertex :: Vertex - Mesh - IO ()

Best regards, Brian.

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


[Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

apfelmus wrote:

However, most genuinely imperative things are often just a building
block for a higher level functional model. The ByteString library is a
good example: the interface is purely functional, the internals are
explicit memory control. It's a bad idea to let the internal memory
control leak out and pollute an otherwise purely functional program with
IO-types.
  

Hi Apfelmus,

This is a really interesting discussion that touches on issues I'm 
currently working with (I'm designing a strict version of Haskell to 
explore various ideas about modules, namespace management, and how to 
get really efficient machine code but without losing the convenience of 
accurate garbage collection etc, but I'm having difficulties deciding 
between the monadic path and the impure path), so I've forked this new 
thread.


Regarding the quote above, if the API must hide explicit memory control 
from the user the only way I can see of doing this would be to use 
(unsafePerformIO), which really is unsafe since Haskell relies on the 
fact that mutable operations can't escape from the IO monad in order to 
get away with not having to impose a value restriction as in ML.


If you don't use (unsafePerformIO), then the slightest need for mutable 
data structures pollutes the entire interface. For example in the 
excellent paper you quoted


 N. Ramsey and J. Dias.
 An Applicative Control-Flow Graph Based on Huet's Zipper
 http://www.eecs.harvard.edu/~nr/pubs/zipcfg-abstract.html 
http://www.eecs.harvard.edu/%7Enr/pubs/zipcfg-abstract.html


the authors are pleased to have found an Applicative solution, and 
indeed their solution has many useful and instructive aspects. However 
on page 111, hidden away in the definition of their API function to 
create a label, is a call to (ref 0)  ;-) The equivalent 
implementation in Haskell would completely destroy all hope of using 
this in a pure context and force all use of the API into the IO monad.


Haskell and ML seem to stand at opposite poles. Haskell is designed so 
that any attempt at abstracting mutable local state will infect the 
entire program (modulo use of a highly dangerous function whose 
semantics is entirely unclear, depending on the vagaries of evaluation 
strategy of the particular compiler) whereas people have been struggling 
in the ML community for at least 15 years to try and find a way to hide 
the fact that mutable storage is being used (cf attempts to find a 
proper solution to the unsoundness introduced by polymorphism and ref 
without having to use imperative/weak type variables etc).


Meanwhile, C++, C#, and Java programmers get a type system (thinking 
only about static methods using generics/templates) that seems to me no 
less powerful than that of the prenex polymorphism of ML, yet without 
any of the unsoundness problems, and therefore without the need of a 
value restriction (afaiu this is because their template/generic 
definitions stand in for an infinite family of monomorphic bindings 
instead of ML which tries unsuccessfully to make one piece of memory 
represent each element of an infinite family of values simultaneously).


Not only this, but there seems to me to be many problems for which it is 
natural to think in terms of objects with identity and mutable state. I 
can readily discard the concepts of deep inheritance hierarchies and 
open recursion but this still leaves the problem of identity and 
localised mutability.


For example consider a simple GUI with 2 edit widgets, a splitter, and a 
single buffer that contains the text being edited. The idea is that you 
should be able to use either edit widget to interact with the same 
buffer eg to edit at different locations in the buffer. A simple 
imperative solution might be something like:


   main = do
   buffer - createBuffer
   edit1 - createEdit buffer
   edit2 - createEdit buffer
   splitter - createSplitter (wrapWidget edit1) (wrapWidget edit2)
   runMessageLoopWith splitter

Here it's really clear what's happening, and different objects in the 
program correspond exactly to how I think about what I'm trying to do ie 
I want to  create individual objects with identity and then plug them 
together. I don't want to have to bother about passing state around, or 
having to define a new data type every time I want a different 
configuration of widgets. Thus the ability to abstract mutable state 
gives to my mind by far the best solution.


In contrast, all the pure functional GUIs that I've seen are just 
wrappers around someone else's imperative code, and moreover, they 
exchange the simplicity of the object oriented imperative API for a 
veritable mindstorm of unbelievably heavy, clunky, slow, inefficient, 
inextensible, hard to understand encodings that seem to me to have the 
effect of turning a high level language into some kind of circuit board 
(I'm thinking of arrows etc).


Indeed everyone seems to be using either WxWidgets or 

Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

Martin Percossi wrote:

Brian Hulley wrote:

hidden away in the definition of their API function to create a 
label, is a call to (ref 0)  ;-) The equivalent implementation in 
Haskell would completely destroy all hope of using this in a pure 
context and force all use of the API into the IO monad.


Really? I would have thought this is a job for the ST monad, in which 
case the API can be wrapped up in a runST or similar; no need for 
leaking IO monads.


Or am I missing something?


Well I agree you're right on this particular use of a Ref, since their 
program is only dealing with a mapping from input to output so once 
they're finished using the data structure there is no longer any need 
for the ref and so the result can be returned to the rest of the program.


However there are 2 problems with this approach in general afaics:

1) All code that uses this data structure ie that participates in the 
implementation of the transformations by using the API functions will 
have to be in a monad (ST or IO, it really doesn't matter in terms of 
all the perceived burdensomeness of do notation relative to normal 
applicative code).


2) The example doesn't transfer to an interactive situation, where we 
would need to keep the data structure around and use it forever - 
because we would be forever trapped inside the ST monad otherwise we'd 
lose that particular STRef which we were hoping to use to efficiently 
update the output in the face of a delta in the input.




Corey -
I found this page helpful to get an understanding of the value 
restriction in ML:


http://www.smlnj.org/doc/Conversion/types.html

The restriction was proposed by Andrew Wright in 1995:

Simple Imperative Polymorphism by Wright
http://citeseer.ist.psu.edu/wright95simple.html

Some other related papers are:

The Type and effect discipline by Talpin and Jouvelot 1992
Standard ML-NJ weak polymorphism and imperative constructs by Hoang, 
Mitchell, and Viswanathan

Weak polymorphism can be sound by Greiner 1993

and more recently (2003)

Relaxing the value restriction by Garrigue
http://citeseer.ist.psu.edu/garrigue03relaxing.html

(Note that even now there is still no real solution to it.)


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


Re: [Haskell-cafe] Language support for imperative code. Was: Re: monad subexpressions

2007-08-08 Thread Brian Hulley

Hugh Perkins wrote:
On 8/8/07, *Brian Hulley* [EMAIL PROTECTED] 
mailto:[EMAIL PROTECTED] wrote:


In contrast, all the pure functional GUIs that I've seen...

In defense of Haskell (wow!), note that imperative languages are not 
without problems in GUIs.  In a multithreaded environment,
If you're using multiple threads you'd need to be in the IO monad to 
create/manipulate the MVars or TVars or whatever. (In contrast to eg 
AliceML where you could easily use a synchronising logic variable 
without having to leave all the familiar applicative coding comforts 
behind to brave the fiercesome lonely toil of Monadia ;-))


typically only one thread is allowed to manage the GUI, and then you 
typically need to set up some sort of message-passing system to 
communicate between this thread and the others AFAIK?  This is a total 
PITA, so if someone has a solution for this that would rock :-)
 
Question: to what extent do the Haskell wrappers around gtk and 
wxWidgets suffer from this problem?  I mean, I havent tried them, so 
it's a genuine question.
I don't know though I seem to recall some info on this on the website of 
Gtk2Hs.


 
(Note: off the top of my head, in an imperative language, I guess one 
could use some sort of generator to take an interface and generate the 
message classes, and marshalling classes automatically)
 
(Disclaimer: I havent really searched very hard for ways to handle 
threading in GUIs in imperative languages, since mostly I either use 
web pages as the visual interface, which avoids around the problem, or 
use a single thread, which also avoids the problem)


So far I've always managed to get away with just using a single threaded 
GUI. I think you run into problems with XLib and OpenGL (on GNU/Linux at 
least) if you try to call into those APIs from multiple threads and also 
it seems better to separate concerns by having all rendering code, 
including cacheing of geometry etc, in the same thread since it's easy 
enough to spawn new threads to do calculations and set a flag in the 
relevant widget when the result is complete...


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


Re: [Haskell-cafe] a regressive view of support for imperative programming in Haskell

2007-08-08 Thread Brian Hulley

Paul Hudak wrote:
All of the recent talk of support for imperative programming in 
Haskell makes me really nervous


... if we give imperative programmers the tools to do all the things 
they are used to doing in C++, then we will be depriving them of the 
joys of programming in the Functional Way.  How many times have we 
seen responses to newbie posts along the lines of, That's how you'd 
do it in C++, but in Haskell here's a better way
Perhaps I may have sounded unappreciative of all the hard work that's 
been done trying to find solutions to the problem of GUI programming in 
a pure functional style. I think the problem is that for the purposes of 
research, it is sufficient to show that a concept can be implemented but 
the speed of the resulting program is not that important compared to the 
essential ideas.


Thus the concept of a GUI as a time varying continuous function of 
events and response pictures (represented as functions:: Vector3 Float 
- RGB) is tremendously appealing, and will surely become the standard 
way when machines get fast enough, but for the moment this nice pure 
functional way just doesn't seem directly applicable (;-)).


I see the problem you're pointing to though - that the language could 
become caught in the middle trying to serve two rather different 
purposes namely a pure ground for research and a fast general purpose 
platform for creating programs now. As for me, the issue is just that 
after spending almost 2 years with Haskell trying to find/discover a 
purely functional solution to this problem that will be suitable for a 
practical high speed graphics application on standard hardware, being 
unsuccessful, and not having any funding to pursue this research 
further, my only option is to either use the imperative monadic style of 
Haskell programming or to use OCaml or C++, because I need to get 
something written right now that I can put on my website to sell...


Personally I don't find the existing do notation all that burdensome - 
I've got used to it, and even though each action must be explicitly 
written, the ease with which higher order functions can be introduced to 
factor out commonality means that the do blocks are often shorter than 
the corresponding C++ code from my previous GUI.


Furthermore, even though I'm using the imperative style, the use of 
Haskell has led me to surprisingly neat solutions to several problems 
that I didn't discover when I implemented the previous versions in C++ 
and C#, so I think there are still great benefits to be had from using 
Haskell or languages inspired by it.


Best regards, Brian.





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


Re: [Haskell-cafe] Newbie question: multi-methods in Haskell

2007-08-06 Thread Brian Hulley

peterv wrote:

In de book Modern C++ design, Andrei Alexandrescu writes that Haskell
supports “multi-methods”



Using multi-methods, I could write (in pseudo code)
collide (Asteroid, Planet) = an asteroid hit a planet
collide (Asteroid, Earth) = the end of the dinos
...
collide (Planet, Asteroid) = collide (Asteroid, Planet)
collide (Earth, Asteroid)  = collide (Earth, Asteroid)


Hi, In Haskell you can use multi parameter type classes to solve this 
problem:


{-# OPTIONS_GHC -fglasgow-exts
   -fallow-undecidable-instances
   -fallow-overlapping-instances #-}

module Collide where

class Collide a b where
   collide :: (a,b) - String

data Solid = Solid
data Asteroid = Asteroid
data Planet = Planet
data Jupiter = Jupiter
data Earth = Earth

instance Collide Asteroid Planet where
   collide (Asteroid, Planet) = an asteroid hit a planet

instance Collide Asteroid Earth where
   collide (Asteroid, Earth) = the end of the dinos

-- Needs overlapping and undecidable instances
instance Collide a b = Collide b a where
   collide (a,b) = collide (b, a)

-- ghci output
*Collide collide (Asteroid, Earth)
the end of the dinos
*Collide collide (Earth, Asteroid)
the end of the dinos

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


Re: [Haskell-cafe] Newbie question: multi-methods in Haskell

2007-08-06 Thread Brian Hulley

Dan Weston wrote:
Remember that type classes do not provide object-oriented 
functionality. The dispatch is static, not dynamic. Although OOP can 
be simulated in Haskell, it is not a natural idiom. If you need 
dynamic dispatch (including multiple dispatch), you may want to 
reconsider your solution.
Dynamic dispatch is easily added to Haskell code by using an existential 
to represent any collision:


{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances 
-fallow-overlapping-instances #-}


module Collide where

-- Changed to a single param to make life easier...
class Collide a where
   collide :: a - String

data Solid = Solid
data Asteroid = Asteroid
data Planet = Planet
data Jupiter = Jupiter
data Earth = Earth

instance Collide (Asteroid, Planet) where
   collide (Asteroid, Planet) = an asteroid hit a planet

instance Collide (Asteroid, Earth) where
   collide (Asteroid, Earth) = the end of the dinos

-- Needs overlapping and undecidable instances
instance Collide (a, b) = Collide (b, a) where
   collide (a,b) = collide (b, a)

-- This is how you get dynamic dispatch in Haskell
data Collision = forall a. Collide a = Collision a

instance Collide Collision where
   collide (Collision a) = collide a

-- ghci output
*Collide let ae = Collision (Asteroid, Earth)
*Collide let pa = Collision (Planet, Asteroid)
*Collide collide ae
the end of the dinos
*Collide collide pa
an asteroid hit a planet
*Collide map collide [ae, pa]
[the end of the dinos,an asteroid hit a planet]


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


Re: [Haskell-cafe] Newbie question: multi-methods in Haskell

2007-08-06 Thread Brian Hulley

peterv wrote:

This is very nice, but it does not really solve the original problem.
  
To get Haskell to choose the best fit it's necessary to encode the 
location of each element in the hierarchy, so that elements deeper in 
the hierarchy are more instantiated than those at the top. Then instance 
selection chooses the best fit by just choosing the most instantiated match.


Encoding can be done using phantom types, so a generic solid has the path

IsSolid s

a planet has

IsSolid (IsPlanet p)

and a specific planet eg Earth has path

IsSolid (IsPlanet Earth)

A newtype can be used to associate the path with the actual object:

newtype InH path body = InH body

so Earth is represented by

InH Earth :: InH (IsSolid (IsPlanet Earth)) Earth

A class with a functional dependency gives us the mapping between 
concrete objects and the objects as viewed by the hierarchy:


class ToH body path | body - path where
toH :: body - InH path body
toH = InH

The functional dependency means that the path (location in the 
hierarchy) is uniquely determined by the body, and instance decls then 
define this relationship:



instance ToH Asteroid (IsSolid Asteroid)
instance ToH Jupiter (IsSolid (IsPlanet Jupiter))
instance ToH Earth (IsSolid (IsPlanet Earth))


The code is below but as you can see the OOP encoding in Haskell becomes 
quite heavy and clunky so this style is probably not ideal for a real 
program - Tillmann's suggestion to use algebraic datatypes instead is 
more idiomatic - but anyway here goes:


{-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances
-fallow-overlapping-instances #-}

module Collide where

class Collide a where
collide :: a - String

data Asteroid = Asteroid
data Jupiter = Jupiter
data Earth = Earth


data IsSolid a
data IsPlanet a

newtype InH path body = InH body

class ToH body path | body - path where
toH :: body - InH path body
toH = InH

instance ToH Asteroid (IsSolid Asteroid)
instance ToH Jupiter (IsSolid (IsPlanet Jupiter))
instance ToH Earth (IsSolid (IsPlanet Earth))


data Collision = forall a. Collide a = Collision a

mkCollision
:: (ToH a pa, ToH b pb, Collide (InH pa a, InH pb b))
= a - b - Collision
mkCollision a b = Collision (toH a, toH b)


instance Collide (InH (IsSolid a) aa, InH (IsSolid b) bb) where
collide _ = generic collision

instance Collide (InH (IsSolid Asteroid) Asteroid, InH (IsSolid 
(IsPlanet bb)) cc) where

collide _ = an asteroid hit a planet

instance Collide (InH (IsSolid (IsPlanet a)) aa, InH (IsSolid Asteroid) 
Asteroid) where

collide _ = an asteroid hit a planet

instance Collide (InH (IsSolid Asteroid) Asteroid, InH (IsSolid 
(IsPlanet Earth)) Earth) where

collide _ = the end of the dinos

instance Collide (InH (IsSolid (IsPlanet Earth)) Earth, InH (IsSolid 
Asteroid) Asteroid) where

collide _ = the end of the dinos

instance Collide Collision where
collide (Collision a) = collide a

--- ghci output

*Collide mapM_ putStrLn (map collide
[ mkCollision Asteroid Earth
, mkCollision Earth Asteroid
, mkCollision Jupiter Asteroid
, mkCollision Asteroid Jupiter
, mkCollision Asteroid Asteroid
])
the end of the dinos
the end of the dinos
an asteroid hit a planet
an asteroid hit a planet
generic collision
*Collide

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


[Haskell-cafe] Re: monad subexpressions

2007-08-05 Thread Brian Hulley

On Fri Aug 3 06:06:31 EDT Neil Mitchell wrote:
 What are the semantics of
  do b  f (- a)
 where does the evaluation of a get lifted to?

I suggest the execution of (a) should be done immediately before the 
action obtained by applying the monadic function whose argument it is 
part of:


  do b  ( a = \ra - f ra)

Similarly, I'd desugar

  if (- a) then f (- b) else g (- c)

to

  a = \ra - if ra then (b = \rb - f rb) else (c = \rc - g rc)

I think it would just be confusing to have to think about lines in the 
do block since do blocks are just syntactic sugar. The only possible 
thing that might be needed by the do block is to define what monad the 
action should be evaluated in.


Perhaps the rule could be that if (- a) occurs in some expression the 
compiler should search for the nearest enclosing do block to identify 
which monad (a) should be evaluated in, then should again search 
outwards from the expression (- a) to find the nearest enclosing 
expression (mexp) which yields a result in that same monad, then desugar 
to (a = \ra - mexp') where mexp' is obtained from mexp by replacing 
that occurrence of (- a) by (ra). (Evaluations would be done in the 
same order as depth first traversal of their occurrences in mexp)


Regarding objections by others about (- a) being confused with a 
section, (-) is not a valid operator therefore it can't be part of a 
section so no confusion should arise imho...


Best regards, Brian.



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


[Haskell-cafe] Using Haskell to investigate ML's value restriction

2007-07-18 Thread Brian Hulley

Hi,
Ii is interesting that in ML, the presence of mutable ref cells and 
parametric polymorphism requires the whole language to be dominated by a 
value restriction [1] to ensure that the type system remains sound, 
whereas in Haskell, because IORef's can only be created (and used) in 
the IO monad, no such restriction is necessary.


I've often wondered why such a simple thing as using a monad has this 
magical effect, especially since it seems to me that the real problem 
lies in the fact that type variables in HMD type inference are not 
generalised properly due to the absence of an explicit representation of 
the quantifier, so I decided to try using Haskell's more modern type 
system to investigate further, using the IO monad together with 
(unsafePerformIO) and (evaluate) to simulate the execution of an ML program:


{-# OPTIONS_GHC -fglasgow-exts #-}
module Test where

import Data.IORef
import System.IO.Unsafe (unsafePerformIO)
import Control.Exception (evaluate)

ref v = unsafePerformIO $ newIORef v

put r f = unsafePerformIO $ writeIORef r f

get r = unsafePerformIO $ readIORef r

-- Gives a core dump as expected
test1 :: IO ()
test1 = do
   let r  = ref (\x - x)
   evaluate (put r (\x - x + 1))
   evaluate (get r True)
   return ()

(test1) is based on one of the ML examples in [1], and when executed, 
causes a segmentation fault. The reason seems to be the strange type 
that is assigned to (r):

*Test let r = ref (\x - x)
*Test :t r
r :: forall t. IORef (t - t)
*Test

(To run this you need to use ghci -fglasgow-exts Test.hs to get ghci 
6.6.1 to display the quantifier.)


What's strange (to me) about the above typing is that the forall has 
moved outside the IORef constructor. In other words, although we 
supplied the constructor with a function which can operate on any value, 
we got back something which, for any value, contains a function which 
can operate on it.


The reason afaics that (test1) goes wrong is that the let binding causes 
(r) to be bound to the type above, so the argument matches both


   forall a. Num a = a - a

and

   Bool - Bool

so the action (evaluate (get r True)) tries to apply a function which 
expects a number to a Bool.


However if we add an explicit type to (r) to get (what I see as) the 
expected quantification, the type checker correctly rejects the program:


test2 :: IO ()
test2 = do
   let r :: IORef (forall a. a - a) = ref (\x - x)
   evaluate (put r (\x - x + 1))
   evaluate (get r True)
   return ()

no instance for Num a ...

which might seem like a reason not quite related to our chain of thought 
so I also tested this using:


test3 :: IO ()
test3 = do
   let r :: IORef (forall a. a - a) = ref (\x - x)
   evaluate (put r (\'c' - 'c'))
   evaluate (get r True)
   return ()

which gives couldn't match expected type `a' (a rigid variable) against 
inferred type `Char'. In other words, the IORef must always contain a 
function that works with anything - we can't just give it a more 
specialized function, so the program is rejected for the reasons we expect.


Interestingly, even without type annotations, if we use a case instead 
of a let, the typechecker also rejects the program:


test4 :: IO ()
test4 =
   case ref (\x - x) of
   r - do
   evaluate (put r (\'c' - 'c'))
   evaluate (get r True)
   return ()

this time by noting that (Bool - t) does not match (Char - Char). This 
illustrates (afaiu) that case does not introduce any quantification, 
in contrast to let hence the uninstantiated meta-tyvars of r have to 
unify with both its uses.


In conclusion, it seems that the magic given by always having to use 
IORef's inside the IO monad (without unsafePerformIO of course) is due 
to the fact that when used this way types involving IORefs never get 
generalized wrongly since they're never created by a let binding.


Another conclusion is that if we wanted at some point to have another 
new strict language with Haskell's nice type system and syntax as an 
alternative to the ML family, and we also wanted to have references (and 
continuations), then either the rule for generalizing the meta-type 
variables in a let binding would have to be changed or else we would 
still have to use monads.


I'd be interested to know if the use of impredicative types would 
automatically solve the wierd quantification problem, since:


*Test :t ref
ref :: forall a. a - IORef a

therefore applying this to an argument of type (forall b. b - b) should 
hopefully give a result of type (IORef (forall b. b - b)), thus the use 
of impredicative types might allow such a strict variant of Haskell to 
use side-effects instead of monads while still retaining type soundness... ?


Best regards,
Brian.

[1] http://www.smlnj.org/doc/Conversion/types.html
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: haskell's prefix exprs

2007-07-10 Thread Brian Hulley

Christian Maeder wrote:

Hi,

I would like haskell to accept the following (currently illegal)
expressions as syntactically valid prefix applications:

f = id \ _ - []
g = id let x = [] in x
h = id case [] of [] - []
i = id do []
j = id if True then [] else []

The rational is that expressions starting with a keyword should extend
as far as possible (to the right and over several lines within their
layout).
  

On page 15/16 of the H98 report I think this could be achieved by:

exp10 ::= fexp

fexp ::= [fexp] keyexp

keyexp ::= \ apat ... - exp | let ... | ... | aexp


(In fact, maybe for haskell' $ could be changed to a keyword.)
  


Alternatively the # symbol could be removed from the pool of symbol 
chars and used to construct syntactic sugar so you could use


 f = id #$ \_ - []

to mean exactly

 f = id (\_ - [])

I think when the idea of $ arose originally people didn't at that time 
know about the many cases where the use of $ is not semantically 
equivalent to explict brackets, since this knowledge probably only arose 
later with the introduction of rank-n polymorphism. (Of course the need 
for #$ would be fixed with impredicative types as in MLF.)


Best regards,
Brian.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: 64-bit windows version? (Haskell is a scripting language too!)

2007-06-21 Thread Brian Hulley

skaller wrote:

The key thing for the building portability is that the C and C++
compilers are represented by Python classes. There is a pre-programmed
class for gcc, and another for MSVC++.
  
I suggest (for GHC) a Haskell class with instances for the different 
combinations of

compilers and platforms and optimization levels.

(a) Pick a portable scripting language which is readily available
on all platforms. I chose Python. Perl would also do.
If I had time to look into improving the GHC build system I'd definitely 
use Haskell as the scripting language. What's the point of having to 
learn more than one language to accomplish a task? Surely it is more 
productive to add functionality to a single language (especially when 
it's only a case of writing some libraries) rather than grappling with 
the different syntaxes and limitations and quirks of a multitude of 
languages/tools and the problems of trying to get them all to work 
harmoniously together on different platforms?


In concrete terms, for each sub-project within GHC ie each directory of 
source files I'd have a little Haskell program that was responsible for 
building that sub-project. Kind of like CM.make or the ML Basis system, 
except with the full power of Haskell so that complicated things such as 
building successive boot levels could easily be automated. (Ie instead 
of having a special tool like make that is invoked on dead data 
(supplied by autoconf etc) to drive the build process, instead use 
Haskell as a scripting language.)


The top level build would be done by another Haskell program which 
delegated responsibility to the sub-programs in each directory.


I'd include the complete source code for all the Haskell tools like Alex 
and Happy so they could be built the same way.


In other words, the entire GHC project would be built by running a 
single Haskell program, and every single piece of source would either be 
a Haskell module or a file that is the input to a Haskell program that 
the main build-driver has built first (from Haskell sources). Therefore 
there would be no dependency on anything except GHC itself.


To port GHC to a completely new platform, you'd of course need a Haskell 
compiler or interpreter already. However to bootstrap the process only a 
slow interpreter would be needed so as long as a portable pre-built 
bytecode version was available for download the only thing left to port 
would be a byte code interpreter which could just be a single file of c 
code.


Perhaps this is too long-term a vision for solving the short term 
problems, but maybe it could be the basis of some future projects?


Best regards,

Brian.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Why do we have stack overflows?

2007-05-07 Thread Brian Hulley

Brandon Michael Moore wrote:

On Thu, May 03, 2007 at 04:59:58PM -0700, John Meacham wrote:
  

I believe it is because a stack cannot be garbage collected, and must be
traversed as roots for every garbage collection. I don't think there are
any issues with a huge stack per se, but it does not play nice with
garbage collection so may hurt your performance and memory usage in
unforeseen ways.



Isn't it just the top of the stack that has to be treadted as a root?
  
No, because the functions below the top are still active and would 
usually be referencing other heap locations not visible to the top function.


On another note, why use stacks in the first place? Couldn't all 
activation  records just be heap allocated?


Regards, Brian.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: GHC 6.6.1 Windows installer, test version

2007-05-07 Thread Brian Hulley

Neil Mitchell wrote:

Hi,

I've prepared a GHC 6.6.1 Windows installer. Before I offer this up as
an official installer, could people please test it?

http://www.haskell.org/ghc/dist/6.6.1/ghc-6.6.1-i386-windows-test1.exe

Thanks Neil,
This works perfectly!

Best regards, Brian.
___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Trouble trying to find packages for ubuntu linux

2007-03-16 Thread Brian Hulley
Thanks to everyone for sending me info on how to install ghc6.6 on
Ubuntu. The way I used eventually was one sent to me off list and uses
the generic i86 linux at
http://www.haskell.org/ghc/download_ghc_66.html#x86linux

The exact steps I used after downloading the tarball at the above URL to
my Desktop were:

~$ mkdir ghc-6.6
~$ mkdir tarball
~$ mv Desktop/ghc-6.6-i386-unknown-linux.tar.bz2 tarball
~$ cd tarball
~/tarball$ tar -jxvf ghc-6.6-i386-unknown-linux.tar.bz2
~/tarball$ sudo apt-get install libreadline4 libncurses5
~/tarball$ cd ghc-6.6
~/tarball/ghc-6.6$ ./configure --prefix=$HOME/ghc-6.6
~/tarball/ghc-6.6$ make install
~/tarball/ghc-6.6$ cd ../..
~$ gedit .bashrc

and added $HOME/ghc-6.6/bin to my PATH (must be no spaces in the line
below):

  export PATH=$HOME/ghc-6.6/bin:$PATH

Then closed the terminal and opened a new terminal and lo! ghc, ghci,
and many libraries are now available! :-)

Thanks again for the other suggestions also - I chose the above method
just because it will allow me to easily try out different versions of
ghc in future while still being able to keep the 6.6 version around just
by changing my PATH to whatever version I want to use.

Best regards, Brian.


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Problem exporting Haskell to C via a DLL in GHC 6.6

2007-02-08 Thread Brian Hulley

Simon Peyton-Jones wrote:

I don't think there is any reason in principle why GHC can't generate
DLLs that just work, but plainly it's deficient at the moment.


The fundamental reason is that the DLL mechanism itself doesn't allow 
initialization/ shutdown do be hidden from the user of a DLL, because the 
order of loading/unloading DLLs is unspecified by the MS Windows operating 
system. Therefore it's not a GHC problem - it's just a fact of life with 
DLLs...



The other thing is that we could do with more how to documentation
about GHC and DLLs.  We have a bit here:
http://haskell.org/haskellwiki/GHC/Using_the_FFI
Could you expand it in the light of your experience?


I've added a section 
http://haskell.org/haskellwiki/GHC/Using_the_FFI#Beware_of_DllMain.28.29.21 
which attempts to explain why init/exit code can't be put in DllMain, as 
well as an *untested* example to show what I meant by putting init/exit code 
in Begin/End functions instead.


I've put a note next to the example to say that it's untested, and to appeal 
to anyone with more knowledge of static linking between Haskell and C to fix 
anything I've missed or replace with a better example. (Apologies for not 
testing it but static linking to stubs generated by GHC seems to require the 
DLL to be compiled by gcc and use of gcc on Windows seems to require Cygwin 
since gcc doesn't seem to understand Windows paths and I don't have Cygwin 
installed - unfortunately at the moment I don't have time to pursue this 
further.)


Best regards, Brian.
--
http://www.metamilk.com 


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Problem exporting Haskell to C via a DLL in GHC 6.6

2007-02-06 Thread Brian Hulley

SevenThunders wrote:

Brian Hulley wrote:

SevenThunders wrote:

DllMain
 if (reason == DLL_PROCESS_DETACH) {
   shutdownHaskell();
   return TRUE;
 }

The above *may* be the problem: it is unsafe to do anything in
DllMain that...

Instead of trying to start/shutdown Haskell from DllMain, I'd export
a Begin() and End() function from the DLL and explicitly call these
from your application's main().


So in your scheme the Begin() would call the startupHaskell function
and the End() call the shutdown Haskell?


Yes.


Or would the Begin initiate
the linking to the specific DLL using LoadLibrary?


Since Begin would be a function exported by the DLL, Windows would ensure 
that the DLL was loaded when it is first called from your application if it 
was not already loaded so there would be no need for an explicit call to 
LoadLibrary.



and then End
specifically unload the library; or both?


I wouldn't bother explicitly unloading the library - I'd leave this up to 
Windows. The importance of using an End function is that you can ensure that 
the call to shutdown Haskell happens at a time when all DLLs needed by 
Haskell are still available, whereas using DllMain to do the shutdown call 
is dangerous because DllMain may be invoked when some DLL necessary for 
Haskell to shutdown has already been unloaded by Windows.


Ideally there would also be some way to call Begin/End when using the DLL 
from Matlab but I don't know anything about Matlab so can't help with this. 
A quick hack to enable you to use the DLL safely from your application 
(using Begin/End) as well as unsafely from Matlab (relying on DllMain to 
shutdown Haskell), would just be to have a flag in the DLL to keep track of 
whether you've already shut Haskell down. Then in the case for 
process_detach you could just check this so that shutdown would only be 
called from DllMain as a last resort.




Another question I have is, is it possible to create a statically
linked Haskell library that can be linked using MS VC tools?  Also I
must say I am a bit confused about the use of the routine
__stginit_Bad.  Suppose I had multiple Haskell modules each with
their own functions to export.  Which __stginit_??? routine do I use?


I don't know - hopefully someone else may be able to answer this question.

Best regards, Brian.
--
http://www.metamilk.com 


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: List syntax (was: Re: help from the community?)

2007-02-03 Thread Brian Hulley

Douglas Philips wrote:

On 2007 Feb 3, at 2:55 AM, Brian Hulley indited:

I know, I find the need to manually delete and insert commas
extremely tedious as well. This is why I proposed:
...


I like that. (I haven't done enough analysis on the layout part of
the grammar to personally make sure it is ok.)


The #( sugar ...


Bulat Ziganshin wrote:

Saturday, February 3, 2007, 10:55:52 AM, you wrote:


bracket_
(enter a)
(exit a)
(do
b
c)-- looks like LISP...


this pattern is very typical in my programs and i use '$' before last
parameter


I've written more details (and made some improvements to my original idea) 
at http://www.haskell.org/haskellwiki/Accessible_layout_proposal


Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] Proposal for allowing more use of layout to avoid parentheses and commas

2007-02-03 Thread Brian Hulley

Hi,
Following a recent thread on the Haskell' mailing list about the nusiance of 
having to deal with commas in tuples (when cutting and pasting things to 
re-order the elements there's always a pesky comma left over in the wrong 
place), I've written up a proposal for a very simple syntax tweak that would 
allow you to use the layout rule for function arguments, tuple/list/record 
contents etc for some future version of Haskell at 
http://www.haskell.org/haskellwiki/Accessible_layout_proposal


This post is not intended to spark a lot of discussion just to point out the 
existence of the page for anyone interested. I've also added a link to all 
the new proposals from http://www.haskell.org/haskellwiki/Future .


(If I don't reply to any follow up posts to this thread it's not because I'm 
ignoring them. It will just be because I have to try to get down to actually 
writing more of my program in the next few weeks, and I find thinking up 
ideas and reading posts, books, cooking, shopping, watching dvds etc, is 
infinitely more diverting than the painstakingly hard work of actual coding 
(though of course it's great in the rare occasions when things fall into 
place) ... ;-))


Brian.
--
http://www.metamilk.com 


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


Re: List syntax (was: Re: help from the community?)

2007-02-02 Thread Brian Hulley

Douglas Philips wrote:

What would be the proper way to propose that:

( exp1 , ... , expk ) (tuple, k=2)
[ exp1 , ... , expk ] (list, k=1)

be amended to:

( exp1 , ... , expk [ , ] ) (tuple, k=2)
[ exp1 , ... , expk [ , ] ] (list, k=1)


I think a problem with the above proposal is that by allowing an optional 
trailing comma the compiler can no longer detect as an error the case where 
the programmer has simply just forgotten to fill in the last element of the 
tuple/list. The existing syntax forces the user to do some extra work 
fiddling about with commas but the reward is that the compiler can verify 
that you haven't forgotten the last argument.


About a year ago I proposed (on the cafe) a syntax sugar to avoid commas in 
tuples and lists which made use of the layout rule something like:


   let a = #[-- introduces new layout block
   first
   second
   third

   let b = #(
   one
   two

As an aside it would also be nice to be able to use layout for function 
arguments as in:


   do
   a - foo
   #bracket_
   enter
   exit
   action

the general idea being that '#' immediately followed by an identifier (which 
may be qualified) or the symbol '(' or '[' would start a layout block. ('#' 
of course would no longer be able to be used in symbolic identifiers)


Brian.
--
http://www.metamilk.com 


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


Re: List syntax (was: Re: help from the community?)

2007-02-02 Thread Brian Hulley

Douglas Philips wrote:

On 2007 Feb 2, at 1:03 PM, Neil Mitchell indited:

Personally I'd make the rule that trailing commas are never allowed,
anywhere, but I do see an argument for adding them to import lists.


You just highlighted the inconsistency:
You refer to import lists... you appear to think of the import
syntax _as a list_,
and it is precisely that mental processing where the inconsistency
hits/grates.
If it is an import _list_ it can have trailing commas, but if it is
some other _list_, it can't.
I don't see the justification for making those two cases different.


I don't either, but I'd agree with Neil that trailing commas shouldn't be 
allowed anywhere, but would reject the argument of allowing them in import 
lists since it just seems to me that this was to save someone making the 
trivial effort to make their code look tidy and complete. Apart from the 
extra possibility for errors (yes I understood that you'd define it to not 
be an error but this doesn't change the fact that for people who always 
wrote their tuples using the normal mathematical convention not using an 
optional trailing comma it would be an error in their code) to go 
undetected, it would just substitute one inconsistency for another: as 
Malcolm pointed out the syntax (,,) represents the constructor for a 3-tuple 
therefore:


   let a = (x,y,)-- in your proposal a 2-tuple
   let b = (,,) x y -- still a 3-tuple with a missing element

I think this would just be far too confusing: the choice to use (,) to 
represent the pair constructor is IMHO too deeply ingrained in existing 
Haskell code to change it to mean a 1-tuple (also do we want to add the 
concept of 1-tuples to the language?). Also, I think in maths the convention 
is to use commas as separators when writing down coordinates etc.


From a personal aesthetic point of view the appearance of a trailing comma 
is highly irritating to me like passing a shelf in a shop where someone has 
left a book unsettled with the cover twisted over the edge at an annoying 
angle and some pages crumpled up, that forces me to stop and fix it... :-)


Regarding import/export lists, in some ways I think the {;} syntax should 
have been used instead then the layout rule could have been applied to good 
effect to get rid of the need for any separators eg:


   module Foo #-- # introduces a layout block 
{;}

   Bar #
   Con1
   Con2
   where

   import Control.Monad.Trans #
   MonadIO{..}
   MonadTrans{..}

(Though the above is obviously too radical a departure for Haskell')

Brian.
--
http://www.metamilk.com 


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


Re: List syntax (was: Re: help from the community?)

2007-02-02 Thread Brian Hulley

Douglas Philips wrote:

On 2007 Feb 2, at 11:25 PM, Brian Hulley indited:

Apart from the extra possibility for errors (yes I understood that
you'd define it to not be an error but this doesn't change the fact
that for people who always wrote their tuples using the normal
mathematical convention not using an optional trailing comma it
would be an error in their code)


Well it would now, but in my proposal it wouldn't be. So it would not
make any correct code incorrect.


Of course, but when I said error I meant error with respect to the 
intentions of the programmer not syntax error detected by the compiler. 
The problem with your proposal is that if optional trailing commas were 
allowed, if *I* wrote:


   (1,2,)

by mistake, forgetting to add in the last element, the fact that the 
compiler would now treat the trailing comma as optional means it would now 
accept the code as being syntactically ok. If *you* wrote that same code, it 
*would* correspond to what you meant ie just (1,2), for me it would not 
because I'd have meant to write something like (1,2,3), so for me, instead 
of a nice simple syntax error I'd get a confusing type error possibly 
somewhere else in the code therefore my net productivity would be reduced.


However a compiler option could be used to switch the optional trailing 
comma feature on and off and therefore suit everyone.





to go undetected, it would just substitute one inconsistency for
another: as Malcolm pointed out the syntax (,,) represents the
constructor for a 3-tuple therefore:

   let a = (x,y,)-- in your proposal a 2-tuple
   let b = (,,) x y -- still a 3-tuple with a missing element


Prelude :t (1,2,) 3
ERROR - Syntax error in expression (unexpected `)')
Prelude :t (1,2,)
ERROR - Syntax error in expression (unexpected `)')
Prelude

Again, this would not break existing code, since there is no
mechanism for section'd tuples.


What I meant was that the number of commas for a constructor is fixed: 
always 2 commas means a constructor for a 3-tuple. However you'd now have a 
choice of how many commas to use when writing out the sugared saturated 
application - either 2 or 3 commas. Which seems inconsistent, since in 5 
years time someone used to always writing a pair like:


   let pair = (1,2,)-- trailing commas now very popular

might quite sensibly want to write this as

   let pair = (,,) 1 2

(since the whole point of the (,,) syntax is that the number of commas is 
the same as that used when writing out the value in tuple notation) but we 
can't have a programmer choice when it comes to the constructor: the 
compiler writer must choose one way or the other. So I don't think there 
should be a choice in the sugar syntax either. Then if we choose to use (,,) 
to represent the pair constructor because of the popularity of trailing 
commas in the applied syntax, this would beg the question of what (,) would 
represent hence the spectre of introducing 1-tuples...



Also, I think in maths the convention is to use commas as
separators when writing down coordinates etc.


??? I don't quite get the applicability here...


Perhaps it is not applicable, but I thought a guiding principle of Haskell 
syntax was to try and stay as close to normal mathematical notation where 
possible, and I remember learning 2d coordinates in school as (x,y) not 
(x,y,).






From a personal aesthetic point of view the appearance of a
trailing comma is highly irritating to me like passing a shelf in a
shop where someone has left a book unsettled with the cover
twisted over the edge at an annoying angle and some pages crumpled
up, that forces me to stop and fix it... :-)


Well, if we're going to bring personal points of view in, it highly
pisses me off that in a construct such as:
( expr ,
  expr ,
  expr ,
  expr ,
  expr ,
)
I have to be vigilant to remove that trailing comma when it is in _no
way_ ambiguous.


I know, I find the need to manually delete and insert commas extremely 
tedious as well. This is why I proposed:


   #(
   expr
   expr

as sugar for (expr, expr), because it seems crazy to me that we've got all 
the machinery in place in the form of the layout rule yet we can only use it 
for a handful of built in constructs, when everywhere else we still need to 
juggle with commas and try to make parentheses as invisible as possible eg:


   bracket_
   (enter a)
   (exit a)
   (do
   b
   c)-- looks like LISP...

instead of just:

   #bracket_
   enter a
   exit a
   do
   b
   c


[snip]
I don't think we're ever going to get agreement on apparently
irreconcilable personal aesthetics, but perhaps we can apply some
principles, such as regularity and consistency and both get what we
want?


The #( sugar would only go part of the way to address your proposal since it 
doesn't address tuples written inline

Re: help from the community?

2007-02-01 Thread Brian Hulley

Taral wrote:

On 1/31/07, Conor McBride [EMAIL PROTECTED] wrote:

So, as far as Haskell' is concerned, I'd favour forbidding non-empty
cases, but only because I favour having some more explicit syntax for
empty cases, further down the line.


I see nothing wrong with case x of {}, with required braces. The
layout rule never generates empty braces.


main = do
   a - do
   b - something
   case b of
   return a

Doesn't the layout rule convert the above to:

main = do { a - do { b - something; case b of {}}; return a}
 ^^ 
empty braces


In any case I thought the layout rule was supposed to be regarded as just a 
convenience rather than making a distinction between explicit braces and 
braces added by the rule?


Also, can anyone explain why empty case constructs are needed? Why not just 
write undefined?


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Channel9 Interview: Software Composability andtheFu ture of Languages

2007-01-31 Thread Brian Hulley

Donald Bruce Stewart wrote:

magnus:

All I'm trying to say is that imperative thinking is so common
outside of CS/math and we learn it so early on in life that we
probably can consider it the natural thinking way.


   foldl (\water dish - wash water dish) soapywater dishes ::
[Dishes]

 ^^ type error

I hope they weren't expensive dishes because as each dish is washed it 
dissolves into the water never to be seen again! :-)


Brian.
--
http://www.metamilk.com 


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


Re: help from the community?

2007-01-30 Thread Brian Hulley

Andres Loeh wrote:

The only reasons that I could see in favor of allowing empty
foralls is that it might be easier to automatically generate
code. Haskell seems to be a bit inconsistent in how it treats empty
constructs. For example, empty let and empty where seems to be
allowed, but not an empty case?


Just a little remark on the side: 'If' and 'case' demand exactly one
expression. In such cases allowing zero expressions is not a
generalization but an unnecessary complication. 'Let' and 'where'
allow any number of bindings, so allowing zero bindings (instead of
demanding at least one) is a simplification.


I meant the branches of a case (the report specifies at least 1).


I think it's important to keep some possibility for the compiler to detect 
probable errors as syntax errors. If all syntax is inhabited by strange 
defaults then this just means simple errors will go undetected eg:


   let a = case foo of

Here, the user has probably got sidetracked into editing some other part of 
the program and just forgotten to get back to fill in the cases for the case 
construct. Allowing zero cases means the user will get a strange runtime 
error instead as the function part of the case is undefined.


   let z = \y (foo y)

Here, it seems clear that the user has just forgotten to type the - which 
means a simple syntax error would get transformed into a much more puzzling 
(esp for a newbie) type error.


The difference between the above and 'let' and 'where' is that if the 
enclosing construct (eg a binding) is complete, we know that the contents of 
the 'let' are complete (since extra local bindings added afterwards would be 
irrelevant) similarly for 'where', and if the enclosing construct is not 
complete the compiler will detect this.


Therefore I think the original choices are the best since they don't seem 
inconsistent when looked at this way.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Trouble understanding records and existential types

2007-01-25 Thread Brian Hulley

On Thursday, January 25, 2007 7:08 AM, John Ky wrote:

On 1/25/07, Brandon S. Allbery KF8NH [EMAIL PROTECTED] wrote:
I'm probably missing something, but:

(a) Why not:

data ANode
= Branch { name :: String, description :: String,
children :: [AnyNode] }
  | Leaf { name :: String, value :: String } -- this reuse


Would I be able to this?

  getLeaves :: ANode - [Leaf]

If not, is it the case that people generally don't bother and do this 
instead?


  getLeaves :: ANode - [ANode]


As has been pointed out, Leaf is a data constructor not a type so you'd have 
to use [ANode].

Inspired by the problem I tried a GADT:

   data IsLeaf
   data IsBranch

   data ANode a where
   Branch :: String - String - [forall b. ANode b] - ANode IsBranch
   Leaf :: String - String - ANode IsLeaf

   getLeaves :: ANode IsBranch - [ANode IsLeaf]
   getLeaves (Branch _ _ ls) = leaves ls

   leaves :: [forall b. ANode b] - [ANode IsLeaf]
   leaves (l@(Leaf _ _) : ls) = l : leaves ls
   leaves (Branch _ _ ls : lls) = leaves ls ++ leaves lls

but unfortunately the above code generates the following error by GHC6.6:

   Couldn't match expected type `forall b. ANode b'
   against inferred type `ANode a'
   In the pattern: Leaf _ _
   In the pattern: (l@(Leaf _ _)) : ls
   In the definition of `leaves':
   leaves ((l@(Leaf _ _)) : ls) = l : (leaves ls)

Just out of curiosity, does anyone know why the above code doesn't compile 
ie why is the inferred type for the pattern:


   Leaf _ _

(ANode a) and not (ANode IsLeaf)?

Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Trouble understanding records and existential types

2007-01-25 Thread Brian Hulley

Chris Kuklewicz wrote:

This is how I would write getLeaves, based on your GADT:


data IsLeaf
data IsBranch

newtype Node = Node { getNode :: (forall c. ANode c) }

data ANode :: * - * where
Branch :: String - String - (ANode a,ANode b) - [Node] -

ANode IsBranch
Leaf :: String - String - ANode IsLeaf

getLeaves :: ANode a - [ANode IsLeaf]
getLeaves (Branch _ _ (l1,l2) rest) = getLeaves l1 ++ getLeaves l2
++ concatMap (getLeaves.getNode) rest
getLeaves x@(Leaf {}) = [x]


Thanks Chris - that's really neat!
I see it's the explicit wrapping and unwrapping of the existential that 
solves the typechecking problem, and the use of newtype ensures there's no 
run-time penalty for this.
Also the wrapping of the existential allowed higher order functions to be 
used making the code much neater.
Regarding the question of why in the original example the typechecker was 
trying to match (forall b.ANode b) against (ANode a) and not (ANode IsLeaf), 
I think the answer is probably that the typechecker first finds the MGU of 
the types occupying the same position in all the left hand sides first, then 
it tries to match this against the declared type at that position, whereas 
for the original example to have typechecked it would have to treat each 
equation separately. Anyway it's now an irrelevant point given the clarity 
of your solution which compiles fine,


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] basic field questions

2007-01-24 Thread Brian Hulley

jamin1001 wrote:

Hi, I am new at Haskell and have some basic questions.
So then how should this be done?  What if I want to do something like

data Chair = Chair {pos:: Int, color :: Int}
data Table = Table {pos:: Int, color :: Int}


Unfortunately you have to think up different names for all constructors and 
field names that are declared anywhere in the same module. A possible 
methodical way to do this is to prefix all names by the type name (with 
first letter lowercase of course) eg:


   data Chair = Chair {chair_pos:: Int, chair_color :: Int}
   data Table = Table {table_pos:: Int, table_color :: Int}

The reason is that when you declare a fieldname this also introduces a top 
level function with the same name which returns the relevant component of 
the record ie in the above the following top level functions are generated 
by the compiler:


   chair_pos :: Char - Int
   chair_color :: Chair - Int
   table_pos :: Table - Int
   table_color :: Table - Int




Also, could someone tell me why this doesn't compile in GHC:

data Test = A {a::Int} | B {a::Int, b::Int}
data Test2 = C {c::A}

(Test2 line): Not in scope: type constructor or class 'A'


(A) is a data constructor whereas you need a type here, so it should be:

   data Test2 = C {c :: Test}

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell] Views in Haskell

2007-01-23 Thread Brian Hulley

Simon Peyton-Jones wrote:


http://hackage.haskell.org/trac/haskell-prime/wiki/ViewPatterns

I'm thinking of implementing it in GHC, so I'd be interested in
feedback of the form
- how desirable is it to have a feature of this general form?
- can this particular proposal be improved?


Regarding the syntax, I don't like the use of -, because I think it is 
confusing to write


   even - n

when even is the function itself. In all other places in Haskell, A - B 
represents a function from A to B whereas in the proposal A - B represents 
the function A applied to the thing currently being matched which may return 
a value wrapped up in Maybe which matches B.


There are 2 things - the inconsistent use of - and the implicit Maybe.

I'd rather the Maybe was not implicit (as described in extension 2), and a 
more consistent syntax was found. A possible syntax could represent the 
value being matched explicitly, say using ? to represent the value currently 
being matched, then the pattern could be written as an equation:


   f (prodSize ? = Small) = ...
   f (prodSize ? = Medium) = ...
   f (prodSize ? = Big) = ...

or simulating an n + k pattern:

   g (? - 3 = n) = ...

or a function which checks its arg satisfies an arbitrary expression:

   h (? - (3 * ?) = 10) = ...

or an n+k against the second element of a list

   j ( toList ? = (_ : (? - 3 = n : _))) = ...

Regarding the problem itself, I'm still not sure why views are needed. For 
example in (f) above, why not just write as:


   f :: Product - ...
   f prod = k (prodSize prod) where k = ...

Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] IO is not a monad

2007-01-23 Thread Brian Hulley

Yitzchak Gale wrote:

I wrote:

Prelude let f .! g = ((.) $! f) $! g
Prelude let f = undefined :: Int - IO Int
Prelude f `seq` 42
*** Exception: Prelude.undefined
Prelude ((= f) . return) `seq` 42
42
Prelude ((= f) .! return) `seq` 42
42


Duncan Coutts wrote:

Perhaps I'm missing something but I don't see what's wrong.


The monad laws say that (= f) . return must be
identical to f.


I thought it was:

   return x = f = f x

so here the lhs is saturated, so will hit _|_ when the action is executed 
just as the rhs will.
I think the problem you're encountering is just that the above law doesn't 
imply:


   (= f) . return = f

in Haskell because the lhs is of the form \x - _|_ whereas the rhs, which 
should really be of the form \x - _|_, is actually _|_ already(!) so the 
_|_ has effectively been allowed to jump to the left of the arrow hence the 
inequality detected by seq.


Perhaps a solution would be to force _|_ to respect the shape of the type, 
thus non-terminating values of type a - b would be given the value \_ - 
_|_ instead of _|_ ?


Regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] IO is not a monad

2007-01-23 Thread Brian Hulley

Brian Hulley wrote:

Yitzchak Gale wrote:

I wrote:

Prelude let f = undefined :: Int - IO Int
Prelude f `seq` 42
*** Exception: Prelude.undefined
Prelude ((= f) . return) `seq` 42
42

The monad laws say that (= f) . return must be
identical to f.


I thought it was:

   return x = f = f x

so here the lhs is saturated, so will hit _|_ when the action is
executed just as the rhs will.
I think the problem you're encountering is just that the above law
doesn't imply:

   (= f) . return = f

in Haskell

ok so far...


because the lhs is of the form \x - _|_


No I got this wrong. Evaluating the lhs to WHNF doesn't hit the _|_. 
(Incidentally the version using .! evaluates to exactly the same thing since 
(= f) `seq` ((= f) . return) = ((= f) . return) since (\x - x = f) 
is already in WHNF afaiu)


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] IO is not a monad

2007-01-23 Thread Brian Hulley

Brian Hulley wrote:

Brian Hulley wrote:

Yitzchak Gale wrote:

I wrote:

Prelude let f = undefined :: Int - IO Int
Prelude f `seq` 42
*** Exception: Prelude.undefined
Prelude ((= f) . return) `seq` 42
42

The monad laws say that (= f) . return must be
identical to f.


I thought it was:

   return x = f = f x

so here the lhs is saturated, so will hit _|_ when the action is
executed just as the rhs will.


Ooops! But that does not mean the equation holds because for example

   Prelude (return 3 = f) `seq` 42
   42
   Prelude (f 3) `seq` 42
   *** Exception: Prelude.undefined

In the lhs you only hit _|_ when the composite (=) action is actually 
being executed whereas in the rhs you hit _|_ when computing the function 
which will return the action to execute so there is difference.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Article review: Category Theory

2007-01-19 Thread Brian Hulley

Lennart Augustsson wrote:


On Jan 19, 2007, at 08:05 , [EMAIL PROTECTED] wrote:

Thus, Hask is not a category, at least not as defined in the article.
The problem is that (either) morphisms or the morphism composition
('.')
are not internalized correctly in Haskell.




And this is why some of us think that adding polymorphic seq to
Haskell was a mistake. :(


I've often wondered why seq is the primitive and not $!
Would this solve the problem?
Is there any solution that would allow excess laziness to be removed from a 
Haskell program such that Hask would be a category?


Thanks, Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] seq (was: Article review: Category Theory)

2007-01-19 Thread Brian Hulley

Neil Mitchell wrote:

Hi Brian,

Is there any solution that would allow excess laziness to be removed
from a Haskell program such that Hask would be a category?


class Seq a where
   seq :: a - b - b

Then you have a different seq based on the types, and it doesn't go
wrong. You would probably want deriving Seq support.


This seems an amazingly neat solution to a really terrible problem, so:

1) Does anyone know why this was not used in the first place?

2) Would it be good to use this in future versions of Haskell?

3) Is there any practical program which requires the current seq that could 
not be rewritten to use the typeclass seq?


Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Article review: Category Theory

2007-01-18 Thread Brian Hulley

Johan Gršnqvist wrote:

Ulf Norell skrev:


On Jan 16, 2007, at 7:22 PM, David House wrote:


In the section on the category laws you say that the identity
morphism should satisfy

  f . idA = idB . f

This is not strong enough. You need

  f . idA = f = idB . f



(I do not know category theory, but try to learn from the
tutorial/article/introduction.)

Given this, and looking at the figure accompanying exercise 2. Can I
not then show that f=h from:

f.g = idA (f.g is A - A and idA is the only morphism A - A,
closedness gives the equality)

h.g = idA (same argument)
g.f = g.h = idB (same argument)

thus (using the laws for id and associativity)

f =  idA . f  =  (h . g) . f = h . (g . f)  = h . idB  = h

Thus in the figure f=h must hold, nad one arrow can be removed from
 the graph.


But f /= h so by the above reasoning you get a proof by contradiction that 
the figure is not a category.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Article review: Category Theory

2007-01-17 Thread Brian Hulley

David House wrote:

http://en.wikibooks.org/wiki/Haskell/Category_theory
I'd love comments from newcomers and experts alike regarding my
approach, the content, improvements and so on. Of course, it's on the
wikibook, so if you have anything to add (that's not _too_ substantial
otherwise I'd recommend discussion first) then go ahead.


Hi David,

In the introduction you say that Set is the category of all sets with 
morphisms as standard functions and composition as standard function 
composition.


But in the second exercise in the intro it's clear that function composition 
is not associative. Therefore surely this means everything based on function 
composition can't be a category?


Also, why does this exercise contain redundant morphisms (I hope I'm not 
spoiling it for anyone by saying this or perhaps I've just totally 
misunderstood everything)?


Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Article review: Category Theory

2007-01-17 Thread Brian Hulley

Brian Hulley wrote:

David House wrote:

http://en.wikibooks.org/wiki/Haskell/Category_theory

But in the second exercise in the intro it's clear that function
composition is not associative.


Apologies. I got totally confused with the way function composition is back 
to front etc.

I still have no idea what the solution to the second exercise is though.

Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Article review: Category Theory

2007-01-17 Thread Brian Hulley

Yitzchak Gale wrote:

David House wrote:

I've added a bit more explanation, so it may now be palatable. It is
quite a hard exercise, though, perhaps it shouldn't come so early on.


In my opinion, it is now much more clear. And it is a very
instructive example.

If people still find it too hard, you could add the additional
hint: Keep in mind that there are no morphisms
other than the ones shown in the diagram.


Ok I understand it now, because David has just clarified offlist the thing 
that puzzled me about the diagram: namely that morphisms have an 
individuality of their own that isn't fully determined by the lhs and rhs of 
the arrow like the relationship between a function and its type.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-15 Thread Brian Hulley

Meng Wang wrote:

Hi Brian,

Thank you for starting the thread. We (Martin Sulzmann and me)
proposed a type class extension which allows modular extension of
superclasses (a complement of subclass extension). The idea has been
shown to be particularly useful in (but not limited to) encodings of
generic programming with type classes. A brief introduction of the
proposal is documented in our wiki:
http://taichi.ddns.comp.nus.edu.sg/taichiwiki/GPHomePage. I will try
to add it as a link in yours soon.


A more detailed and formal description of the proposal can be found
in our Workshop on Generic Programming 06 paper which is available at
http://www.comp.nus.edu.sg/~sulzmann
http://web.comlab.ox.ac.uk/oucl/work/meng.wang/


Thanks - I've added the above links to 
http://www.haskell.org/haskellwiki/Class_system_extension_proposal along 
with a one-line summary which I'm sure is totally imperfect but hopefully 
not too misleading ;-)


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-09 Thread Brian Hulley

Simon Peyton-Jones wrote:

One of the great things about John's class-alias proposal is that
John worked out a lot of details and captured them in a web page,
rather than it getting buried in an email thread.

If you have ideas to refine his proposal, it'd be good to see if,
with him, you can come up with a unified design, and again capture it
in a Wiki page or something.


I've started a page at 
http://www.haskell.org/haskellwiki/Class_system_extension_proposal
John - I haven't added anything about your class alias proposal because 
you've copyrighted your proposal and I don't want to do the wrong thing ;-) 
Can you add a section for your proposal (or containing a link to your 
proposal) on his page?


Please could everyone who has any other ideas about class system extensions 
add them to the page above so that we have a central location. Hopefully it 
will gradually become clear what all the issues are and perhaps a path for 
trying to implement some extensions in order of difficulty.


Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-09 Thread Brian Hulley

Brian Hulley wrote:

Simon Peyton-Jones wrote:

One of the great things about John's class-alias proposal is that
John worked out a lot of details and captured them in a web page,
rather than it getting buried in an email thread.

If you have ideas to refine his proposal, it'd be good to see if,
with him, you can come up with a unified design, and again capture it
in a Wiki page or something.


I've started a page at
http://www.haskell.org/haskellwiki/Class_system_extension_proposal
John - I haven't added anything about your class alias proposal
because you've copyrighted your proposal and I don't want to do the
wrong thing ;-) Can you add a section for your proposal (or
containing a link to your proposal) on his page?

  ^^^
Apologies for typo - should be this page

Best regards, Brian.
--
http://www.metamilk.com
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] why can't you surround (+) in backticks and have it beinfix?

2007-01-08 Thread Brian Hulley

[EMAIL PROTECTED] wrote:

David House wrote:


You can fake this:

(-!) = ($)
(!-) = flip ($)

foo -! liftM2 (,) !- bar


Was anyone in that brainstorm thinking of Chung-chieh Shan's
-: and :-
(http://www.haskell.org/pipermail/haskell-cafe/2002-July/003215.html)
or was the similarity just a really cool coincidence?


I hope no-one seriously thinks the above syntax is clearer than:

   liftM2 (,) foo bar

Brian.
--
Operators: one small step for compilers, one giant leap for obfuscation.

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


[Haskell-cafe] Why does the wiki search facility not work properly?

2007-01-07 Thread Brian Hulley

Hi,
There is a page on the Haskell Wiki titled Talk:SantaClausProblem 
subtitled Beautiful concurrency. However typing any of the following into 
the search box *doesn't* lead to the page:


   Santa
   talk:santaclausproblem
   beautiful
   beautiful concurrency
   Talk:Santa

In fact to get the page you have to type the *exact* full title in the 
*exact* case. Luckily I could always refer back to SimonPJ's post to the 
Haskell mailing list to find the link to the page, but I think this 
situation is really bad because it means that things on the wiki are more or 
less just being thrown down a gaping void never to be seen again unless you 
know which catagories to look in from the main page.


Another point is that the word beautiful does occur on the page but the 
page is not included in the list of page text matches. Perhaps the site is 
not being automatically re-indexed frequently enough? There is also a bunch 
of check boxes at the bottom of the search results page that doesn't seem to 
do anything either except cause nothing at all to happen when you click 
search unless the (Main) box is the only box ticked.


Anyway I thought I'd just point this out in case anyone knows how to fix it.

Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-06 Thread Brian Hulley

Bulat Ziganshin wrote:

Hello Brian,

Thursday, January 4, 2007, 10:00:05 PM, you wrote:


deeper, the programmer is burdened more and more by the need to
cut-and-paste method definitions between instances because Haskell
doesn't allow a superclass (or ancestor class) method default to be
redefined in a subclass.


i've runned into this problem with Streams library. finally i've
decided to wrote bodies of such methods outside of class:

[example snipped]

Hello Bulat,

Thanks for the workaround, which solves the need to copy and paste method 
bodies though not the problem of having to write out instance decls for a 
potentially large chain of classes leading to the subclass of interest. Part 
of the motivation for proposing that a superclass method default could be 
redefined in a subclass (or a particular instance) is that it would allow 
some refactorings of the class hierarchy without affecting code that just 
uses the subclass - in particular it would allow existing code using Monad 
to compile unchanged even when Monad moved down to Functor = Applicative = 
Monad because return and = are enough to get completely defined instances 
for Functor and Applicative.


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Stupid newbie question

2007-01-06 Thread Brian Hulley

Brian Hurt wrote:

nth 0 (x:xs) = Some x
nth i (x:xs) = if i  0 then Empty else nth (i-1) xs
nth i [] = Empty

[blows stack on large i]

As other people have pointed out, this is due to laziness. I'd write it 
like:


   nth 0 (x:_) = Some x
   nth i (_:xs) = of i  0 then Empty else (nth $! i-1) xs
   nth _ [] = Empty

where a general rule of thumb is always to replace (fun intexp) by (fun $! 
intexp) whenever intexp is just a trivial arithmetic expression that doesn't 
involve traversing (ie forcing of) any other data structure.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Stupid newbie question

2007-01-06 Thread Brian Hulley

Brian Hulley wrote:

Brian Hurt wrote:

nth 0 (x:xs) = Some x
nth i (x:xs) = if i  0 then Empty else nth (i-1) xs
nth i [] = Empty

[blows stack on large i]

As other people have pointed out, this is due to laziness. I'd write
it like:

   nth 0 (x:_) = Some x
   nth i (_:xs) = of i  0 then Empty else (nth $! i-1) xs

  ^^^ -- oops!


   nth _ [] = Empty


I think the above code would be more efficient written as:

   nth n xs = if n  0 then Empty else nth' n xs
   where
   nth' 0 (x:_) = Some x
   nth' i (_:xs) = (nth' $! i - 1) xs
   nth' _ _ = Empty

since the first 2 cases deal with every situation where we've got a 
non-empty list and an index = 0 (so no need to keep checking that the index 
is = 0 in the second case - instead the test can be moved outside the 
loop) and there's no need to pattern match against [] in the last case 
because we already know this must be an empty list.
(Though in general it's probably a good idea to make each pattern as 
independent as possible when writing a function so that if some cases of a 
function are later edited there's more chance of the compiler being able to 
lead you to errors via the incomplete patterns warning - hopefully the 
compiler can optimize out any redundant checks)


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Stupid newbie question

2007-01-06 Thread Brian Hulley

Brian Hulley wrote:

Brian Hulley wrote:

Brian Hurt wrote:

nth 0 (x:xs) = Some x
nth i (x:xs) = if i  0 then Empty else nth (i-1) xs
nth i [] = Empty

[blows stack on large i]

As other people have pointed out, this is due to laziness. I'd write
it like:

   nth 0 (x:_) = Some x
   nth i (_:xs) = of i  0 then Empty else (nth $! i-1) xs

  ^^^ -- oops!


   nth _ [] = Empty


Actually I see I should have read Jeremy Shaw's answer more carefully before 
giving my own since I'd missed the point about the problem being with the 
list itself not the decrementing of (i) (which wouldn't be a problem since 
it is immediately forced on the next iteration by the comparison of i to 0).


The answer therefore lies in the laziness of the makelist function which 
could be solved by:


   makelist i = i : (makelist $! i - 1)

Jeremy Shaw wrote:

pps. I didn't explain why [1..100] works, but [1..] fails, because
I don't know :) It's a bit suprising to me...


I think this might be because the code that produces the list [1..100] 
would have to be something like:


   produce n i = if i  n then i : produce n (i +1) else []

so each element of the list is now forced by the comparison with n, so even 
though the end of the list will be a thunk when 100 has not yet been 
reached, none of the elements are thunks.


Anyway it was certainly not a stupid question - thanks for asking it.

Best regards, Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-04 Thread Brian Hulley

Hi,
Looking at some of the ideas in 
http://www.haskell.org/haskellwiki/The_Other_Prelude , it struck me that the 
class system at the moment suffers from the problem that as hierarchies get 
deeper, the programmer is burdened more and more by the need to 
cut-and-paste method definitions between instances because Haskell doesn't 
allow a superclass (or ancestor class) method default to be redefined in a 
subclass.


For example, consider this part of a proposal for Functor = Applicative = 
Monad:


   -- I've just used 'm' so it's easy to see what parts are relevant to 
Monad

   class Functor m where
   fmap :: (a - b) - m a - m b

   class Functor m = Applicative m where
   return :: a - m a

   (*) :: m (a - b) - m a - m b

   () :: m a - m b - m b
   ma  mb = -- left as exercise for a rainy day!

   class Applicative m = Monad m where
   (=) :: m a - (a - m b) - m b

The problem with this is that whereas someone defining a Monad at the moment 
only needs to define (return) and (=), with the above, though it gives 
obvious advantages in flexibility, generality etc, defining a new Monad 
involves providing methods (in instance decls) for fmap and (*) as well, 
and the default method for () is


   ma  mb = (fmap (const id) ma) * mb

(from that page above) which I'm sure everyone will agree is a *lot* more 
complicated than:


   ma  mb = ma = (\_ - mb)

Not only is the first definition for () more complicated, it obscures the 
simple fact that for monads it's just a trivial special-use case of = 
where the bound argument is ignored.


Therefore I'm wondering if it would be possible to allow default methods for 
a superclass to be defined, or redefined, in a subclass, so we could write:


   class Applicative m = Monad m where
   (=) :: m a - (a - m b) - m b

   mf * ma = mf = \f - ma = \a - return (f a)

   ma  mb = ma = \_ = - mb

   fmap f ma = ma = \a - return (f a)

(I know the above can be written in a more point-free style but I wrote it 
like that to make it easy to understand what's happening.)


The essential point here (excuse the pun :-) ) is that it is impossible to 
write the default methods in the class in which the operation is defined, 
because the implementation depends on methods of the relevant subclass (and 
will therefore be different for different subclasses though not for each 
particular instance of a given ancestor class of a  particular subclass). As 
Haskell stands at the moment, we are forced to cut and paste identical 
methods for each individual instance of each ancestor class of a particular 
subclass because we can't override an ancestor class method in the *class* 
decl for a subclass.


The type class system at present is based on the idea that you can define 
related methods together and in terms of each other, at one level of the 
hierarchy. However as the above example shows, related methods sometimes 
need to be spread over the hierarchy but we still want to be able to define 
default implementations of them in terms of each other.


Perhaps there is some reason this can't be done?

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Redefining superclass default methods in a subclass

2007-01-04 Thread Brian Hulley

Roberto Zunino wrote:

Brian Hulley wrote:

because Haskell doesn't allow a superclass (or ancestor class)
method default to be redefined in a subclass.


How one would write instances? Using your Monad class, does
   instance Monad F where
  return = ...
  (=) = ...
automatically define an instance for Applicative?


Yes, but I'd make the method names be call-site-bound so the actual method 
that is called is determined by the set of instance decls and class decls 
visible at each particular call site, and any instances that are 
automatically created would be hidden by any explicitly defined instances 
that are visible.




If it does: What if there already is such an instance? Which one gets
used for ()? The user-defined one or the Monad default?


A possible proposal could be:
1) Class and instance decls would allow method implementations to be given 
for any methods in the class or any ancestor class.


2) Whenever an instance decl is visible there would always be a full set of 
instance decls for all ancestor classes, by supplementing the set of 
explicitly given instance decls that are visible by automatically generated 
implicit instance decls.


3) The most specific method implementation would always be chosen (ie prefer 
an explicit instance method over a class method and prefer a subclass method 
to a superclass method)


In particular rule 2) would mean that the actual method used depends on 
what's available at the call site which means that a Haskell program could 
no longer be thought of as being re-written into a single module before 
compilation, since the meaning of overloaded names would be determined by 
(CalledFromModule, Type) not just Type.


(The desire to hide instance decls or have different instance decls for the 
same type within the same program has come up before on the list but 
unfortunately I can't remember who posted something along these lines or 
when.)



Is separate
compilation still possible? (If there is no instance right now, one
might pop out in another module...)



I think it should still be possible because within a module, the 
overloadings would be determined by the set of explicitly defined instances 
in scope in that module. Various optimizations might be more tricky because 
the call site module associated with each overloaded name would need to be 
taken into account when inlining across module boundaries (ie a name used 
inside an inlined function needs to be resolved as if it had been used in 
the module where the function was defined not the module where the function 
is inlined).


For example:

   module A where
   import Proposed.Control.Monad

   data T a = T a
   instance Monad T

   [-# INLINE foo #-}
   foo :: a - T a
   foo = return  -- uses Monad class default
   -- which is inherited from the Applicative
   -- class default

   module B where
   import A
   import Proposed.Control.Monad

   instance Applicative T where
   return x = retB x

   bar :: T a
   bar = return 'q'-- would use (retB)

   zap :: T a
   zap = foo 'q'-- would use (return) from A

A question is whether the extra difficulty in resolving overloadings (for 
human reader as well as complier) is worth the advantages of being able to 
get generated definitions for () for Applicative and (fmap) for Functor 
from a single instance decl for (Monad.=) etc.


[Rearranged]

The class aliases proposal lists several similar shortcomings of the
current class system.
http://repetae.net/john/recent/out/classalias.html


IIUC the class alias proposal is about being able to group classes together 
and deal with them as a whole so similar issues of resolving overloadings 
arising from overlapping aliases/ explicit instance decls etc would arise 
(and I imagine the solutions would lie in similar directions).


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Composing functions with runST

2007-01-01 Thread Brian Hulley

Yitzchak Gale wrote:

Can anyone explain the following behavior (GHCi 6.6):

Prelude Control.Monad.ST runST (return 42)
42
Prelude Control.Monad.ST (runST . return) 42

interactive:1:9:
   Couldn't match expected type `forall s. ST s a'
  against inferred type `m a1'
   In the second argument of `(.)', namely `return'
   In the expression: (runST . return) 42
   In the definition of `it': it = (runST . return) 42


Section 7.4.8 of GHC manual states that a type variable can't be 
instantiated with a forall type, though it doesn't give any explanation why.


Hazarding a guess, I suggest it *might* be due to the fact that

   forall s. ST s a

means

   forall s. (ST s a)

whereas you'd need it to mean

   (forall s. ST s) a

in order for it to unify with (m a).

Just a guess - I'd be interested to know the real reason as well.

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Idiomatic Haskell equivalent of keyword argumentsto functions

2006-12-29 Thread Brian Hulley

Paul Moore wrote:

I'm thinking around the design of a couple of things, and am hitting
an issue which I know how I would solve in Python, but I'm not sure
what a good idiomatic Haskell approach would be.

The problem is that I am trying to write a function which takes a
rather large number of arguments, many of which are optional (ie, have
sensible defaults).


There's an interesting solution to this in section 15 (starting page 53) of 
Magnus Carlsson and Thomas Hallgren's Fudgets thesis available online at: 
http://www.cs.chalmers.se/~hallgren/Thesis/ (Fudgets main page is at 
http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/ ).


Basically the idea is that for any function which takes lots of params, the 
params are gathered together into a datatype whose details are hidden from 
the user of the function. For each parameter, the user is given a function 
called a Customiser in the thesis, which takes a value of the hidden 
datatype and modifies it by setting the relevant parameter. Multiple params 
can therefore be specified by chaining Customisers together in any order 
with the usual function composition. The original function, instead of 
taking lots of params, now just takes a single parameter: a Customiser, 
which is used to turn the default params into the customised params.
This is similar to the idea of using records but has the advantage that by 
judicious use of typeclasses of which the param data is an instance, you 
don't need to keep on inventing different names for the same thing (eg to 
specify colour for the background of a label control in a GUI or colour for 
a font you could use the name setColour in both cases).
(A possible disadvantage is the overhead of having to create a whole new 
modified version of the parameter record for each Customiser in the 
composition so if efficiency were an issue you'd have to see if the compiler 
could inline the composition of the customiser functions to make it as 
efficient as the built in multiple field record update using rec{a=a', c=c'} 
syntax)



To make things concrete, the example I'm really thinking of is a send
an email function, which would take a subject, a body, a list of
recipients, optional lists of cc and bcc recipients, an optional
mailserver (default localhost), an optional port (default 25), and
possibly optional authentication details. I found a couple of Haskell
modules implementing a SMTP client, but they both just used a list of
positional parameters, which I'm not really happy with. At the very
least, I'd like to wrap them in a nicer interface for my code.



-- hidden from clients
data EmailParams =
   EmailParams
   { subject :: String
   , body :: String
   , recipients :: [Recipient]
   , cc :: [Recipient]
   , bcc :: [Recipient]
   , mailserver :: Mailserver
   , port :: Port
   , authentication :: Authentication
   }

-- record syntax elided to save space
defaultEmailParams = EmailParams   [] [] [] defaultMailserver 
defaultPort defaultAuthentication


--a Customiser visible to clients
setSubject :: String - EmailParams - EmailParams
setSubject s ep = ep{subject = s}

-- etc

send :: (EmailParams - EmailParams) - IO ()
send f = sendInternal (f defaultEmailParams)
   where
   sendInternal :: EmailParams - IO ()
   sendInternal = ...

-- In user code:

main = send (setSubject Test . setBody A test email)

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Seeking advice on a style question

2006-12-27 Thread Brian Hulley

Steve Schafer wrote:

In my text/graphics formatting work, I find myself doing a lot of
pipeline processing, where a data structure will undergo a number of
step-by-step transformations from input to output. For example, I
have a function that looks like this (the names have been changed to
protect the innocent--and to focus on the structure):

 process :: a - b - c - d - e
 process x1 x2 x3 x4 =
   let y01   = f01 x1 x2 x3;
   y02   = f02 x1;
   y03   = f03 y02;
   y04   = f04 y03;
   y05   = f05 x1 y01 y04;
   y06   = f06 x2 y05;
   (y07,y08) = f07 y01 y06;
   y09   = f08 y07;
   (y10,y11) = f09 x2 x4 y09 y08;
   y12   = f10 y10;
   y13   = f11 y12;
   y14   = f12 x1 x2 x3 y01 y13;
   y15   = f13 y14;
   y16   = f14 y15 y11
   in y16


Disclaimer: just re-written by hand so needs double-checking before use:

   process x1 x2 x3 x4 =
   let
   y01 = f01 x1 x2 x3
   (y07, y08) = f07 y01 (f06 x2 (f05 x1 y01 (f04 (f03 y02
   (y10, y11) = f09 x2 x4 (f08 y07) y08
   in
   f14 (f13 (f12 x1 x2 x3 y01 (f11 (f10 y10 y11

You can also make it look more like the diagram by using more indentation 
eg:


   process x1 x2 x3 x4 =
   let
   y01 =
   f01
   x1
   x2
   x3
   (y07, y08) =
   f07
   y01
   (f06
   x2
   (f05
   x1
   y01
   (f04
   (f03
   y02
   ...

Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Versioning

2006-12-21 Thread Brian Hulley

Lennart Augustsson wrote:

On Dec 21, 2006, at 15:53 , Neil Mitchell wrote:


Hi


there are really no choices for real development. many libraries,
language
extensions and techniques are for ghc only


I develop everything in Hugs, including the Yhc compiler itself. Hugs
is great. There are lots of extensions in GHC, but Haskell 98 is a
perfectly useable language!



I must second this opinion.  There's this (false) perception that you
need all
kinds of extensions to make Haskell usable.  It's simply not true.
Certain
extensions can make your life easier, but that's it.


Well, FingerTrees for example, require MPTCs as in

   pushL :: Measured v a = a - FingerTree v a - FingerTree v a

For any kind of object oriented programming you need existentials to 
separate the interface from the different concrete objects. Also in the code 
I've written I've often needed higher rank polymorphism and scoped type 
variables. Sure it's possible to use all kinds of horrific hacks to try and 
avoid the need for scoped type variables etc but why would anyone waste 
their time writing difficult obfuscated code when GHC has the perfect 
solution all ready to use.


In other words, what on earth is good about gluing oneself to Haskell98? 
Life's moved on...


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Versioning

2006-12-21 Thread Brian Hulley

Neil Mitchell wrote:

Hi


In other words, what on earth is good about gluing oneself to
Haskell98? Life's moved on...


If you stick to Haskell 98 you can:

* Convert your code to Clean (Hacle)
* Debug it (Hat)
* Run it in your browser (ycr2js)
* Document it (Haddock)
* Make a cross platform binary (yhc)
* Get automatic suggestions (Dr Haskell)
...

Sometimes you need a type extension, but if you don't, you do get
benefits.


True, though it would be even better if the usual extensions were more 
widely supported, though I suppose identifying what's useful and therefore 
worth supporting is the point of the Haskell Prime process.


As an aside I've often thought it would be better if the various components 
of Haskell compilers/tools would be separated out so that people could 
effectively build their own compiler tailored more specifically for their 
needs. Ie lots of smaller projects each dealing with a particular phase of 
Haskell processing which would be joined together by standard APIs, so that 
someone could use the latest type system extensions with whole program 
optimization while someone else could use those same type extensions with a 
back end designed for graphical debugging etc, and also so that people just 
interested in developing whole program optimization (for example) wouldn't 
have to reinvent the ever-more-difficult wheel of 
lexing/parsing/typechecking/targeting  multiple platforms...


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: Stronger static types, was Re: [Haskell-cafe] Re: Versioning

2006-12-21 Thread Brian Hulley

Jacques Carette wrote:

Yes, dependent types have a lot to do with all this.  And I am an
eager lurker of all this Epigram.


Would it be possible to augment Haskell's type system so that it was the 
same as that used in Epigram?
Epigram itself uses a novel 2d layout and a novel way of writing programs 
(by creating a proof interactively) but these seem orthogonal to the actual 
type system itself.


Also, typing is not the only issue for compile time guarantees. Consider:

   data Dir = Left | Right | Up | Down deriving Eq

   -- Compiler can check the function is total
   foo :: Dir - String
   foo Left = Horizontal
   foo Right = Horizontal
   foo Up = Vertical
   foo Down = Vertical

versus

   -- Less verbose but compiler can't look inside guards
   foo x | x == Left || x == Right = Horizontal
   foo x | x == Up || x == Down = Vertical

versus something like:

   foo (Left || Right) = ...
   foo (Up || Down) = ...

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Shrinking the Prelude: The categorical approach

2006-12-20 Thread Brian Hulley

Imam Tashdid ul Alam wrote:

hi guys,
I was just wondering if anyone is interested is a
quasi-project of rewriting the Prelude (only
shrinking it as measured by the total number of names
imported, read along...)
the idea is (just to be substantially different in
approach) to develop an alternate history of
Haskell.
take map for example, and fmap, I don't think they
should be named different (fmap is ugly, not
suggestive, and conceptually the same).
mplus could be renamed (++) (they are conceptually the
same


I suggest that all functions in classes be given actual names and ASCII 
symbolic names could be defined outside the class as an additional 
convenience eg:


   class Monad m = MonadPlus m where
   mzero :: m a
   mplus :: m a - m a - m a

   (++) = mplus-- 'convenience' name

I think people forget that ASCII symbol names which look intuitive to them 
when they are writing a library or paper, can be very confusing for people 
who need to use many libraries (with consequent explosion of obfuscatory 
symbols) in a project, look terrible when qualified, and make code difficult 
to read because of the need to find/remember precedences and associativity. 
(Note that Haddock does *not* supply this info, you need to look at the 
actual source code of the library to find it out.)



, mzero looks odd, name it empty, or simply zero)


What about (mempty) from Monoid or (empty) from Data.Sequence or 
Control.Applicative? Either these are in some way the same thing as mzero, 
or else they are different in which case either qualified imports would be 
needed everywhere (not necessarily a bad thing) or different names like the 
ones we already have, are needed.



although I think concat should be replaced by msum (or
the other way around preferably :) ? msum is a bad
name) I am somewhat confused by join. concat seems to
match join's type but I don't think the ideas
coincide.
and so on. in particular, we would want:
* no backwards compatibility. the Prelude as is it, is
good enough. we are defining a new module.


Starting with a clean slate seems a good idea, especially to get rid of 
lispy names like (cons), (snoc), (null) and replace them with something 
self-explanatory like (pushL), (pushR), (isEmpty).



* clean categorical hierarchy of type classes
(category theorists wanted!) promoting uniformity.


This would be great. However it is a question to me whether it is even 
possible to organize everything in a single hierarchy. Eg look at the 
problems with trying to reorganize Num, or standard OOP problems with 
hierarchies in general. Since there are multiple ways of looking at a 
domain, it is likely there will need to be multiple hierarchies which will 
probably not interact so well.



* cleaner names. foldl1 means nothing. absolutely
nothing. what's the 1 for?


A while back I suggested using capital letters for suffix to distinguish the 
functionality (fold) from the variant (L == left). Perhaps (foldl1) could be 
renamed (foldLN) ie fold + left + non-empty or (foldLO) for fold + left + 
occupied.



* our Prelude only contains typeclasses, datatypes,
and functions of utmost conceptual (and semantic, such
as error, undefined and seq) importance, everything
else goes to other modules. our Prelude is not going
to be a place for convenient declarations.
* the suffix method of naming (liftM2) is considered
messy. we would prefer a seperate module (promoting
qualified import).


In the particular case of *M functions, I quite like the existing naming 
since it's clear that it's a monadic function. However I'd agree that names 
like (newIORef) are an abomination, that should be replaced by (Ref.new).



this is a fun project. we will not rewrite the
Prelude, we'll merely rename it. I would suggest the
name TheOtherPrelude to make our intentions clear. the
conveniences (like concatMap) goes to
TheOtherPrelude.Extension. I suggest we do it on the
wiki. anyone interested just open a page with your
name of choice. I am not doing it only because there's
no point doing it if no one's interested.


Good luck with this. For my own project, I re-implemented FingerTree's so I 
could use my preferred naming style (and also as an exercise following the 
excellent tutorial-style FingerTree paper), and wrote some trivial wrappers 
for a few other modules eg Data.IORef, Data.Unique so that I could use 
Ref.new, Unique.new etc.I think it would be quite a big task to refactor the 
entire code base according to a clean hierarchy of type classes, and also a 
task I can't really help with since I'm not familiar enough with category 
theory at present, but certainly it would be a worthwhile endeavour imho,


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Haskell Side Effect

2006-12-20 Thread Brian Hulley

Ashley Yakeley wrote:

Since learning Haskell, I can now count in Spanish! See:

  one in Spanish,
  two in Spanish,
  three in Spanish,
  four in Spanish..


Is there a solution ie some concept C such that C Haskell  C Spanish, 
somewhere?

Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Class annotation on datatype ineffective in function

2006-12-19 Thread Brian Hulley

Reto Kramer wrote:

The code below does not compile unless the bar function is
annotated with a suitable constraint on the class of the formal
parameter.


class (C a)
data (C foo) = XY foo = X foo | Y foo

bar :: a - XY a
bar aFoo = X aFoo


As suggested, this works:


bar :: (C a) = a - XY a


Can someone explain to me why the compiler can not infer that a (in
bar) must be (C a) from the bar result type XY a (by way of the C
class provided for the datatype)?


Hi Reto -
If you'd not given any signature at all the compiler would have inferred the 
correct type for bar, but since you gave an explicit signature, the compiler 
had no option but to complain that you missed out the C a constraint. (ie if 
you decide to provide a signature you must give the full signature including 
constraints since the compiler won't add anything to them - partial 
signatures are not (yet) supported)


Regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Showing the 1 element tuple

2006-12-19 Thread Brian Hulley

Neil Mitchell wrote:

Hi,

A weird question, what does the 1 element tuple look like?

() -- 0 element tuple
(,) a b -- 2 element tuple
(,,) a b c -- 3 element tuple

() a - meaningless
(a) - a in brackets

GHC has the 1 element unboxed tuple, (# a #), and all the other sizes
unboxed as well, but how would you visually represent the 1 element
boxed tuple?


Tuples represent dimensionality therefore a 1-element tuple is just a 
1-dimensional value ie the value itself hence a == (a) == ((a)) == (((a))) 
== ...


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell] ANNOUNCE: Phooey -- a Functional UI library for Haskell

2006-12-12 Thread Brian Hulley

From: Conal Elliott
To: haskell@haskell.org
Sent: Tuesday, December 12, 2006 7:17 AM

GUIs are usually programmed in an unnatural style, in that 
implementation
dependencies are inverted, relative to logical dependencies. This reversal 
results
directly from the imperative orientation of most GUI libraries. While 
outputs
depend on inputs from a user and semantic point of view, the imperative 
approach

imposes an implementation dependence of inputs on outputs.


Hi,
This looks really interesting, but I'm struggling to understand what you 
mean by reversal. Can you elaborate on what you mean by the imperative 
approach  imposes an implementation dependence of inputs on outputs. In the 
model-view-controller pattern for example, I see no such reversal.


Also, suppose you have a gui consisting of an edit widget such that when the 
user types something it gets lexed, parsed, and fontified as a Haskell 
program, ie from the user's point of view the widget maintains a syntax 
highlighted view of the code which is continuously updated. Would your 
system do the lexing/parsing for every key that was pressed or only once, 
when the widget needs to be re-rendered (a typical gui for Windows would 
only propagate changes and re-draw the gui (ie lex/parse/fontify) when there 
are no event messages pending)?


In other words, does your system solve the problem of automatic caching of 
updates that would be solved in the imperative setting by the (admittedly 
rather messy) waiting for nothing else happening?


Regards, Brian.
--
http://www.metamilk.com
___
Haskell mailing list
Haskell@haskell.org
http://www.haskell.org/mailman/listinfo/haskell 


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


[Haskell-cafe] Re: [Haskell] ANNOUNCE: Phooey -- a Functional UI library for Haskell

2006-12-12 Thread Brian Hulley

Brian Hulley wrote:

Conal Elliott wrote:


GUIs are usually programmed in an unnatural style, in that ...


Also, suppose you have a gui consisting of an edit widget such that
when the user types something it gets lexed, parsed, and fontified as
a Haskell program, ie from the user's point of view the widget
maintains a syntax highlighted view of the code which is
continuously updated. Would your system do the lexing/parsing for
every key that was pressed or only once, when the widget needs to be
re-rendered (a typical gui for Windows would only propagate changes
and re-draw the gui (ie lex/parse/fontify) when there are no event
messages pending)?


Thinking about this more, a better example would be a gui with 2 widgets: an 
edit widget to type in code and a list widget which displays a list of top 
level functions defined in that code. (The code could be Haskell or some 
simple toy language.)
Then the question becomes: how to set things up such that the code in the 
edit widget is only parsed when the list widget (and/or edit widget) is 
asked to render it's contents rather than every time the user presses a key. 
I think perhaps the problem would be solved by the edit widget passing a 
lazy parse tree (ie an expression evaluating to the parse tree) to the list 
widget.


But an interesting thing is if you compare this to imperative guis, in the 
functional gui each widget passes lazy expressions eagerly whereas in 
imperative guis each widget passes eagerly evaluated expressions lazily ie 
functional is push messages whereas imperative is pull changes when I'm 
asked to pick or render something etc and I'm dirty. (Have I got this 
wrong?)


I imagine that the overhead of eager passing in the functional gui is a 
small price to pay for the ease of using a functional gui, since the 
important thing is that in both guis, the hard work of parsing the code in 
the edit buffer would only be done on demand, unless I'm much mistaken.


If you're still thinking of examples for your paper it would also be really 
great to see how you'd create a widget that displays the result of another 
process (eg a window that displays the output as ghc compiles a program) or 
some other example of how to use the IO monad inside a widget for those 
unfamiliar with combining arrows with monads.


It would also be useful to know more about the relationship between the 
functional gui and WxWidgets to see what characteristics an imperative gui 
toolkit must have in order to be usable with it. (Like the extremely useful 
discussion of low level details in the Fudgets thesis.)


Best regards, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Re: Aim Of Haskell

2006-12-12 Thread Brian Hulley

Kirsten Chevalier wrote:

since it's not as if anyone programs in Pascal anymore.


Yet I'm sure most people who did a computer science degree some decades ago 
remember the old joke about passing things by name or value for what it's 
Wirth... :-)


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs of components?

2006-12-03 Thread Brian Hulley

Taral wrote:

On 12/1/06, Brian Hulley [EMAIL PROTECTED] wrote:

This problem is so general (ie converting a cyclic graph into an
expression tree such that each node appears no more than once) that
I'm sure someone somewhere must already have determined whether or
not there can be a solution, though I don't know where to look or
what to search for.


I suggest you check the Functional Graph Library (FGL). It's shipped
as part of GHC.


Thanks for the suggestion. FGL itself (afaics) doesn't seem to have what I 
was looking for but graph algorithm would be a good place to start 
looking.


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs ofcomponents?

2006-12-03 Thread Brian Hulley

Paul Hudak wrote:

Brian Hulley wrote:

Anyway to get to my point, though all this sounds great, I'm
wondering how to construct an arbitrary graph of Fudgets just from a
fixed set of combinators, such that each Fudget (node in the graph)
is only mentioned once in the expression. To simplify the question,


If you consider just Dags, I believe that this question is equivalent
to asking what set of combinators will allow you to create an
arbitrary composition of functions that allow sharing inputs and
returning multiple results.  And I think that one answer to that is
the set of combinators that make up the Arrow class.  If you want to
include recursion (i.e. cycles), then you'd have to throw in
ArrowLoop (although that might only provide a nested form of cycles).
It's in this sense that Fudgets is analogous to Fruit.


Thanks. Actually thinking more about it I've probably missed the point that 
for a compositional GUI there's no need for a general graph, since each 
view/controller of the underlying model could be encapsulated as a single 
widget (eg fudget or signal transformer) which could be connected to the 
model via a loop which exposes only the model (thus allowing other views to 
be added later).


Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Strange type behavior in GHCi 6.4.2

2006-12-02 Thread Brian Hulley

Grady Lemoine wrote:

f x = x^3



f' = snd . (evalDeriv f)


When I load this in GHCi, I get:

*Main :t f
f :: (Num a) = a - a
*Main :t snd . (evalDeriv f)
snd . (evalDeriv f) :: (Num a, Num (Dual a)) = a - a
*Main :t f'
f' :: Integer - Integer

Why is the type of f' Integer - Integer, especially when the type of
the expression it's defined as is more general?  Is this something I'm
not understanding about Haskell, or is it more to do with GHC 6.4.2
specifically?


This is the monomorphism restriction, which basically says that any binding 
which just has a single variable on the left of the '=' is artificially 
forced to be monomorphic (unless you've given it an explicit type signature) 
eg:


   f = \x - x + 1-- Integer - Integer

whereas

   f x = x + 1-- Num a = a - a

The reason for this is that if you have something like:

   let x = e in (x,x)

you often expect the expression (e) to be evaluated at most once, and shared 
by the two components of the tuple. However if there were no monomorphism 
restriction, then (x) could be polymorphic hence (e) would have to be 
evaluated twice (once for each overloading, even if the result tuple is fed 
to another function which expects both elements to have the same type) which 
would make programs run slower than the programmer expected.


I couldn't find any page on the wiki about this, but there's lots of stuff 
scattered around on the web, and endless discussions in the Haskell mailing 
lists which make entertaining reading ;-)


(The MR is controversial - see 
http://hackage.haskell.org/trac/haskell-prime/wiki/MonomorphismRestriction 
for the latest on what might happen to it in future versions of Haskell.)


Brian.
--
http://www.metamilk.com 


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


[Haskell-cafe] Functional GUI combinators for arbitrary graphs of components?

2006-12-01 Thread Brian Hulley

Hi,
I've been looking at the Fudgets research 
(http://www.cs.chalmers.se/ComputingScience/Research/Functional/Fudgets/ ) 
as an example of a purely functional gui.


Afaiu a brief summary is that a Fudget can represent a GUI widget or some 
other object, which can have some internal state, and which receives and 
passes messages to the other Fudgets it is connected to. Fudgets are 
connected to each other by combinators eg:


   second == first-- sequential (first sends messages to second)
   a * b   -- parallel

There is a continuation passing implementation such that the messages are 
passed and internal states of Fudgets are updated (by replacing each fudget 
with an updated fudget) as these expressions are evaluated hence the message 
passing and maintenance of state doesn't involve any IORefs though 
interaction with external devices such as the OS uses IO.


Anyway to get to my point, though all this sounds great, I'm wondering how 
to construct an arbitrary graph of Fudgets just from a fixed set of 
combinators, such that each Fudget (node in the graph) is only mentioned 
once in the expression. To simplify the question, assume we have the 
following data structure to describe the desired graph:


   data LinkDesc a
   = Series a a
   | Broadcast a [a]
   | Merge [a] a

   type GraphDesc a = [LinkDesc a]

and a function to compute a combined object (eg Fudget) corresponding to an 
arbitrary graph would be:


   mkObj :: Ord label = Map label Obj - GraphDesc label - Obj
   mkObj = -- ???

The result of mkObj will be some expression, composed from a finite set of 
combinators applied to the named objects, but with the all important 
property that each named object appears no more than once in the expression 
(this is what allows Fudgets to correspond to notional objects which 
maintain internal state - during evaluation each fudget gets replaced by an 
updated fudget hence can only appear once in the whole expression).


As a very simple example using existing Fudgets combinators,

   type Map label value = [(label, value)]

   mkObj [(A, objA), (B, objB), (C, objC)]
   [Series A B, Series B C]

   ===objC == objB == objA

and

   mkObj [(A, objA), (B, objB), (C, objC)]
   [Broadcast A [B, C]]

   === (objB * objC) == objA

However:

   mkObj [(A, objA), (B, objB), (C, objC), (D, objD)]
   [Broadcast A [B, C], Series B D, Series A D]

   === ???

The Fudgets library provides many combinators eg for looping, but even so, I 
don't think there are sufficient combinators to express the above graph 
(though possibly extra nodes and tagging/untagging would solve this 
example), or more heavily connected graphs such as:


   [Series A B, Series B C, Series C D, Series D B, 
Series C A]


This problem is so general (ie converting a cyclic graph into an expression 
tree such that each node appears no more than once) that I'm sure someone 
somewhere must already have determined whether or not there can be a 
solution, though I don't know where to look or what to search for.


Any ideas?
Thanks, Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] Functional GUI combinators for arbitrary graphs ofcomponents?

2006-12-01 Thread Brian Hulley

Brian Hulley wrote:

Anyway to get to my point, though all this sounds great, I'm
wondering how to construct an arbitrary graph of Fudgets just from a
fixed set of combinators, such that each Fudget (node in the graph)
is only mentioned once in the expression. To simplify the question,
assume we have the following data structure to describe the desired
graph:
   data LinkDesc a
   = Series a a
   | Broadcast a [a]
   | Merge [a] a

   type GraphDesc a = [LinkDesc a]


The above is more complicated than necessary. The problem can be captured 
by:


   type GraphDesc a = [(a,a)]

Brian.
--
http://www.metamilk.com 


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


Re: [Haskell-cafe] [Haskell] Defining Cg, HLSL style vectors in Haskell

2006-11-28 Thread Brian Hulley

Slavomir Kaslev wrote:

I have to define a couple of float2, float3, float4 Cg, HLSL style
vectors in Haskell. At first I was tempted to make them instances of
Num, Floating, RealFrac, etc. but some of the functions defined in
those classes have no sense for vectors.


I'd suggest that this implies that these classes are not suitable for 
Vectors.



One such example is signum from class Num.

There are several workarounds for this. One may come up with some
meaning for vectors of such functions, for example:

instance Num Float3 where
   .
   signum a | a == Float3 0 0 0 = 0
 | otherwise = 1


This looks a bit unnatural. Also, testing equality of Floats is not 
generally recommended.




[snip]
I know that I can scrap all those Num, Floating, RealFrac, etc.
classes and define class Vector from scratch, but I really don't want
to come up and use different names for +, -, etc. that will bloat the
code.


While it may be tempting to want to use symbolic operators like + and -, 
these quickly become very confusing when more distinctions need to be made 
(eg between cross product, dot product, and scaling, or between transforming 
a position versus transforming a direction) so I'd argue that for 
readability descriptive names are better than symbols:


   class Num a = Vector v a where
   plus :: v a - v a - v a
   minus :: v a - v a - v a
   cross :: v a - v a - v a
   dot :: v a - v a - a
   scale :: a - v a - v a
   magSquared :: v a - a

   class Num a = Transform mat vec a where
   transformPosition :: mat a - vec a - vec a
   transformDirection :: mat a - vec a - vec a

   instance Num a = Transform Mat44 Vec4 a where
   -- ...

If you're doing matrix transformations, you might also like to consider 
using separate PositionN and DirectionN types instead of VecN to make use of 
the type system to catch some math bugs but I haven't looked into this 
myself yet so I don't know whether this would be practical or not.


Best regards,
Brian.
--
http://www.metamilk.com 


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


Passing arrays between Haskell and C without overhead

2006-11-26 Thread Brian Hulley

Hi,

For a 3d graphics library, I'd like to have a 4x4 matrix of floats which I 
can pass from Haskell to C without having to copy all 16 floats each time, 
something like:


   data Mat44f = Mat44f Float# Float# ... Float#

   foreign import ccall c_setWorldTransform :: Ptr Mat44f - IO ()

   setWorldTransform :: Mat44f - IO ()
   setWorldTransform mat =
   withSafePtr mat c_setWorldTransform

where

   withSafePtr :: a - (Ptr a - IO b) - IO b

would supply a pointer directly to the Haskell heap representation of (a) 
and would ensure that (a) doesn't get garbage collected until the IO action 
is completed. (Note that this is not the same as Foreign.Marshal.Utils.with, 
which uses alloca and poke to copy the matrix - I'm trying to avoid this 
overhead of copying.)


However there is no such function afaics so the only solutions at present 
seem to be to either make Mat44f an instance of Storable and use alloca 
(which involves copying all 16 floats just so that C can read it even though 
I'd expect the heap representation to already be identical since there is 
only one constructor and all fields are unboxed) or else pass the 16 floats 
individually by:


   foreign import ccall c_SetWorldTransform' :: Float# - Float# - ... - 
Float# - IO ()


   setWorldTransform (Mat44f m11 m12 m13 m14 ... m44) =
   c_SetWorldTransform' m11 m12 m13 ... m44

In this second case the C function will have to manually put these 16 floats 
back into an array so that it will have a pointer to a temporary array of 16 
floats to use internally (eg to pass to the DirectX api which will then make 
its own copy of it), so in both cases there is a wasteful deconstruction 
then reconstruction of the original array of 16 floats stored on the Haskell 
heap.


Similar problems arise when trying to pass an array from C back to Haskell, 
but in this case it's clear some copying will be needed so that one ends up 
with a value stored on the Haskell heap - the double copy problem only 
arises in the direction from Haskell to C.


I've also thought about just implementing all the math functions in C and 
using mallocForeignPtrArray so that the data type would be:


   newtype Mat44f = Mat44f (ForeignPtr CFloat)

While this would make passing between C and Haskell very fast, it seems a 
pity to have to sacrifice the ability to code the math ops directly in 
Haskell in a functional style with all the attendant optimizations one could 
expect from GHC (using ForeignPtr requires unsafePerformIO, withForeignPtr, 
and lots and lots of peek/pokeElemOff's in a monadic style - rather gross 
compared to pattern matching etc)


So my questions are:

1) Is there any reason why there can't be a function (withSafePtr) to avoid 
all this marshalling overhead when we know (or specify via a pragma) that 
Haskell stores the data already in a form compatible with C, or is there 
some other way to represent a 4x4 matrix such that it can be manipulated in 
Haskell and passed without overhead to C?


2) Does withSafePtr already exist somewhere?

3) Would it be a good idea to make Storable one of the classes which can be 
automatically derived?


Thanks, Brian.
--
http://www.metamilk.com 


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: Passing arrays between Haskell and C without overhead

2006-11-26 Thread Brian Hulley

Bulat Ziganshin wrote:

Hello Brian,

Sunday, November 26, 2006, 5:34:51 PM, you wrote:


For a 3d graphics library, I'd like to have a 4x4 matrix of floats
which I can pass from Haskell to C without having to copy all 16
floats each time, something like:


http://haskell.org/haskellwiki/Modern_array_libraries

you should use StorableArray. also, i suggest you to use ghc 6.6
because it has much faster foreign ptrs implementation. you may also
consider using my ArrayRef lib, although from that you said i don't
see that you will get any advantages from this


Hi Bulat -
Thanks for the suggestion and the link to that page - the info on it is very 
useful,


Brian.
--
http://www.metamilk.com 


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


[Haskell-cafe] Why instances can't be hidden (was: non-total operator precedence order)

2006-11-11 Thread Brian Hulley

Benjamin Franksen wrote:

Henning Thielemann wrote:

On Fri, 10 Nov 2006, Benjamin Franksen wrote:

Although one could view this as a bug in the offending module it
makes me somewhat uneasy that one additional import can have such a
drastic effect on the code in a module /even if you don't use
anything from that module/.


It's the same as with instance declarations, isn't it? I don't want
to defend the problems arising with todays anonymous instance
declarations,


Right. However, with instances I can imagine solutions that avoid
naming them, that is, I could imagine to write something like

 select instance C T1 T2 ... Tn from module M

or

 import M hiding (instance C T1 T2 ... Tn, )

Such a feature could prove extremely useful in practice.

Disclaimer: I am almost sure that there is something I have
overlooked that makes such a simple solution impossible, otherwise it
would have been proposed and implemented long ago...


I think the reason you can't do this kind of thing is that within any set of 
modules that is compiled at the same time, anywhere in any of these modules, 
if you have a type T that's an instance of class C, then all occurrences of 
C T must refer to the exact same instance declaration or else things would 
get totally messed up when/if the compiler did whole program optimization.
In other words, the instances are actually properties of the type(s) 
themselves so allowing different modules to see different implementations 
of the instances would break the conceptual merging of modules (modulo 
renaming) that occurs at compile time.


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

http://www.metamilk.com 


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


Re: ghc 6.6 for Windows crashes my program on exit

2006-10-15 Thread Brian Hulley

Brian Hulley wrote:

Hi,
Has anyone else come across this crash with ghc 6.6 on Windows?

   The thread 'Win32 Thread' (0x5c8) has exited with code 0 (0x0).
   First-chance exception at 0x7c90eb74 in main.exe: 0xC008:
  An invalid HANDLE was specified.
   Unhandled exception at 0x7c90eb74 in main.exe: 0xC008:
  An invalid HANDLE was specified.


Actually this behaviour happens even with the trivial program main = return 
() so I've submitted a bug report at 
http://hackage.haskell.org/trac/ghc/ticket/942


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

http://www.metamilk.com 


___
Glasgow-haskell-users mailing list
Glasgow-haskell-users@haskell.org
http://www.haskell.org/mailman/listinfo/glasgow-haskell-users


Re: [Haskell-cafe] Automatic fixity allocation for symbolic operators

2006-10-15 Thread Brian Hulley

Jim Apple wrote:

On 10/14/06, Brian Hulley [EMAIL PROTECTED] wrote:

User defined fixities are an enormous problem for
an interactive editor


This is the second or third time you've proposed a language change
based on the editor you're writing. I don't think this is a fruitful
avenue.



Bertram Felgenhauer wrote:

Brian Hulley wrote:

   infixr 9  .!!   99.9

Ouch.

As far as editors go I have little sympathy.



Nicolas Frisby wrote:

I think it's unreasonable to tie programmers' hands for the sake of
off-loading rather trivial tasks to editors.



J. Garrett Morris wrote:

On 10/14/06, Nicolas Frisby [EMAIL PROTECTED] wrote:

Perhaps the editor could assume a default precedence ...

I agree that changing the language in such an unintuitive way -
breaking existing code in the process - to suit an editor is
counterproductive and ridiculous.



I feel that the example I used of an interactive editor has somewhat 
eclipsed the purpose of my post, which was basically to see if there is some 
way to arrive at an agreed association of operator precedences with symbolic 
ops such that this would include the current Prelude operators and have some 
kind of intuitive extension to all other possible symbolic ops which would 
respect one's expectations that * and + should be similar to * and + in 
terms of relative precedence and absolute associativity. After all, if a 
library writer decided to make * bind more loosely than + one might 
justifiably be frustrated at the apparent inconsistency therefore why not 
just make all this systematic and fixed down to remove these problems?


I had thought perhaps someone might have already made such a global 
operator table suitable for functional programming, or some suitable 
algorithm hence the inclusion of my first stumbling attempt at one to try 
and set the ball rolling and at least save someone else several hours of 
hard work going down the same dead end if such it is.


Jim Apple wrote:


There are three ways to change Haskell's lexical structure:

1. DIY on an open-source compiler/interpreter of your choice.
2. Write your own compiler/interpreter.
3. Get the change into Haskell''.

If the Haskell'' procedure is like the Haskell' procedure, you'll have
to do 1 or 2 before you do 3.

It's possible that you will convince someone that your syntax changes
are worth doing, and that this person will do step 1 or step 2 for
you, but I don't think so. I haven't done the research myself, but I
think if you look at the source control logs for Your Favorite Haskell
Compiler/interpreter and the HCAR, you will find very few
commits/projects devoted to syntax. I think this is because Haskellers
are much more interested in semantics.


Afaiu the whole concept of type classes arose because of the desire to avoid 
having to think up different names for related functions and MPTCs were 
suggested by the syntax for single parameter TCs (though I can't remember 
the reference where I think I remember reading this latter point).




Proposing changes that break existing code or segment the Haskell code
base just doesn't seem like a win.


Since all syntactic and many semantic changes necessarily break existing 
code or segment the code base this would seem to imply that the language 
should not be changed at all or that everything must be backwards 
compatible, so that we have to drag the Achilles heel of original mistakes 
around for all eternity. I'd have thought a solution would be to just use a 
tool to automatically convert existing code to whatever new syntax is found 
to be better, thus allowing the language to be gradually perfected as more 
and more issues are brought to light.


Still I agree with you that a more sensible approach in terms of someone 
like me writing an editor is simply for me to take Haskell as an inspiration 
and incorporate my ideas in it so that any changes can later be seen in 
relation to a (hopefully facilitated and enjoyable) programming experience 
rather than trying to share my ideas piecemeal and insufficiently 
contextualized as they arise.


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

http://www.metamilk.com 


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


  1   2   3   4   5   6   >