Re: [Haskell-cafe] What Haskell Records Need

2012-08-03 Thread Jonathan Geddes
Evan Laforge wrote:
I consider that a strength of the lens approach.  If I say 'set
(a.b.c.d) 42 record', 'a', 'b' etc. don't have to be record fields, I
can swap them out for other lenses later on.

I can also easily precompose, e.g. 'setThis = a . b; setThat = b . c'
and encourage people to use the composed ones (or require via export
lists).  This corresponds to asking in that it introduces a point of
abstraction where I can change all access / modification in one place,
or a module can retain control by only exporting the composed version.

The same is true with SEC functions:

personsSalary' :: (Salary - Salary) - Person - Person
personsSalary' = job' . salary'

Here I've created a new updater that is
composed of 2 that are generated for me (from
the examples given in the original email). I
can export whichever of these functions I
like, generated or otherwise, and keep as much
abstraction as I like!

The nice part about the SEC functions is that
they compose as regular functions. Lenses are
super powerful in that they form a category.
Unfortunately using categories other than
functions feels a tad unwieldy because you
have to hide something from prelude and then
import Category. (A bit like exceptions,
currently).

If you like the look of set with lenses,
you could define a helper function to use
with SEC updaters.

set :: ((b - a) - c) - a - c
set sec = sec . const

--and then use it like so:
setPersonsSalary :: Salary - Person - Person
setPersonsSalary salary = set personsSalary' salary

With it you can use an updater as a setter.
I'd like to reiterate one of finer points of
the original proposal.

The compiler could disallow using old-style
update syntax for fields whose SEC update
function is not in scope, giving us
fine-grained control over access and update.
On the other hand we currently have to create
new functions to achieve this (exporting the
getter means exporting the ability to update
[using update syntax] as well, currently).

And now back to lenses:

it is really convenient how lenses let you compose the getter
and setter together.

I don't recall too many cases where having the
getter and setter and modifier all in one
place was terribly useful. Could anyone give
me an example? But again, where that is
useful, a lens can be created from a getter
and a SEC updater.

Thoughts?

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


Re: [Haskell-cafe] What Haskell Records Need

2012-08-02 Thread Jonathan Geddes
Richard O'Keefe Said:
 Ouch! And that's not even very deeply nested.
 Imagine 4 or 5 levels deep. It really makes
 Haskell feel clunky next to `a.b.c.d = val`
 that you see in other languages.

I was taught that this kind of thing violates the Law of Demeter
and that an object should not be mutating the parts of an
acquaintance's parts, but should ask the acquaintance to do so.
I'd say that a.b.c.d = val is at the very least a sign that
some encapsulation did not happen.

Absolutely! But in Haskell how do you do the
asking? I guess that's what I'm proposing is
a built in way of doing just that! I'm
shooting for as-easy-as the built in getters.

Erik Hesselink said:
Isn't this exactly the problem solved by all the lens packages?

Yes it is. I think the existence of these
packages along with all the proposals to
change records is an indication that
something is missing from the language as a
whole. What I'm proposing is that the
language give you something that is
lightweight and easy to use to address this
issue. You can still use lenses on top of all
of this.

 makeLens myField myField'

If I remember correctly, one of the problems
with lenses is that they cannot support
polymorphic updates (updates which change a
type variable of the data). SEC functions, on
the other hand support polymorphic updates.

--Jonathan

On Thu, Aug 2, 2012 at 4:48 AM, Andrew Butterfield 
andrew.butterfi...@scss.tcd.ie wrote:

 Ah yes - the joy of Haskell

 It so easy to roll your own, rather than search to find someone else's
 (better/more elegant) solution...   :-)


 On 2 Aug 2012, at 11:41, Erik Hesselink wrote:

  On Thu, Aug 2, 2012 at 12:30 PM, Andrew Butterfield
  andrew.butterfi...@scss.tcd.ie wrote:
 
  On 2 Aug 2012, at 09:25, Erik Hesselink wrote:
 
  Isn't this exactly the problem solved by all the lens packages?
  Current popular ones are fclabels [0] and data-lens [1].
 
  [0] http://hackage.haskell.org/package/fclabels
  [1] http://hackage.haskell.org/package/data-lens
 
  Not sure what all of these do, but I have a simple solution I use
  in my work:
 
  They do exactly that. They create 'lenses' which are
  getters/setters/modifiers combined, and allow you to compose these to
  get/set/modify deep inside nested data types. Look at the examples in
  the fclabels documentation [2] for more details.
 
  [2]
 http://hackage.haskell.org/packages/archive/fclabels/1.1.4/doc/html/Data-Label.html

 
 Andrew Butterfield Tel: +353-1-896-2517 Fax: +353-1-677-2204
 Lero@TCD, Head of Foundations  Methods Research Group
 Director of Teaching and Learning - Undergraduate,
 School of Computer Science and Statistics,
 Room G.39, O'Reilly Institute, Trinity College, University of Dublin
   http://www.scss.tcd.ie/Andrew.Butterfield/
 


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

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


[Haskell-cafe] What Haskell Records Need

2012-08-01 Thread Jonathan Geddes
Greetings,

tl;dr - What Haskell Records need are
semantic editor combinators for free.

I know this is yet another Record proposal
among many, but none of them out there
strike me as being exactly what I want in
Haskell.

Take the following types from a contrived
example.

type Salary = Integer

data Job = Job
  { title  :: String
  , salary :: Salary
  }

data Person = Person
  { name :: String
  , job  :: Job
  }

Since I've used record syntax, I get
getter/accessor functions (title, salary,
name, job) for free. Now suppose I want to
create an aggregate getter function: return
the salary of a given person. Piece of cake,
it's just function composition

getSalary :: Person - Salary
getSalary = salary . job

Done! Now suppose I want to write a
setter/mutator function for the same nested
field

setSalaryMessy :: Salary - Person - Person
setSalaryMessy newSalary person =
  person {
job = (job person) {
  salary = newSalary
}
  }

Ouch! And that's not even very deeply nested.
Imagine 4 or 5 levels deep. It really makes
Haskell feel clunky next to `a.b.c.d = val`
that you see in other languages. Of course
immutability means that the semantics of
Haskell are quite different (we're creating
new values here, not updating old ones) but
it's still common to model change using these
kinds of updates.

What if along with the free getters that
the compiler generates when we use record
syntax, we also got semantic editor
combinator (SEC) functions[0] that could be
used as follows?

setSalary newSalary = job' $ salary' (const newSalary)

giveRaise amount = job' $ salary' (+amount)

givePercentRaise percent = job' $ salary' (*(1+percent))

For each field x, the compiler generates a
function x' (the tic is mnemonic for change).
These little functions aren't hard to write,
but they're classic boilerplate.

job' :: (Job - Job) - Person - Person
job' f person = person {job = f $ job person}

salary' :: (Salary - Salary) - Job - Job
salary' f job = job { salary = f $ salary job}

These type of utility functions are a dream
when working with any reference type or
State Monad.

 modify $ givePercentRaise 0.25

The compiler could also generate polymorphic
SEC functions for polymorphic fields.
Further, the compiler could disallow using
old-style update syntax for fields whose SEC
update function is not in scope, giving us
fine-grained control over access and update.
On the other hand we currently have to create
new functions to achieve this (exporting the
getter means exporting the ability to update
as well, currently).

Of course this doesn't address the
namespacing issues with records, but it is
likely nicely orthogonal to other proposals
which do.

Also note that there's a package on hackage [1]
that will generate SEC functions using TH.
It's nice, but I prefer the style of field
names used above for updaters (field' vs
editField).

Let me know what you think. I'll write up an
official proposal if there's a bit of
general interest around this.

Thanks for reading,

--Jonathan

[0] - http://conal.net/blog/posts/semantic-editor-combinators
[1] -
http://hackage.haskell.org/packages/archive/sec/0.0.1/doc/html/Data-SemanticEditors.html
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Best way to build a GHC backend?

2012-07-09 Thread Jonathan Geddes
Thanks for all the Info, Brent! I wasn't aware of many of those projects.

I agree that contributing to an existing project is a better idea than
doing something new. I suppose I was hoping there would be an official GHC
JavaScript backend so that it would be clear which of the efforts to
contribute to (and use).

-J Arthur

On Mon, Jul 9, 2012 at 8:38 AM, Brent Yorgey byor...@seas.upenn.edu wrote:

 On Sun, Jul 08, 2012 at 09:21:08AM -0600, Jonathan Geddes wrote:
  I agree that the Raison d'être for a .NET or JVM backend is interop.
  Perhaps that's not worth the effort of an entirely new backend.
 JavaScript
  is a different beast, however.  I said before:
 
  From my point of view, languages that cannot run on one of the 3
   aforementioned platforms will become irrelevant. (with the exception of
  C,
   of course).
 
  I'll take that one step further and say that for web applications it is
  becoming increasingly difficult to justify using a language that WILL NOT
  run both client and server. JavaScript (with NodeJS), Clojure (with
  ClojureScript), and Dart are just a few examples.
 
  I really believe that with a solid JavaScript backend, Haskell would be
 an
  ideal web application language. Am I alone in that belief? What can I do
 to
  get the ball rolling on that?

 I should point out that the ball already IS rolling -- ranging from
 EDSLs that compile to JavaScript [1,2] to macro systems [3] to more
 serious full-featured efforts [4,5].  There's even a wiki page listing
 all these and more [6].  The yesod developers share your view that
 Haskell would benefit from some sort of JavaScript backend; see [7] as
 well as the ensuing discussion on Reddit [8]. See also Elm [9], which
 compiles to HTML+CSS+JavaScript and has some Haskell integration [10].

 Rather than trying to start yet another effort, what about
 contributing to one of these ongoing ones?

 -Brent

 [1] http://www.ittc.ku.edu/csdlblog/?p=88
 [2] http://www.ittc.ku.edu/csdl/fpg/node/125
 [3] http://www.haskell.org/haskellwiki/JMacro
 [4] http://uu-computerscience.github.com/uhc-js/
 [5] https://github.com/ghcjs/ghcjs
 [6] http://www.haskell.org/haskellwiki/The_JavaScript_Problem
 [7] http://www.yesodweb.com/blog/2012/04/client-side
 [8]
 http://www.reddit.com/r/haskell/comments/sm72n/client_side_yesod_an_frpinspired_approach/
 [9] http://elm-lang.org/
 [10]
 http://www.reddit.com/r/haskell/comments/uugne/announcing_elm_02_haskell_integration_yesod/

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

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


Re: [Haskell-cafe] Best way to build a GHC backend?

2012-07-08 Thread Jonathan Geddes
I agree that the Raison d'être for a .NET or JVM backend is interop.
Perhaps that's not worth the effort of an entirely new backend. JavaScript
is a different beast, however.  I said before:

From my point of view, languages that cannot run on one of the 3
 aforementioned platforms will become irrelevant. (with the exception of
C,
 of course).

I'll take that one step further and say that for web applications it is
becoming increasingly difficult to justify using a language that WILL NOT
run both client and server. JavaScript (with NodeJS), Clojure (with
ClojureScript), and Dart are just a few examples.

I really believe that with a solid JavaScript backend, Haskell would be an
ideal web application language. Am I alone in that belief? What can I do to
get the ball rolling on that?

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


[Haskell-cafe] Best way to build a GHC backend?

2012-07-07 Thread Jonathan Geddes
Venerable Haskell Hackers,

I love Haskell and think it should run everywhere. Now supposing I would
like to build another backend for GHC, perhaps for Java Bytecode, .Net CIL,
or JavaScript, What would be the best way to approach that? I can think of
a few options:

1. Produce External Core with -fext-core and compile that with a completely
separate compiler
2. Use the GHC apis to build a compiler that reuses a load of GHC's code,
but has it's own backend
3. Add a new backend directly into GHC

Any other options?

While I'm on the subject, why has Haskell not been ported to the likes of
the JVM, .NET CLR, or JavaScript? Are Haskell's non-strict semantics just
too different from the semantics of these other platforms?

SPJ is known for saying that Haskell's plan for world domination is support
for many parallelism/concurrency idioms. I believe running on many
platforms is just as important. From my point of view, languages that
cannot run on one of the 3 aforementioned platforms will become irrelevant.
(with the exception of C, of course).

Thoughts?

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


Re: [Haskell-cafe] ghci session slows down over time.

2012-06-25 Thread Jonathan Geddes
Thanks for the responses.

I am using GHC 7.4.1 an Ubuntu.

Shutting down and restarting ghci is my current workaround. I was hoping
for something a bit less disruptive. :kickoffGC or something like that.

--J Arthur



On Mon, Jun 25, 2012 at 6:54 AM, Ketil Malde ke...@malde.org wrote:

 Jonathan Geddes geddes.jonat...@gmail.com writes:

  Is this a known issue? More importantly, is there a known workaround?

 My experience is that ghci (typically run as an inferior Emacs process)
 often retains a lot of memory.  Thus, I occasionally kill and
 restart it. (Not sure if that counts as a workaround :-)

 -k
 --
 If I haven't seen further, it is by standing in the footprints of giants

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


[Haskell-cafe] ghci session slows down over time.

2012-06-24 Thread Jonathan Geddes
Haskell Cafe,

I'm seeing crazy amounts of slowdown in a ghci session after just a few
executions of :r (reload). Using :set +r (revert top-level bindings)
doesn't seem to help.

Is it possible that the dynamically-loaded object code is not being garbage
collected?

Is this a known issue? More importantly, is there a known workaround?

Thanks,

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


[Haskell-cafe] Martin Odersky on What's wrong with Monads

2012-06-23 Thread Jonathan Geddes
Cafe,

I was watching a panel on languages[0] recently and Martin Odersky (the
creator of Scala) said something about Monads:

What's wrong with Monads is that if you go into a Monad you have to change
your whole syntax from scratch. Every single line of your program changes
if you get it in or out of a Monad. They're not polymorphic so it's really
the old days of Pascal. A monomorphic type system that says 'well that's
all I do' ... there's no way to abstract over things.  [0, 53:45]

Thoughts?

--J Arthur

[0] - http://css.dzone.com/articles/you-can-write-large-programs
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] How do people still not understand what FP is about? What are we doing wrong?

2012-06-18 Thread Jonathan Geddes
I believe you are observing and commiserating over what Paul Graham
famously refers to as the blub paradox[0].

Here is the problem from my perspective. It is a bootstrapping problem: you
have to think FP is good to invest the time to learn it, but you have to
invest a lot of time to learn it before you think it's good. This may be
why FP has found a place in academia--loads of smart people who want to
learn for the shear joy of learning.

In my experience, it is often useful to provide a person with another
motive to learn FP. If you can get them to learn anything at all, you can
hope to get the bootstrapping process going. For example, one friend of
mine really enjoys a good debate, but he really couldn't argue with me when
it came to FP and so he went off to learn it. Now we argue about Haskell vs
Scala for much more time than is productive, but he is sold on FP. In
another case a junior programmer asked me how he could be more productive
and I told him to learn FP.

Anyway, I don't think things are not as bleak as you might think. See, for
example [1]'s headline for the month of June.  While not exactly
scientific, it is encouraging.

[0] - http://www.paulgraham.com/avg.html
[1] - http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html

-J Arthur

On Mon, Jun 18, 2012 at 1:59 PM, Ben Kolera ben.kol...@gmail.com wrote:

 Saw this float by in twitter, and it made me a bit sad. Obviously this is
 still a large misunderstanding of FP in the larger programming community
 and it make me wonder what we FP enthusiasts are doing wrong to not get the
 message out to people.

 Programming languages that require random senseless voodoo to get an
 effect are awesome. Let's make programming hard through poor design. [1]

 The sad thing about this is that the inverse of this has more truth to it;
 that languages that allow people to intersperse side effects anywhere in
 their computation without thought are flawed by design and allow
 programmers to do stupid things that hinder the composability, thread
 safety and ability to reason of/about their code.

 Has anyone had any experience / success with convincing people that the
 senseless voodoo is actually a boon rather than a bane?

 Is it even worth trying to convince people so set in their ways?

 ( Sorry if this is even too off-topic for the cafe. Just needed a place to
 vent my frustration at this. )

 Cheers,
 Ben

 [1] https://twitter.com/cwestin63/status/214793627170390018



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

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


Re: [Haskell-cafe] Requesting Feedback: I Love Haskell, but can't find a place to use it

2012-05-31 Thread Jonathan Geddes
Thanks for the responses, everyone.

J. W. wrote:
have you considered your head as such a place that should be easy to
find.
 even just for specifying things, Haskell is tremendously useful.
even if you don't write programs, but just their types.
you can express your software design that way,
 and have it formally verified (by the compiler's type checker).

Yes! And in fact this is exactly how I use Haskell now (aside from little
scripts and such). It has had a HUGE effect on the way I write software.
There have been a number of times that a colleague has asked what a strange
comment was in my Java[Script] code. When I tell them that the funny
looking one-liner is the Haskell equivalent of the following 30+
Java[Script] lines, they are incredulous, to say the least. But taking that
beautiful Haskell one-liner and manually transcribing it into an imperative
language feels like being a human compiler. My favorite example of this was
the use of the power set in JavaScript:

//powerSet = filterM (const [True, False])

and then a few dozen JavaScript lines it compiled down to via the human
compiler.

--J Arthur


On Thu, May 31, 2012 at 8:41 AM, Ivan Perez ivanperezdoming...@gmail.comwrote:

 On 31 May 2012 01:30, Jonathan Geddes geddes.jonat...@gmail.com wrote:
  I love Haskell. It is my absolute favorite language. But I have a very
 hard
  time finding places where I can actually use it!
 This has been bugging me for years and, like you, I think we ought to
 lean towards web-pages and mobile devices.

 Yesod has been a tremendous push forward in this direction but, as you
 already stated, the browser and android devices remain mostly
 unexplored in Haskell. Here's my bit:

 - There's a port of ghc for iphone.
 - There's frege (http://code.google.com/p/frege/), a non-strict, pure,
 functional programming language in the spirit of Haskell.
 - I've been working as a freelance developer for some time now. I
 focus on desktop apps in Haskell. I can't say I'm overwhelmed by the
 amount of offers (speaking of which, if anyone needs a freelance
 haskell developer,... ahem), but this area will not be clinically
 dead as long as we cannot use web applications knowing (99% sure)
 that the owner of the website cannot use our personal information for
 any purpose other than giving us our service. There's only two kinds
 of clients here, though: those that explicitly want Haskell, and those
 than don't care about the programming language. Otherwise, you'll have
 to sell Haskell and, personally, I'm not that good a salesman (10%
 success, tops).
 - I've also ported Haskell designs to other programming languages
 (with small adaptations). I only found this cost-effective because the
 code in Haskell was not going to be thrown away.

 Good luck. Please, let us know what you find.

 Cheers,
 Ivan.

  I had hoped that compiling Haskell to C with -fvia-C (or would it be just
  -C?) would allow Haskell to run in new, uncharted territory such as
 Android
  (with NDK), IOS, Google's NaCl, etc. But today I learned that GHC's C
  backend has been deprecated!  Is it more difficult than I am imagining to
  get Haskell to work in these environments? Is it simply a matter of low
  interest in this kind of work? Or something more fundamental? Am I
 missing
  something?
 
  I'm hoping that the Haskell-JavaScript efforts will mature enough to
 make
  Haskell viable for client-side web apps. (I think the first sign of this
  will be a self-hosting Haskell-JavaScript compiler.)
 
  I use Haskell for Server-Side code with various web frameworks, but over
 the
  years more and more of the app logic is moved into client-side
 JavaScript,
  leaving the server-side code as little more than a simple validation and
  security layer over the database and other services. Haskell doesn't have
  any trouble with this, of course, but it's not exactly a role where it
 can
  shine. (Of course this is not true of ALL server-side code, just the
 kind of
  apps I have been writing.)
 
  So anyway I'd like to request feedback: where can I use Haskell besides
  simple CLI utilities, dull server code, or project Euler problems? Even
 if
  it's just to contribute to getting Haskell in the environments mentioned
  above, any feedback is welcome!
 
  Thanks for reading,
 
  --J Arthur
 
  ___
  Haskell-Cafe mailing list
  Haskell-Cafe@haskell.org
  http://www.haskell.org/mailman/listinfo/haskell-cafe
 

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


[Haskell-cafe] Most Important GHC extensions to learn/use?

2012-05-31 Thread Jonathan Geddes
Haskell Hackers,

I'm pretty comfortable with all of Haskell 98 (and 2010, really). But I've
always sort of avoided extensions. I realize that this is a bit silly and
if I want to continue learning, it probably means delving into the
extensions. Which ones are the most important to know from a practical
point of view? And which ones from a {Language,Category,Math}-theoretical
point of view? (Any other interesting/important points of view I'm missing?
:D )

As always, thanks for the feedback.

Cheers,

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


Re: [Haskell-cafe] Most Important GHC extensions to learn/use?

2012-05-31 Thread Jonathan Geddes
Thanks, Wren, I really appreciate the detailed response! Though I am
surprised that Template Haskell isn't on your list. From the little I know
of TH it seems like all of the interesting generic/generative stuff is done
with TH. Do the other extensions subsume the need for TH, or is it just not
terribly interesting?

--J Arthur

On Thu, May 31, 2012 at 10:29 PM, wren ng thornton w...@freegeek.orgwrote:

 On 5/31/12 7:15 PM, Jonathan Geddes wrote:

 Haskell Hackers,

 I'm pretty comfortable with all of Haskell 98 (and 2010, really). But I've
 always sort of avoided extensions. I realize that this is a bit silly and
 if I want to continue learning, it probably means delving into the
 extensions. Which ones are the most important to know from a practical
 point of view? And which ones from a {Language,Category,Math}-**
 theoretical
 point of view? (Any other interesting/important points of view I'm
 missing?
 :D )


 There are a bunch which are mostly just syntax changes. The important ones
 are:

ForeignFunctionInterface (aka FFI)
Not technically part of H98, though it was a quick addition. It
is part of H2010, so it's not really an extension anymore.

ScopedTypeVariables
This one's really easy, and in the cases where you want it you
really really want it.

KindSignatures
This one's simple, and it helps expose you to the idea of
kinds, which is helpful for what's to come.

TypeOperators
This one's trivial, but it makes things a bit prettier.

FlexibleContexts, FlexibleInstances
These are essential for actually using MPTCs (described below).
IMO they should be enabled automatically whenever MPTCs are on.

 And there are also a bunch of ones about extending the deriving mechanic
 to work with new classes or with newtypes.


 Then there are the ones that actually change the language in a significant
 way. I'd say the critical ones to learn are:

RankNTypes (or Rank2Types if you're squeamish)
This is used in lots of nice tricks like list fusion. Learning
list fusion is a good place for the H98 veteran to explore
next, since it's easy to pick up and has many applications
outside of just doing list fusion. Also, it's been around
forever and isn't going anywhere anytime soon.

MultiParamTypeClasses (aka MPTCs)
This has been around forever, and is considered standard
Haskell by most people, even though it hasn't made it into the
Report yet (due the the fundeps vs TFs issue).

FunctionalDependencies (aka fundeps)
This is helpful for making certain MPTCs usable without too
many type signatures. Also, it's good for understanding the
fundeps vs TFs issue. Also, this one has been around forever,
and although it's fallen into disfavor it is still
indispensable due to limitations in TFs.

TypeFamilies (aka TFs)
These are really nifty and they're all the rage these days. In
a formal sense they're equivalent to fundeps, but in practice
they're weaker than fundeps.

GADTs
These are really nifty and they're all the rage these days.
Though beware, GADTs are a rabbit hole leading off to the world
of dependent types. You should be aware of the basic ideas
here, though don't worry too much about the theory (unless you
want to spend a lot of time worrying about the theory).

 --
 Live well,
 ~wren

 __**_
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/**mailman/listinfo/haskell-cafehttp://www.haskell.org/mailman/listinfo/haskell-cafe

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


[Haskell-cafe] Requesting Feedback: I Love Haskell, but can't find a place to use it

2012-05-30 Thread Jonathan Geddes
I love Haskell. It is my absolute favorite language. But I have a very hard
time finding places where I can actually use it!

I had hoped that compiling Haskell to C with -fvia-C (or would it be just
-C?) would allow Haskell to run in new, uncharted territory such as Android
(with NDK), IOS, Google's NaCl, etc. But today I learned that GHC's C
backend has been deprecated!  Is it more difficult than I am imagining to
get Haskell to work in these environments? Is it simply a matter of low
interest in this kind of work? Or something more fundamental? Am I missing
something?

I'm hoping that the Haskell-JavaScript efforts will mature enough to make
Haskell viable for client-side web apps. (I think the first sign of this
will be a self-hosting Haskell-JavaScript compiler.)

I use Haskell for Server-Side code with various web frameworks, but over
the years more and more of the app logic is moved into client-side
JavaScript, leaving the server-side code as little more than a simple
validation and security layer over the database and other services. Haskell
doesn't have any trouble with this, of course, but it's not exactly a role
where it can shine. (Of course this is not true of ALL server-side code,
just the kind of apps I have been writing.)

So anyway I'd like to request feedback: where can I use Haskell besides
simple CLI utilities, dull server code, or project Euler problems? Even if
it's just to contribute to getting Haskell in the environments mentioned
above, any feedback is welcome!

Thanks for reading,

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


Re: [Haskell-cafe] Some thoughts on Type-Directed Name Resolution

2012-02-09 Thread Jonathan Geddes

   modifyConfig :: (Config - a) - (a - a) - Config - Config
   modifyConfig fr fv a = a { fr = fv (fr a)


I like this Idea. The only problem I see is this: if I'm trying to write
code that is very generic and abstract, how does the compiler know if the
update

 a { fr = 5 }

is targeting a field fr of the record a, or a variable fr, which is in
scope and points to a first-class field. The difference depends on the
record in question, so the code would work differently depending on the
context. I would think it would have to be something like

 a { :fr = 5 }

or something else syntactically distinct from current record update syntax.

With this and a few more conveniences on record syntax, lenses could go
away. For example, I'd love to see a lambda update syntax. For example
instead of:

 setName n r = r {name = n}

we'd write

 setName n = \{name = n}

I'd also like to see an Update field by syntax. Instead of

 addMr r = r { name = Mr.  ++ (name r) }

we'd write

 addMr r = r { name = (Mr. ++) }

or combining the previous 2:

 addMr = \{name=(Mr. ++)}

feels very terse and Haskelly to me.

Regards,

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


[Haskell-cafe] Get a variable's type in quasiquote

2012-01-05 Thread Jonathan Geddes
Cafe,

I'm playing around with Template Haskell, specifically QuasiQuotes and I've
run into something that I hope is not an inherent limitation in TH.

Specifically I want to get the type of a variable whose name is used in a
QuasiQuote. The code generated by the QQ should depend on the type of the
variables that are to be antiquoted.

For example

let a = True
in [qq | a |]

should result in different code being generated by the qq than

let a = 42
in [qq | a |]

because the type of variable a is different.

So far I've tried simple reification, but

 quote = do
let varname = someVariableKnownToExist
info - reify $ mkName str
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Get a variable's type in quasiquote

2012-01-05 Thread Jonathan Geddes
Oops I didn't get to finish... accidentally sent. Here's the completed
version:

I'm playing around with Template Haskell, specifically QuasiQuotes and I've
run into something that I hope is not an inherent limitation in
TH.Specifically I want to get the type of a variable whose name is used in
a QuasiQuote. The code generated by the QQ should depend on the type of the
variables that are to be antiquoted.

For example

let a = True
in [qq | a |]

should result in different code being generated by the qq than

let a = 42
in [qq | a |]


because the type of variable a is different.

So far I've tried simple reification

 quote str = do
   let varname = someVariableKnownToExist
   info - reify $ mkName str
   ...

but this results in `someVariableKnownToExists' is not in scope at a reify

any thoughts?

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


[Haskell-cafe] Type System vs Test Driven Development

2011-01-05 Thread Jonathan Geddes
Cafe,

In every language I program in, I try to be as disciplined as possible
and use Test-Driven Development. That is, every language except
Haskell.

There are a few great benefits that come from having a comprehensive
test suite with your application:

1. Refactoring is safer/easier
2. You have higher confidence in your code
3. You have a sort of 'beacon' to show where code breakage occurs

Admittedly, I don't believe there is any magical benefit that comes
from writing your tests before your code. But I find that when I don't
write tests first, it is incredibly hard to go back and write them for
'completed' code.

But as mentioned, I don't write unit tests in Haskell. Here's why not.

When I write Haskell code, I write functions (and monadic actions)
that are either a) so trivial that writing any kind of unit/property
test seems silly, or are b) composed of other trivial functions using
equally-trivial combinators.

So, am I missing the benefits of TDD in my Haskell code?

Is the refactoring I do in Haskell less safe? I don't think so. I
would assert that there is no such thing as refactoring with the style
of Haskell I described: the code is already super-factored, so any
code reorganization would be better described as recomposition. When
recomposing a program, its incredibly rare for the type system to
miss an introduced error, in my experience.

Am I less confidence in my Haskell code? On the contrary. In general,
I feel more confident in Haskell code WITHOUT unit tests than code in
other languages WITH unit tests!

Finally, am I missing the error beacon when things break? Again I
feel like the type system has got me covered here. One of the things
that immediately appealed to me about Haskell is that the strong type
system gives the feeling of writing code against a solid test base.

The irony is that the type system (specifically the IO monad) force
you to structure code that would be very easy to test because logic
code is generally separated from IO code.

I explained these thoughts to a fellow programmer who is not familiar
with Haskell and his response was essentially that any language that
discourages you from writing unit tests is a very poor language. He
(mis)quoted: compilation [is] the weakest form of unit testing [0].
I vehemently disagreed, stating that invariants embedded in the type
system are stronger than any other form of assuring correctness I know
of.

I know that much of my code could benefit from a property test or two
on the more complex parts, but other than that I can't think that unit
testing will improve my Haskell code/programming practice. Am I
putting too much faith in the type system?

[0] http://blog.jayfields.com/2008/02/static-typing-considered-harmful.html

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


Re: [Haskell-cafe] Type System vs Test Driven Development

2011-01-05 Thread Jonathan Geddes
 The Haskell type system is simply not rich enough to guarantee everything you 
 might need.

That's true, and after giving this a bit more thought, I realized it's
not JUST the type system that I'm talking about here. There are a few
other features that make it hard for me to want to use unit/property
tests.

For example, say (for the sake of simplicity and familiarity) that I'm
writing the foldl function. If I were writing this function in any
other language, this would be my process: first I'd write a test to
check that foldl returns the original accumulator when the list is
empty. Then I would write code until the test passed. Then I would
move on to the next property of foldl and write a test for it. Rinse
repeat.

But in Haskell, I would just write the code:

 foldl _ acc [] = acc

The function is obviously correct for my (missing) test. So I move on
to the next parts of the function:

foldl _ acc [] = acc
foldl f acc (x:xs) = foldl f (f acc x) xs

and this is equally obviously correct. I can't think of a test that
would increase my confidence in this code. I might drop into the ghci
repl to manually test it once, but not a full unit test.

I said that writing Haskell code feels like writing code against a
solid test base. But I think there's more to it than this. Writing
Haskell code feels like writing unit tests and letting the machine
generate the actual code from those tests. Declarative code for the
win.

Despite all this, I suspect that since Haskell is at a higher level of
abstraction than other languages, the tests in Haskell must be at a
correspondingly higher level than the tests in other languages. I can
see that such tests would give great benefits to the development
process. I am convinced that I should try to write such tests. But I
still think that Haskell makes a huge class of tests unnecessary.

 Haskell has some awesome testing tool, and I highly recommend getting
 acquainted with them.

I will certainly take your advice here. Like I said, I use TDD in
other languages but mysteriously don't feel its absence in Haskell. I
probably need to get into better habits.

--Jonathan

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


Re: [Haskell-cafe] Template Haskell a Permanent solution?

2010-12-28 Thread Jonathan Geddes
On Tue, Dec 28, 2010 at 8:17 AM, Tillmann Rendel
ren...@mathematik.uni-marburg.de wrote:
 This seems simple enough to me, so it looks as if your use case is already
 supported as a library on top of the more general API.

This is exactly what I was looking for, and much simpler than my
previous experiences with quasiQuoters.

In the original post I said, It may very well be that I am simply not
experienced enough with TH to fully appreciate and embrace it. More
and more I am thinking this is the case. I'll have to give TH a more
thorough look.

BTW, in addition to the resources already given, can anyone suggest
materials for my aforementioned more thorough look?

Thanks again for the responses.

--Jonathan

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


Re: [Haskell-cafe] Template Haskell a Permanent solution?

2010-12-27 Thread Jonathan Geddes
On Mon, Dec 27, 2010 at 12:44 AM, Henning Thielemann
lemm...@henning-thielemann.de wrote:
 I think it would be enough, if the compiler could be told to unfold an
 expression like
  parse text in a domain specific language
  at compile time.

I'm afraid I have to disagree with you here. Being able to specify
that the string should be parsed at compile time is only half of the
equation in my mind. The other half is the clean syntax for multi-line
strings.

Haskell already has great syntax for specifying data in a declarative
manner. Especially in contrast with ie Java/C++. Even as good as the
dynamic languages ie JavaScript/Python/Ruby. When you add the ability
to specify data in ANY syntax you can parse, Haskell is clearly the
best. But the complexity of TH detracts from the elegance of this
greatly in my opinion. And wrapping your data in string syntax,
multi-line or otherwise, detracts from the elegance as well. A syntax
has to be less painful or more convenient or more
readable/maintainable than literal list/record syntax before it is
useful.

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


Re: [Haskell-cafe] Template Haskell a Permanent solution?

2010-12-27 Thread Jonathan Geddes
On Mon, Dec 27, 2010 at 1:14 AM, Stephen Tetley
stephen.tet...@gmail.com wrote:

 By this are you meaning to add quasiquoting to the language Haskell
 or the Glasgow Haskell, taking it out of the domain of Template
 Haskell?

I believe that all new features should start as extensions and as an
extension, these things could coexist with TH. I just can't see TH
becoming standard. I think something much simpler that accomplishes
the common uses of TH is more likely to make it into Haskell'
20[1-2]x.

--Jonathan

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


Re: [Haskell-cafe] Template Haskell a Permanent solution?

2010-12-27 Thread Jonathan Geddes
Thanks, everyone, for the responses.

 I don't understand why the library/extension duality is a problem.

I don't think it is a _problem_ it just feels strange to me. Maybe I'm
misunderstanding, is it possible to use TH without using the library
components?

 Shouldn't specialized features be defined in terms of general features?

Absolutely, but usually don't you use the specialized features over
general ones where you can? For example, I don't often (if ever) use
the general feature of the goto statement in C. Instead I use
conditionals, loops, and functions. I don't often write explicitly
recursive functions in Haskell, rather I use map, filter, fold, etc.
whenever the structure of the recursion allows.

 How does this differ from the current QuasiQuotes extension? From what I can
 tell, all you need to achieve this with TH is to automatically derive a
 Language.Haskell.TH.Lift instance for JsonObject, i.e. a  function lift ::
 JsonObject - Q Exp such that the expression will evaluate to the original
 JsonObject. A QuasiQuoter like the one you describe can then be created by
 QuasiQuoter { parseExp = lift . json }.

Right, it's not a lot of extra work. But it's enough that in most
cases, I stick with constructing records or using other built-in
syntax.

 Should both approaches be supported
 directly, or should we sacrifice the generality of the current quoters for
 the simplicity of the ones you suggest?

No, I don't think TH should be sacrificed. I just think more specific
(and more simple) features might be nice in place of some of TH's
specific uses.

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


[Haskell-cafe] Template Haskell a Permanent solution?

2010-12-26 Thread Jonathan Geddes
Cafe,

First let me say that Template Haskell is very powerful and a lot of
great work has been done in this area. It fills in a number of holes
in Haskell's feature set.

But TH gives me the same feeling as other language features that have
been described as bolted on. Also, TH is both library and built-in
syntax (via an extension) which feels strange to me. Finally, It's
very complicated to do some simple things.

I see TH used most for the following tasks:

#1 Parse a string at compile-time so that a custom syntax for
representing data can be used. At the extreme, this data might even
be an EDSL.
#2 Provide instances automatically.

I would propose that more specialized features be implemented to
accomplish these tasks. To start, I'll throw out some ideas that
provide these capabilities.

For TH use #1, compile-time parsing of arbitrary strings, I think it
would be nice for quasiquote semantics to be modified so that code
like

 json :: String - JsonObject
 json = ...

 data = [ json |
{ name : Jonathan
, favorite language: Haskell
}
|]

causes the function json to be called at compile time with a string
argument of{\name\ : \Jonathan\\n   , \favorite language\:
\Haskell\\n   }. The whole expression being then replaced with the
result of the function application. What I like about this is that
defining quasiquoters is trivial. They're just functions of the form
String - a. Many such quasiquoters already exist and would be ready
for use! I imagine certain rules would apply, ie a quasiquoter must be
defined prior to use and in a separate module, etc.

For TH use #2, automatic instances, I would propose a way of declaring
that a class can be automatically derived, and therefore added to the
set [Eq, Ord, Show, Read, ... , etc]. This is the set of classes that
can be put in the deriving clause of a type declaration. I don't
know exactly what the syntax for this would look like, but I imagine
it would look a bit like the various current implementations of
automatic instances in TH.

Again, TH is very powerful, and fills in a number of holes in
Haskell's feature set. But it leaves me wondering if these holes
should not be filled in by other, more specialized features, leaving
TH to continue to find other holes to fill.

I'm wondering if others see TH as a permanent solution, or if you
agree with me that some of TH's most common usages should have more
specialized features dedicated to them. It may very well be that I am
simply not experienced enough with TH to fully appreciate and embrace
it.

By the way, did I miss any uses of TH as common as the ones I mentioned?

--Jonathan

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


Re: [Haskell-cafe] Do we need Monad fail (or MonadFail)?

2010-12-21 Thread Jonathan Geddes
I'd love for the compiler to give an error (or maybe just a warning)
in the case that I have a pattern match in a monad that just blows up
(throws an exception) on a pattern match failure.

Currently there's no way to know the behavior of failed pattern match
failures without looking at the instance for the current monad. And
what if you're writing monad agnostic (higher-order polymorphism?)
code?

If there were a MonadFail class, you could explicitly codify that you
expect a monad to NOT crash your program in the case of a pattern
match.

For example:

someFunction :: (MonadState m, MonadFail m) = a - m a
someFunction arg = do
[x,y,z] - action arg
return z

Of course one of the laws for MonadFail would be that fail never
throws an exception. The compiler couldn't exactly enforce it, but
we're used to expecting sane instances that obey laws. I think IO
would be the exception (no pun intended) to this and be an instance of
MonadFail, but just throw an exception on fail. Since you can only
catch exceptions in the IO monad, this sounds reasonable to me.

--Jonathan

On Tue, Dec 21, 2010 at 2:49 AM, John Smith volderm...@hotmail.com wrote:
 Monads seem to use fail in one of three ways:

 -Regular monads leave it at the default definition of error
 -MonadPlus sometimes redefines it to mzero
 -IO redefines it to failIO

 Are there any other definitions of fail? If not, does the special case of IO
 really need a class-level definition, or could there be another way of
 dealing with failed pattern matches?


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


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


Re: [Haskell-cafe] Do we need Monad fail (or MonadFail)?

2010-12-21 Thread Jonathan Geddes
I'd be really interested in learning the rationale behind those changes. I'm
sure it wasn't done for capricious or arbitrary reasons, but I can't help
but see it as a step back.

--Jonathan Geddes (sent from android mobile)

On Dec 21, 2010 8:47 AM, Lauri Alanko l...@iki.fi wrote:

On Tue, Dec 21, 2010 at 08:31:08AM -0700, Jonathan Geddes wrote:
 I'd love for the compiler to give...
You will be interested to know that everything you ask for already was
in Haskell ages ago:

http://www.cs.auckland.ac.nz/references/haskell/haskell-report-1.4-html/exps.html#do-expressions

They decided to get rid of it in Haskell 98, for reasons that someone
else can probably explain.


Lauri


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


Re: [Haskell-cafe] Haskell, Step by Step, Tutorial, Developing a Whole Application

2010-12-18 Thread Jonathan Geddes
I agree with the feeling that Haskell tutorials feel like they are
bottom-up. But I think there's a reason for this: In my experience, at
least, Haskell applications are built bottom-up.

Functional programming languages strive for composability. In Haskell
you have very clean, clear ways of composing functions, Monads, and
even composing them with each other. In OOP languages, the glue that
you have for composing objects is more objects. This can be a much
less elegant way to build applications bottom-up, and so bottom up
applications feel sloppy and hacked together.

In an OOP app, you need to start with some kind of scaffolding, such
as mvc or the like, so that as you compose your objects, they start to
take the shape of a well-structured application. In functional
programming, that composability is much more flexible, so you don't
need to worry as much about coding yourself into a poorly structured
app. After all, mvc is all about separation of concerns which comes
naturally if you keep as much as possible outside of the IO monad.

When I'm coding in Haskell, I like to think in the paradigm of
creating a domain specific language. I'm not writing my program for
the first 90% of development, I'm actually working on the DSL that
will be used to create my app. Finally, i switch from functional
programming to imperative, procedural programming in the IO monad (or
some custom Monad) to write the actual code. The end result is a
flexible, maintainable program in very few lines of code and then some
very general, reusable library code supporting it.

I didn't address the actual question, instead I tried to speak to how
I got around the problem. Hope my $0.02 helps.

--Jonathan

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


Re: [Haskell-cafe] [Haskell] Functor = Applicative = Monad

2010-12-14 Thread Jonathan Geddes
Fail can't just be removed. That would just break too much code. For
example, I find myself writing code like the following:

[a,b,c] - Just someList

in place of

let [a,b,c] = someList

so that pattern match failure is lifted into the maybe monad (as
long as I'm already in the maybe monad).

I would like to see a MonadFail class, with one method 'fail', such
that it is a compile-time error to try 'failable' pattern matches in a
monad that is not an instance of MonadFail.

--Jonathan

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


[Haskell-cafe] $ do?

2010-12-14 Thread Jonathan Geddes
Quick question:

Why do I need the $ in the following bits of code?

 main = withSocketsDo $ do
--do something with sockets

 foo = fromMaybe 0 $ do
--do something in the maybe monad

I don't see (after admittedly only a minute or so thinking about it)
where any grammar ambiguities would be if 'do' had an implicit $ in
front of it:

 foo = fromMaybe 0 do
 --do something in maybe

Though now that I've written it down, that is hard for me to visually
parse at a glance. I'm still curious though.

--Jonathan

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


[Haskell-cafe] typeclass namespace rational?

2010-11-15 Thread Jonathan Geddes
cafe,

Data Constructors and Type Constructors don't share the same
namespace. You see code like the following all the time:

 data MyRecord = MyRecord {...}

This is possible because Data Constructors are used in different parts
of the code than Type Constructors so there's never any ambiguity.

Type Classes, on the other hand, share the same namespace as Type
Constructors. You can't define this:

class String s where
...

instance String String where
...
instance String ByteString where
   ...
instance String Text where
   ...

Not that I'm running out of valid haskell identifiers or anything :P,
I'm just wondering: what's the rationale behind keeping Type Classes
and Type Constructors in the same namespace? I can't think of any
ambiguity there would be if they each had their own namespace. And In
some cases it would be convenient to be able to define both a concrete
representation and an abstract one with the same name as in the String
class example above.

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


[Haskell-cafe] Re: typeclass namespace rational?

2010-11-15 Thread Jonathan Geddes
2 seconds after sending I realized the issue is in module exports:

Module String where (String(..))

is that exporting some concrete ADT with all of its constructors or an
abstract type class with all of its methods?

Its too bad that Classes and ADTs overlap in export syntax and as such
must share a namespace. I would much prefer

Module String where (class String(..), data String(..), someOtherFunction)

which I think is easier for the reader anyway.

--Jonathan

On Mon, Nov 15, 2010 at 8:31 PM, Jonathan Geddes
geddes.jonat...@gmail.com wrote:
 cafe,

 Data Constructors and Type Constructors don't share the same
 namespace. You see code like the following all the time:

 data MyRecord = MyRecord {...}

 This is possible because Data Constructors are used in different parts
 of the code than Type Constructors so there's never any ambiguity.

 Type Classes, on the other hand, share the same namespace as Type
 Constructors. You can't define this:

class String s where
    ...

instance String String where
    ...
instance String ByteString where
   ...
instance String Text where
   ...

 Not that I'm running out of valid haskell identifiers or anything :P,
 I'm just wondering: what's the rationale behind keeping Type Classes
 and Type Constructors in the same namespace? I can't think of any
 ambiguity there would be if they each had their own namespace. And In
 some cases it would be convenient to be able to define both a concrete
 representation and an abstract one with the same name as in the String
 class example above.

 --Jonathan

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


Re: Better Records was Re: [Haskell-cafe] Type Directed Name Resolution

2010-11-12 Thread Jonathan Geddes
 Records do leave quite a bit to be desired. But does anybody actually have a
 concrete alternative proposal yet?

A few months ago I proposed a couple of extensions [1] on -cafe.

The jist of it is in the following:

someUpdate :: MyRecord - MyRecord
someUpdate myRecord = myRecord
 { field1 = f $ field1 myRecord
 , field2 = g $ field2 myRecord
 , field3 = h $ filed3 myRecord
 }

becomes

someUpdate :: MyRecord - MyRecord
someUpdate = \{field1 = f, field2 = g, field3 = h}

The two syntax changes here are:
1. '=' remains as assignment in record updates, but = is added and
means 'field is transformed by', and
2. \{...} is a first-class lambda update. It's made possible by
the 1 since with 1 you no longer need to reference the entire record
anywhere in the update


 Consider what this would do for nested updates:

UpdateTripleInner :: (Inner-Inner) - MyTriplyNestedRecord - 
MyTriplyNestedRecord
UpdateTripleInner f = \{inner1 = \{inner2 = \{inner3 = f }}}

I cringe to imagine what the equivalent is in current Haskell syntax.
Anyone want to try it? Not me!

These extensions, admittedly, don't do anything for the namespacing
problem, which might be a bigger issue than awkward updates. I submit
that it's a different and somewhat unrelated issue, though I'd love to
see something that addresses both (all?) of the issues!

--Jonathan Geddes

[1] http://www.mail-archive.com/haskell-cafe@haskell.org/msg81509.html
On Fri, Nov 12, 2010 at 1:29 PM, Andrew Coppin
andrewcop...@btinternet.com wrote:
 On 11/11/2010 11:48 PM, John Lask wrote:

 again quoting

 http://research.microsoft.com/en-us/um/people/simonpj/Haskell/records.html

 Haskell lacks a serious record system. (The existing mechanism for named
 fields in data types was always seen as a stop-gap measure.)

 isn't it about time this changed?

 Records do leave quite a bit to be desired. But does anybody actually have a
 concrete alternative proposal yet?

 Personally I'm not really keen on TDNR; I'd prefer records that aren't so
 inconvenient. But I have no idea how to design that.

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

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


Re: [Haskell-cafe] Re: Haskell is a scripting language inspired by Python.

2010-11-04 Thread Jonathan Geddes
Regardless of which languages got which features for which other
languages, Haskell is surely NOT a scripting language inspired by
python...

Also, it was my understanding that Python got list comprehensions
straight from Haskell. Unless, of course, some of the pre-Haskells
also had this feature.

Haskell: [f x | x - xs, x = 15]
Python: [f(x) for x in xs if x = 15]

The Python version reads the way I would speak the Haskell one if I
were reading code aloud, though I might say such that rather than
for

--Jonathan Geddes

On Thu, Nov 4, 2010 at 6:05 AM, Stephen Tetley stephen.tet...@gmail.com wrote:
 On 4 November 2010 12:03, Stephen Tetley stephen.tet...@gmail.com wrote:
 Python is approximately as old as Python and most likely got
 indentation from ABC.

 Apologies that should read - as old as Haskell

 Obviously IDSWIM - (I _don't_ say what I mean).
 ___
 Haskell-Cafe mailing list
 Haskell-Cafe@haskell.org
 http://www.haskell.org/mailman/listinfo/haskell-cafe

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


[Haskell-cafe] Haskell is a scripting language inspired by Python.

2010-11-03 Thread Jonathan Geddes
This is off topic (almost regardless of the topic), but It gave me a
laugh. Hope you all enjoy it, too.

I was telling a friend about the power and elegance of Haskell. When I
mentioned that it has influenced many other programming languages,
including his favorite language (Python) he retorted by saying that I
was mistaken and it was, in fact, the other way around: Python
inspired Haskell. The following link was his source of information (or
FUD, as the case may be).

http://www.datarecoverylabs.com/ultimate-computer-language-guide.html

It's called The *Ultimate* Computer Language Guide, and it's on the
internets, so it must be correct, right?

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


Re: [Haskell-cafe] Re: Re: Lambda-case / lambda-if

2010-10-08 Thread Jonathan Geddes
I can honestly say that I haven't felt much pain from the status quo
regarding this. Most of the time my code is structured so that case
statements don't appear in do blocks. When they do, I don't see it as a big
issue. The special case for operator - is a bigger wart on haskell syntax
than this, imo.

I would vote in favor of keeping the language simple. I do like the idea of
generalizing lambda functions to include multiple cases, however.

On the other hand, I almost never use lambdas now since named functions
yield better self-documenting code.

--jonathan

On Oct 8, 2010 8:09 AM, Peter Wortmann sc...@leeds.ac.uk wrote:


On Fri, 2010-10-08 at 01:13 +0300, Lauri Alanko wrote:
 Your general rule doesn't subsume your ...
Yes, that's what I meant. Thanks for describing it properly.


On Fri, 2010-10-08 at 05:41 -0700, Nicolas Pouillard wrote:
 Imagine find this code:

 do s1
 ...
This is roughly what I meant with abused: Where C is very complex,
it might become non-obvious where exactly the monad actions are supposed
to happen. Hence such traps when refactoring.

Also of note: Just moving sub-expressions around isn't something that is
guaranteed to be save. Introducing new names and using them in s2
would be problematic, for example:

 do map (\x - (- putStrLn x)) [a, b]

Obviously can't be made to work. You might have to check for this - or
maybe even disallow the shorthand inside lamdbas and lets. Might be less
satisfying to have such special cases, but it is still a good bit more
general than what is available right now.

Greetings,
  Peter Wortmann



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


Re: [Haskell-cafe] Question on monad transformers stack

2010-09-28 Thread Jonathan Geddes
Arnaud,

You might also consider writing monad-agnostic code: code that doesn't
know which monad it is executing in.

For example:

class (Monad g) = MonadGit g where
   gitOp1 :: 
   gitOp2 :: 
   

instance MonadGit Git where
   gitOp1 = ...
   gitOp2 = ...
   ...

intance MonadGit DebugGit where
  gitOp1 = ...
  gitOp2 = ...

otherGitOp :: (MonadGit g) = a - b - g a
otherGitOp = gitOp1 . gitOp2 . otherF . etc

In other words, you create a typeclass that (at least) two different
monads will implement. One which runs the code normally, while the
other performs the debug actions that you described. Then your debug
flag becomes a choice of which monad to begin execution in. Note that
this can be a bit cumbersome (but I don't think impossible) if the
debug flag has to be changed at runtime.

Hope this helps,

--Jonathan


On Tue, Sep 28, 2010 at 12:56 AM, Arnaud Bailly arnaud.oq...@gmail.com wrote:
 Hello Cafe,

 I have the following type which represents some action using Git

 newtype (Monad m) = Git m a = Git { runGit :: ErrorT String (StateT 
 Environment m) a }
              deriving (Monad, MonadState Environment, MonadError String)

 and the following typeclass whose purpose is to abstract away the
 details of executing commands in the OS, with an obvious IO instance,
 and to ease testing of commands effects:

 -- | A monad for simple execution of a process within the
 class (MonadError e m) = MonadExec e m  where
   debug :: String - m ()
   exec  :: String - [String] - m String
   -- ^Do not really execute commande but output the command string and 
 arguments passed
   exec' :: String - [String] - m String
   exec' proc args = return $ program proc args

 The type environment is :

 data Environment = Env { debugMode     :: Bool,
                          baseDirectory :: FilePath,
                          maven         :: FilePath,
                          git           :: FilePath,
                          p4            :: FilePath,
                          javaHome      :: FilePath}
                  deriving (Eq, Show, Read)

 This follows the monad stack pattern presented in RWH and in Don
 Stewart's presentation on scripting with haskell. Actually, what I am
 trying to achieve is to be able to write my own scripts in Haskell.

 What I would like to do is to be able to wrap each Git action occuring
 in a MonadExec instance into a call to debug according to the status
 of the debugMode flag in environment, in order to prevent the need of
 explicit calls to debug. Something like the -v flag in bash...

 I can imagine being able to do this using 2 different ways:
  - add a constraint on Git monad and write explicitly return and =
   to use debug
  - push the environment or part of it inside the MonadExec, for
   example as a Reader.

 What is the best (i.e. most economical) way of doing this?

 Thanks for your advices.

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

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


[Haskell-cafe] Inverse of HaskellDB

2010-09-25 Thread Jonathan Geddes
Cafe,

HaskellDB takes a database schema and produces Haskell data structures
(plus some other query-related stuff for its EDSL query language).

What I'm looking for is the inverse of this functionality. I want to
create tables based on a Haskell data structure with a few simple
rules. These rules include: if a field is not of the form `Maybe a'
then it can't be nullable in the database. If a field is not a
primitive (in the database) then it is actually stored in another
table and a reference id is stored in the table. Tables are produced
recursively, unless they already exist, etc.

The HaskellDB approach is great for interfacing with existing tables,
but in my case I already have data structures and now I would like a
quick way to create tables to persist them.

Does such a thing exist? If not, would you find it useful? I may take
this up as a side project if it does not already exist and others
would find it useful.

Thanks,

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


Re: [Haskell-cafe] Inverse of HaskellDB

2010-09-25 Thread Jonathan Geddes
Versioning is a tricky problem regardless of how you are creating
tables. And that isn't the problem I was aiming to tackle; the problem
I was aiming to tackle is a bit more narrow than that: I have a record
and now I need a table to stick it in.

By the way, how does HaskellDB handle versioning?

--Jonathan

On Sat, Sep 25, 2010 at 1:57 PM, Antoine Latter aslat...@gmail.com wrote:
 That sounds pretty awesome to me.

 Have you given any thought as to how you want to approach versioning?

 Maybe I'm asking a silly question - I have very little real world experience
 with relation databases and how to version schemas.

 Antoine

 On Sep 25, 2010 2:31 PM, Jonathan Geddes geddes.jonat...@gmail.com
 wrote:
 Cafe,

 HaskellDB takes a database schema and produces Haskell data structures
 (plus some other query-related stuff for its EDSL query language).

 What I'm looking for is the inverse of this functionality. I want to
 create tables based on a Haskell data structure with a few simple
 rules. These rules include: if a field is not of the form `Maybe a'
 then it can't be nullable in the database. If a field is not a
 primitive (in the database) then it is actually stored in another
 table and a reference id is stored in the table. Tables are produced
 recursively, unless they already exist, etc.

 The HaskellDB approach is great for interfacing with existing tables,
 but in my case I already have data structures and now I would like a
 quick way to create tables to persist them.

 Does such a thing exist? If not, would you find it useful? I may take
 this up as a side project if it does not already exist and others
 would find it useful.

 Thanks,

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

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


Re: [Haskell-cafe] Inverse of HaskellDB

2010-09-25 Thread Jonathan Geddes
Have you given any thought as to how you want to approach versioning?

After giving this some more thought, I realized:
1) One of the best practices (even though I despise the term) of
versioning schema is to include a script with the code which checks
for each change to the tables, and makes the change if it is needed
[1]. Each time you check out new code, you run the script to ensure
that the code you are working with matches the tables you are working
with.
2) A system that generates tables from Haskell types could also be
made to check if a given table faithfully represents a given Haskell
record type. It could then make any changes to the table so that it
_does_ faithfully represent the record type.
3) In this way, your Haskell records ARE your table update script,
just (like most Haskell code) incredibly terse. Your usual code
repository will track when and by whom changes are made to the record.

Of course, there are some issues with this, but I think it could be
made to work well.

Hibernate does this, more or less, for Java classes.  That might be a
good place to look for ideas.

Good point. I'll start there.

[1] http://www.codeproject.com/KB/database/DatabaseSchemaVersioning.aspx

--Jonathan

On Sat, Sep 25, 2010 at 3:45 PM, Rogan Creswick cresw...@gmail.com wrote:
 On Sat, Sep 25, 2010 at 12:31 PM, Jonathan Geddes
 geddes.jonat...@gmail.com wrote:

 Does such a thing exist? If not, would you find it useful? I may take
 this up as a side project if it does not already exist and others
 would find it useful.


 I've been looking for something along these lines too.

 Hibernate does this, more or less, for Java classes.  That might be a
 good place to look for ideas.

 --Rogan

 Thanks,

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


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


Re: [Haskell-cafe] record update

2010-09-14 Thread Jonathan Geddes
Wow, I had no idea there were so many record packages! This indicates a
couple things to me: a) Haskell is very flexible. b) I'm not the only one
who things the built-in record system isn't perfect.

Digging a bit deeper, it looks like some of the record-related ghc
extensions might also be useful, such as record punning and field
disambiguation.
Since these are already extensions, they're more likely to make it into
Haskell 20XX. Are these considered to be the solution to current record
syntax problems?

With these extensions, couldn't I write the following?

someUpdate :: MyRecord - MyRecord
someUpdate myRecord@(MyRecord{..}) = let
 { field1 = f field1
 , field2 = g field2
 , field3 = h filed3
 } in myRecord{..}
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


[Haskell-cafe] record update

2010-09-11 Thread Jonathan Geddes
I know that record updates is a topic that has become a bit of a dead
horse, but here I go anyway:

I find that most of the record updates I read and write take the form

someUpdate :: MyRecord - MyRecord
someUpdate myRecord = myRecord
 { field1 = f $ field1 myRecord
 , field2 = g $ field2 myRecord
 , field3 = h $ filed3 myRecord
 }

I find myself wishing I could write something more like

someUpdate :: MyRecord - MyRecord
someUpdate myRecord = myRecord
 { field1 = f
 , field2 = g
 , field3 = h
 }

with equivalent semantics. Here = reads is transformed by. Operator
= could still be used for assignment as in current record updates.

The best part about such an extension, in my opinion, is that it would
open the door for anonymous lambda record updates. Something like:

someUpdate :: MyRecord - MyRecord
someUpdate = \{field1 = f, field2 = g, field3 = h}

again, with the same semantics. This becomes possible because you no
longer need to refer to the record within the {} part of the update.

This would be useful, for example, in the State monad. We could write:

someStateTransform :: State MyRecord ()
someStateTransform = do
 modify $ \{field1 = (++!)}
 ...

where currently we see code like

someStateTransform :: State MyRecord ()
someStateTransform = do
 modify $ \record-record{field1 = (++!) $ field1 record}
 ...

which repeats the record name 3 times and the field name twice. The
repetition just feels out of place next to all the other terse,
readable Haskell code in the program.

So what do my fellow haskellers think? Is this idea worth writing up a
proposal for?

Alternatively, can you offer me some advice on writing code in Haskell
2010 that avoids the ugly, repetitive style of record update?

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


Re: [Haskell-cafe] record update

2010-09-11 Thread Jonathan Geddes
On Sat, Sep 11, 2010 at 11:53 AM, Henning Thielemann
schlepp...@henning-thielemann.de wrote:
 Jonathan Geddes schrieb:
 I know that record updates is a topic that has become a bit of a dead
 horse, but here I go anyway:

 I find that most of the record updates I read and write take the form

 someUpdate :: MyRecord - MyRecord
 someUpdate myRecord = myRecord
     { field1 = f $ field1 myRecord
     , field2 = g $ field2 myRecord
     , field3 = h $ filed3 myRecord
     }

 I find myself wishing I could write something more like

 someUpdate :: MyRecord - MyRecord
 someUpdate myRecord = myRecord
     { field1 = f
     , field2 = g
     , field3 = h
     }

 data-accessor and similar packages may become your friends.

 data-accessor allows you to write:

 someUpdate =
   (field1 ^: f) .
   (field2 ^: g) .
   (field3 ^: h)


data-accessor is a pretty cool package, but if I understand correctly,
your fields are not the same as the straight functions you get from
defining a record, and cant' be used as regular functions. So you have
to create these Data.Accessor.Accessors.

Is defining accessors really any better than just writing update
functions like the following?

 updateField1 :: (Field1Type - Field1Type) - MyRecord - MyRecord
 updateField1 f x = x{field1 = f $ field1 x}
 someUpdate = (updateField1 f) . j(updateField2 g) . (updateField3 h)

I understand that there is a package data-accessor-template for
generating accessors, but couldn't you use TH for generating updater
functions as well?

It seems like something as fundamental as record update should have a
clean, build-in syntax. Or am I thinking too imperatively?

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


Re: [Haskell-cafe] Socket not released

2010-08-09 Thread Jonathan Geddes
 You need to close the parent's socket in the child fork, as well as
 the parent - if it's inherited by the child, it's held open there,
 even if the parent closes it.

Thanks! That did the trick.

I did so by adding

close_fds = True

to the CreateProcess record. However the documentation of
System.Process says that this only works on Windows if std_in,
std_out, and std_err are all set to Inherit. This is not the case in
my program so it will not work on any nodes that run on Windows. What
is the workaround for doing this kind of thing in Windows? Also since
the file descriptor of the socket appears to be inherited by the child
process, can I just start using it rather than closing it in both the
parent and child and then creating a new one?
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe


Re: [Haskell-cafe] Socket not released

2010-08-09 Thread Jonathan Geddes
 Only a guess, but I predict that it will work for your purposes,
 since you're not concerned about what happens to std_in et al.

I actually am concerned about what happens to std_in. The parent
process serializes a bit of state and passes it to the child via the
child's std_in. There's probably a better way to do such a thing, but
it works for now.

That statement in the documentation is ambiguous, so if it isn't
convenient to just test for this, you need someone to clarify
what doesn't work means.

 I will wait to test this when (and if) I have to put a node on a Windows box.

 Sure!  At least from a POSIX perspective, and it would be surprising
 if a Haskell implementation failed to preserve that.

If only I knew for sure that all nodes would remain in the POSIX world.

I appreciate the help.

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


Re: [Haskell-cafe] Re: Haskell in Industry

2010-08-09 Thread Jonathan Geddes
 Yes.  I find that out of 10 people I train, only about 2 pick it up
 and run with it.  I'm starting to believe you are either wired for
 functional programming, or you're not.

Couldn't agree more. This is the usual conclusion I arrive at when I
find myself wondering why so many very intelligent people reject FP
when it's obviously (to my and my FP-wired brain) superior.

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


[Haskell-cafe] Socket not released

2010-08-07 Thread Jonathan Geddes
Cafe,

I'm writing a network application that uses static configuration a la xmonad
and yi. When the app receives a certain command it  recompiles its source,
closes the socket it is using and runs its newly compiled predecessor as a
new process.

The problem I'm having is that the port that the parent process was using is
not available to the child process. Even though the parent process has
terminated, the port is unusable until the child process also terminates.
Can anyone give me a clue about what's going on here?

I'm using Network and System.Process modules and ruining on Ubuntu linux.
I'm using the sClose function to close the socket.

Thanks for any tips.

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


Re: [Haskell-cafe] Socket not released

2010-08-07 Thread Jonathan Geddes
Thank you for your response

 Are you certain of this part?  The usual problem with this kind of program
 is that the system holds the socket open for a minute or so in case there
 are any packets in flight for the connection (the lower level network
 protocols not being 100% reliable).

I'm not certain, but here's what I'm seeing. The process tries n times
to acquire the socket, pausing for a second or so between attempts.
While running a child process I will run a fresh process so that the
two processes are competing for the socket, but neither of them are
getting it. In half a dozen such test cases the fresh process grabs
the socket on the very next attempt after the child process is
interrupted. But if I interrupt the fresh process, the child process
continues to fail to acquire the socket.

And the workaround is to set
 SO_REUSEADDR before binding the port; in Haskell,
 setSocketOption socket ReuseAddr 1

I'm using the Network Module which sets ReuseAddr, according to its
documentation.

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


Re: [Haskell-cafe] Suggestions For An Intro To Monads Talk.

2010-08-06 Thread Jonathan Geddes
On Fri, Aug 6, 2010 at 9:17 AM, aditya siram aditya.si...@gmail.com wrote:

 Upon further reflection I realized that my audience is more pragmatic than 
 theoretical. Instead of emphasizing how monads are constructed and the monad 
 laws I think I want to dive right into the most common and useful monads. 
 From my vantage point they are (in no particular order) : Reader, Writer, 
 State, IO, ST, STM, Parsec (have I missed any?) and of course the transformer 
 versions. I am debating whether or not to add [] to the bunch.

If your audience is indeed a pragmatic lot then they will not be
interested in the same things as a more theoretical crowd (obviously).
So they might not be interested in Monads at all. You've got your work
cut out for you!
With that said, I would suggest starting with the advantages of
purity. I would guess that 95% of bugs in imperative code are related
to some erroneous state. Pure code, on the other hand is immune to
this huge class of bugs. Sometimes state is useful or even necessary
(stateful computations, IO, in-place algorithms, etc), so you really
can't forgo state entirely. The cool thing about Monads is they allow
us to have our cake and eat it too! We can model stateful computations
in pure code. You might also mention the separation of pure and impure
code and how this helps us to reason about a program.

 I'm still a little iffy on why the monad concept isn't used in other 
 languages. From where I sit it seems as though monads really let you play 
 with the order of evaluation - just because one statement is executed after 
 another doesn't mean they are executed in that order. I think other languages 
 don't make this easy.


My guess would be that other languages have much less commitment to
purity. You don't need Monads in other languages because state is
implicit, everything is in the IO monad, in a sense. While Monads are
still an excellent abstraction in other languages they're often more
awkward than just using implicit state/IO/whatever operations. Haskell
has some sweet built-in syntax for monads.
Also related to advantages of purity:
http://www.haskell.org/haskellwiki/Why_Haskell_just_works
I think this approach (stating benefits of purity and maybe laziness)
would be more interesting to a pragmatic crowd. Just a guess though.
Good luck with your presentation!
--Jonathan
___
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe