From westondan at imageworks.com Fri Jul 6 15:08:01 2007 From: westondan at imageworks.com (Dan Weston) Date: Fri Jul 6 15:01:48 2007 Subject: Nested pattern binding translates to outermost binding? In-Reply-To: <20070706092150.GE12066@cse.unsw.EDU.AU> References: <468C0617.8000703@btinternet.com> <200707041553.25910.jcast@ou.edu> <468D2E38.6010204@btinternet.com> <200707051422.42731.jcast@ou.edu> <468D4A4A.10509@btinternet.com> <1265460943.20070706123310@gmail.com> <003c01c7bfad$f27cefb0$d776cf10$@be> <20070706091835.GD12066@cse.unsw.EDU.AU> <20070706092150.GE12066@cse.unsw.EDU.AU> Message-ID: <468E9311.7010308@imageworks.com> From Haskell' ticket #76: http://hackage.haskell.org/trac/haskell-prime/wiki/BangPatterns > The main idea is to add a single new production to the syntax > of patterns > pat ::= !pat Experiments (ghci -fbang-patterns -O2 -S, rename identifiers, then diff) shows that nested pattern bindings are equivalent to the outermost binding: !(!pat) ==> !pat !(~pat) ==> !pat ~(~pat) ==> ~pat ~(!pat) ==> ~pat but I do not see any wording to that effect either in the Haskell 98 report, the GHC documentation, or the Haskell' wiki. Have I overlooked it, or does it follow from the existing language definition? Dan From stefanor at cox.net Fri Jul 6 16:46:47 2007 From: stefanor at cox.net (Stefan O'Rear) Date: Fri Jul 6 16:40:32 2007 Subject: Nested pattern binding translates to outermost binding? In-Reply-To: <468E9311.7010308@imageworks.com> References: <468C0617.8000703@btinternet.com> <200707041553.25910.jcast@ou.edu> <468D2E38.6010204@btinternet.com> <200707051422.42731.jcast@ou.edu> <468D4A4A.10509@btinternet.com> <1265460943.20070706123310@gmail.com> <003c01c7bfad$f27cefb0$d776cf10$@be> <20070706091835.GD12066@cse.unsw.EDU.AU> <20070706092150.GE12066@cse.unsw.EDU.AU> <468E9311.7010308@imageworks.com> Message-ID: <20070706204647.GA4118@localhost.localdomain> On Fri, Jul 06, 2007 at 12:08:01PM -0700, Dan Weston wrote: > From Haskell' ticket #76: > http://hackage.haskell.org/trac/haskell-prime/wiki/BangPatterns > > > The main idea is to add a single new production to the syntax > > of patterns > > pat ::= !pat > > Experiments (ghci -fbang-patterns -O2 -S, rename identifiers, then diff) You could have just used -ddump-ds... Core is way more readable than GHC assembly. > shows that nested pattern bindings are equivalent to the outermost binding: > > !(!pat) ==> !pat > !(~pat) ==> !pat > > ~(~pat) ==> ~pat > ~(!pat) ==> ~pat > > but I do not see any wording to that effect either in the Haskell 98 > report, the GHC documentation, or the Haskell' wiki. Have I overlooked it, > or does it follow from the existing language definition? Pattern matching is completely specified, and from the rules I can derive a counter-example to your assertion. stefan@stefans:~$ ghci -fbang-patterns -v0 Prelude> case 3 of !(!2) -> 'a' *** Exception: :1:0-21: Non-exhaustive patterns in case Prelude> case 3 of !(~2) -> 'a' 'a' Prelude> stefan@stefans:~$ Stefan From bayer at cpw.math.columbia.edu Fri Jul 6 21:20:45 2007 From: bayer at cpw.math.columbia.edu (Dave Bayer) Date: Fri Jul 6 21:14:37 2007 Subject: Nested pattern binding translates to outermost binding? In-Reply-To: <20070706204647.GA4118@localhost.localdomain> References: <468C0617.8000703@btinternet.com> <200707041553.25910.jcast@ou.edu> <468D2E38.6010204@btinternet.com> <200707051422.42731.jcast@ou.edu> <468D4A4A.10509@btinternet.com> <1265460943.20070706123310@gmail.com> <003c01c7bfad$f27cefb0$d776cf10$@be> <20070706091835.GD12066@cse.unsw.EDU.AU> <20070706092150.GE12066@cse.unsw.EDU.AU> <468E9311.7010308@imageworks.com> <20070706204647.GA4118@localhost.localdomain> Message-ID: <3C2DD6C5-35AE-4B3E-AE35-0AE94A1F5FD0@math.columbia.edu> On Jul 6, 2007, at 1:46 PM, Stefan O'Rear wrote: > You could have just used -ddump-ds... Core is way more readable than > GHC assembly. Great suggestion! Core looks familiar from playing with template Haskell, is it identical? Can one / does anyone use Core as a target for experimental toy languages? Aside from the "moving target" caveats... From stefanor at cox.net Fri Jul 6 21:35:15 2007 From: stefanor at cox.net (Stefan O'Rear) Date: Fri Jul 6 21:29:01 2007 Subject: Nested pattern binding translates to outermost binding? In-Reply-To: <3C2DD6C5-35AE-4B3E-AE35-0AE94A1F5FD0@math.columbia.edu> References: <468D2E38.6010204@btinternet.com> <200707051422.42731.jcast@ou.edu> <468D4A4A.10509@btinternet.com> <1265460943.20070706123310@gmail.com> <003c01c7bfad$f27cefb0$d776cf10$@be> <20070706091835.GD12066@cse.unsw.EDU.AU> <20070706092150.GE12066@cse.unsw.EDU.AU> <468E9311.7010308@imageworks.com> <20070706204647.GA4118@localhost.localdomain> <3C2DD6C5-35AE-4B3E-AE35-0AE94A1F5FD0@math.columbia.edu> Message-ID: <20070707013515.GB7964@localhost.localdomain> On Fri, Jul 06, 2007 at 06:20:45PM -0700, Dave Bayer wrote: > On Jul 6, 2007, at 1:46 PM, Stefan O'Rear wrote: > >> You could have just used -ddump-ds... Core is way more readable than >> GHC assembly. > > Great suggestion! > > Core looks familiar from playing with template Haskell, is it identical? No, Core is much lower level. It does not have guards, where-blocks, list comprehensions, type classes, etc; everything is reduced to simple pattern bindings, lambdas, lets, applications, and unboxed literals. > Can one / does anyone use Core as a target for experimental toy languages? > Aside from the "moving target" caveats... Apparently not, since GHC's support for *reading* core has been broken since the 6.0 days with nary a complaint. (Aaron Tomb and Tim Chevalier are currently working on fixing it). Stefan From simonpj at microsoft.com Mon Jul 9 04:38:39 2007 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Mon Jul 9 04:32:17 2007 Subject: Nested pattern binding translates to outermost binding? In-Reply-To: <468E9311.7010308@imageworks.com> References: <468C0617.8000703@btinternet.com> <200707041553.25910.jcast@ou.edu> <468D2E38.6010204@btinternet.com> <200707051422.42731.jcast@ou.edu> <468D4A4A.10509@btinternet.com> <1265460943.20070706123310@gmail.com> <003c01c7bfad$f27cefb0$d776cf10$@be> <20070706091835.GD12066@cse.unsw.EDU.AU> <20070706092150.GE12066@cse.unsw.EDU.AU> <468E9311.7010308@imageworks.com> Message-ID: In the section "Changes to the Report" of the Wiki page you refer to http://hackage.haskell.org/trac/haskell-prime/wiki/BangPatterns I attempted to give the semantics of bang-patterns by saying what changes would be needed in the Haskell Report. If you think it's incomplete or ambiguous, then do yell. (The wiki says that the changes are "incomplete" but I can't now think why!) Simon | -----Original Message----- | From: haskell-prime-bounces@haskell.org [mailto:haskell-prime-bounces@haskell.org] On Behalf Of Dan | Weston | Sent: 06 July 2007 20:08 | To: Haskell Prime | Subject: Nested pattern binding translates to outermost binding? | | From Haskell' ticket #76: | http://hackage.haskell.org/trac/haskell-prime/wiki/BangPatterns | | > The main idea is to add a single new production to the syntax | > of patterns | > pat ::= !pat | | Experiments (ghci -fbang-patterns -O2 -S, rename identifiers, then diff) | shows that nested pattern bindings are equivalent to the outermost binding: | | !(!pat) ==> !pat | !(~pat) ==> !pat | | ~(~pat) ==> ~pat | ~(!pat) ==> ~pat | | but I do not see any wording to that effect either in the Haskell 98 | report, the GHC documentation, or the Haskell' wiki. Have I overlooked | it, or does it follow from the existing language definition? | | Dan | | _______________________________________________ | Haskell-prime mailing list | Haskell-prime@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-prime From stefanor at cox.net Mon Jul 9 12:23:03 2007 From: stefanor at cox.net (Stefan O'Rear) Date: Mon Jul 9 12:16:43 2007 Subject: [Haskell-cafe] Haskell's prefix exprs In-Reply-To: <46923E68.6030005@dfki.de> References: <46923E68.6030005@dfki.de> Message-ID: <20070709162303.GA4883@localhost.localdomain> On Mon, Jul 09, 2007 at 03:55:52PM +0200, 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). > > In this case the above right hand sides (rhs) are unique juxtapositions > of two expressions. (This extension should of course apply to more than > two expressions, i. e. "f a do []") > > Furthermore the above rhs are all valid if written as infix expressions: > > f = id $ \ _ -> [] > g = id $ let x = [] in x > h = id $ case [] of [] -> [] > i = id $ do [] > j = id $ if True then [] else [] False. f = runST $ do return () is a type error. f = runST (do return ()) is legal. So your proposal isn't as pointless as you think :) > (In fact, maybe for haskell-prime "$" could be changed to a keyword.) > > Does this pose any problems that I haven't considered? Not that I know of. Indeed, the status quo is a (minor) pain to parse, and in my Haskell compiler project I *wanted* to implement your proposal. > I think only more (and shorter) illegal haskell programs will become legal. > > Cheers Christian > > Maybe someone else can work out the details for Haskell's grammar Not hard at all. In http://haskell.org/onlinereport/syntax-iso.html, change: exp^10 -> \ apat[1] ... apat[n] -> exp (lambda abstraction, n>=1) | let decls in exp (let expression) | if exp then exp else exp (conditional) | case exp of { alts } (case expression) | do { stmts } (do expression) | fexp fexp -> [fexp] aexp (function application) aexp -> qvar (variable) | gcon (general constructor) | literal | ( exp ) (parenthesized expression) | ( exp[1] , ... , exp[k] ) (tuple, k>=2) | [ exp[1] , ... , exp[k] ] (list, k>=1) | [ exp[1] [, exp[2]] .. [exp[3]] ] (arithmetic sequence) | [ exp | qual[1] , ... , qual[n] ] (list comprehension, n>=1) | ( exp^i+1 qop^(a,i) ) (left section) | ( lexp^i qop^(l,i) ) (left section) | ( qop^(a,i)[<->] exp^i+1 ) (right section) | ( qop^(r,i)[<->] rexp^i ) (right section) | qcon { fbind[1] , ... , fbind[n] } (labeled construction, n>=0) | aexp[] { fbind[1] , ... , fbind[n] } (labeled update, n >= 1) to: exp^10 -> [exp^10] aexp (function application) aexp -> \ apat[1] ... apat[n] -> exp (lambda abstraction, n>=1) | let decls in exp (let expression) | if exp then exp else exp (conditional) | case exp of { alts } (case expression) | do { stmts } (do expression) | qvar (variable) | gcon (general constructor) | literal | ( exp ) (parenthesized expression) | ( exp[1] , ... , exp[k] ) (tuple, k>=2) | [ exp[1] , ... , exp[k] ] (list, k>=1) | [ exp[1] [, exp[2]] .. [exp[3]] ] (arithmetic sequence) | [ exp | qual[1] , ... , qual[n] ] (list comprehension, n>=1) | ( exp^i+1 qop^(a,i) ) (left section) | ( lexp^i qop^(l,i) ) (left section) | ( qop^(a,i)[<->] exp^i+1 ) (right section) | ( qop^(r,i)[<->] rexp^i ) (right section) | qcon { fbind[1] , ... , fbind[n] } (labeled construction, n>=0) | aexp[] { fbind[1] , ... , fbind[n] } (labeled update, n >= 1) All new ambiguities are resolved adequately by the let/lambda meta rule. > (I've posted this message to glasgow-haskell-users before, but it > applies to every Haskell implementation and should be discussed here.) haskell-prime@haskell.org would be even better. Stefan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/haskell-prime/attachments/20070709/ba30c1b0/attachment.bin From isaacdupree at charter.net Mon Jul 9 16:08:03 2007 From: isaacdupree at charter.net (Isaac Dupree) Date: Mon Jul 9 16:02:18 2007 Subject: [Haskell-cafe] Haskell's prefix exprs In-Reply-To: <20070709162303.GA4883@localhost.localdomain> References: <46923E68.6030005@dfki.de> <20070709162303.GA4883@localhost.localdomain> Message-ID: <469295A3.9040107@charter.net> Stefan O'Rear wrote: > On Mon, Jul 09, 2007 at 03:55:52PM +0200, 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 [] I agree. The only (minor) concern I have is: that syntax is hard to read (by humans) without syntax-hilighting of keywords. Isaac From isaacdupree at charter.net Mon Jul 9 16:28:05 2007 From: isaacdupree at charter.net (Isaac Dupree) Date: Mon Jul 9 16:22:16 2007 Subject: monomorphism restriction confusions Message-ID: <46929A55.3020504@charter.net> Haskell98's monomorphism restriction is too confusing! See my mistaken GHC bug report . Whether a binding is monomorphic depends not just on syntax, but on the amount of type constraints on the right-hand side of a binding - and I didn't realize, because this issue usually doesn't come up (usually types are already monomorphic or are at least typeclass qualified, or at least don't have to be monomorphic to prevent a type error). Although this finally convinces me that we should dump H98 m-r in favor of the very straightforward "monomorphic pattern bindings", if we don't, at least I believe that Report Section 4.5.5, Rule 1 needs a reword. It uses "(un) restricted" to mean "restricted (to be monomorphic) IN SOME CASES". Maybe a word like "suspicious" would be less misleading than "restricted" there? Isaac From adde at trialcode.com Tue Jul 10 10:38:22 2007 From: adde at trialcode.com (Adde) Date: Tue Jul 10 10:35:15 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields Message-ID: <1184078302.20597.39.camel@freestyler> Hi, I'm forwarding this feature request as is on the advice of Neil Mitchel for discussion / possible inclusion in future versions of Haskell. #1518: Make it possible to evaluate monadic actions when assigning record fields (<-) ---------------------------------+------------------------------------------ Reporter: adde@trialcode.com | Owner: Type: feature request | Status: new Priority: normal | Milestone: Component: Compiler | Version: 6.6.1 Severity: normal | Keywords: Difficulty: Unknown | Os: Unknown Testcase: | Architecture: Unknown ---------------------------------+------------------------------------------ It is currently not possible to build records from values resulting from monadic actions while still using the field-specifiers. foo :: IO Int ... data Bar = Bar { barFoo :: Int } buildBar :: IO () buildBar = do return Bar { barFoo <- foo --Evaluate foo to get the Int-value } I've found two possible ways of doing this: 1) Using temporaries to evaluate the actions before assigning which doubles the number of lines: tmp <- foo return Bar { barFoo = tmp } 2) Lifting the record constructor which prevents you from using field specifiers (and you really need field specifiers when dealing with larger records): liftM Bar foo Thanks, Adde From isaacdupree at charter.net Tue Jul 10 12:12:03 2007 From: isaacdupree at charter.net (Isaac Dupree) Date: Tue Jul 10 12:06:11 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: <1184078302.20597.39.camel@freestyler> References: <1184078302.20597.39.camel@freestyler> Message-ID: <4693AFD3.9020201@charter.net> Adde wrote: > tmp <- foo > return Bar { > barFoo = tmp > } There is a feature being worked on in GHC HEAD that would let you do do tmp <- foo return Bar{..} which captures fields from everything of the same name that's in scope. I think this would also satisfy your desire. (also, the liftM approach doesn't let you choose the order of the monadic actions.) Isaac From kahl at cas.mcmaster.ca Tue Jul 10 13:04:47 2007 From: kahl at cas.mcmaster.ca (kahl@cas.mcmaster.ca) Date: Tue Jul 10 12:59:38 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: <4693AFD3.9020201@charter.net> (message from Isaac Dupree on Tue, 10 Jul 2007 13:12:03 -0300) References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> Message-ID: <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> Isaac Dupree wrote: > > Adde wrote: > > tmp <- foo > > return Bar { > > barFoo = tmp > > } > > There is a feature being worked on in GHC HEAD that would let you do > > do > tmp <- foo > return Bar{..} > > which captures fields from everything of the same name that's in scope. > I think this would also satisfy your desire. > I guess this means I could write: data D = C {field1 :: Bool, field2 :: Char} f x = do field1 <- foo1 field2 <- foo2 field3 <- foo3 other stuff return C{..} instead of f x = do tmp1 <- foo1 tmp2 <- foo2 field3 <- foo3 other stuff return $ C { field1 = tmp1, field2 = tmp2 } This has a dangerous feel to it --- extending the definition of D to include a field field3 may have quite unintended consequences. What I am missing most in the record arena is a functional notation for record update, for example: {^ field1 } = \ f r -> r {field1 = f (field1 r)} From adde at trialcode.com Tue Jul 10 16:40:12 2007 From: adde at trialcode.com (Adde) Date: Tue Jul 10 16:44:01 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> Message-ID: <1184100012.20597.46.camel@freestyler> On Tue, 2007-07-10 at 17:04 +0000, kahl@cas.mcmaster.ca wrote: > Isaac Dupree wrote: > > > > Adde wrote: > > > tmp <- foo > > > return Bar { > > > barFoo = tmp > > > } > > > > There is a feature being worked on in GHC HEAD that would let you do > > > > do > > tmp <- foo > > return Bar{..} > > > > which captures fields from everything of the same name that's in scope. > > I think this would also satisfy your desire. > > > > I guess this means I could write: > > > data D = C {field1 :: Bool, field2 :: Char} > > f x = do > field1 <- foo1 > field2 <- foo2 > field3 <- foo3 > other stuff > return C{..} > > > instead of > > > f x = do > tmp1 <- foo1 > tmp2 <- foo2 > field3 <- foo3 > other stuff > return $ C { field1 = tmp1, field2 = tmp2 } > > > This has a dangerous feel to it --- > extending the definition of D to include a field field3 > may have quite unintended consequences. > > > What I am missing most in the record arena > is a functional notation for record update, for example: > > {^ field1 } = \ f r -> r {field1 = f (field1 r)} I agree, capturing variables without asking is just scary. While I'm pretty biased I still think my suggestion solves the problem in a cleaner, more consistent way. /Adde From simonpj at microsoft.com Wed Jul 11 03:38:31 2007 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Wed Jul 11 03:32:03 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: <1184100012.20597.46.camel@freestyler> References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> <1184100012.20597.46.camel@freestyler> Message-ID: Another alternative (which I got from Greg Morrisett) that I'm toying with is this. It's tiresome to write do { x <- ; y <- ; f x y } In ML I'd write simply f So Greg's idea (or at least my understanding thereof) is to write it like this: do { f $(stuff1) $(stuff2) } The idea is that a "splice" $e must be lexically enclosed by a 'do', with no intervening lambda. It's desugared to the code above; that is, each splice it pulled out, in lexically left-right order, and given a name, which replaces the splice. Of course it doesn't have to look like the above; the rule applies to any do: do { v <- this; foo $(h v); y <- f $(t v v); ...etc } The "linearise the splices" rule is quite general. Don't burn any cycles on concrete syntax; I know the $ notation is used for Template Haskell; one would need to think of a good syntax. But the idea is to make it more convenient to write programs that make effectful calls, and then use the result exactly once. Anyway, this'd do what the original proposer wanted, but in a much more general way. Just a thought -- I have not implemented this. Simon | -----Original Message----- | From: haskell-prime-bounces@haskell.org [mailto:haskell-prime-bounces@haskell.org] On Behalf Of Adde | Sent: 10 July 2007 21:40 | To: kahl@cas.mcmaster.ca | Cc: haskell-prime@haskell.org | Subject: Re: Make it possible to evaluate monadic actions when assigning record fields | | On Tue, 2007-07-10 at 17:04 +0000, kahl@cas.mcmaster.ca wrote: | > Isaac Dupree wrote: | > > | > > Adde wrote: | > > > tmp <- foo | > > > return Bar { | > > > barFoo = tmp | > > > } | > > | > > There is a feature being worked on in GHC HEAD that would let you do | > > | > > do | > > tmp <- foo | > > return Bar{..} | > > | > > which captures fields from everything of the same name that's in scope. | > > I think this would also satisfy your desire. | > > | > | > I guess this means I could write: | > | > | > data D = C {field1 :: Bool, field2 :: Char} | > | > f x = do | > field1 <- foo1 | > field2 <- foo2 | > field3 <- foo3 | > other stuff | > return C{..} | > | > | > instead of | > | > | > f x = do | > tmp1 <- foo1 | > tmp2 <- foo2 | > field3 <- foo3 | > other stuff | > return $ C { field1 = tmp1, field2 = tmp2 } | > | > | > This has a dangerous feel to it --- | > extending the definition of D to include a field field3 | > may have quite unintended consequences. | > | > | > What I am missing most in the record arena | > is a functional notation for record update, for example: | > | > {^ field1 } = \ f r -> r {field1 = f (field1 r)} | | I agree, capturing variables without asking is just scary. | While I'm pretty biased I still think my suggestion solves the problem | in a cleaner, more consistent way. | | /Adde | | _______________________________________________ | Haskell-prime mailing list | Haskell-prime@haskell.org | http://www.haskell.org/mailman/listinfo/haskell-prime From wss at Cs.Nott.AC.UK Wed Jul 11 06:07:03 2007 From: wss at Cs.Nott.AC.UK (Wouter Swierstra) Date: Wed Jul 11 06:01:09 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> <1184100012.20597.46.camel@freestyler> Message-ID: On 11 Jul 2007, at 08:38, Simon Peyton-Jones wrote: > Another alternative (which I got from Greg Morrisett) that I'm > toying with is this. It's tiresome to write > > do { x <- > ; y <- > ; f x y } > > In ML I'd write simply > > f Using Control.Applicative you could already write: f <$> x <*> y I don't see the immediate need for more syntactic sugar - this is about as concise as it can get and it does not require compiler extensions. All the best, Wouter This message has been checked for viruses but the contents of an attachment may still contain software viruses, which could damage your computer system: you are advised to perform your own checks. Email communications with the University of Nottingham may be monitored as permitted by UK legislation. From apfelmus at quantentunnel.de Wed Jul 11 06:13:28 2007 From: apfelmus at quantentunnel.de (apfelmus) Date: Wed Jul 11 06:07:15 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> <1184100012.20597.46.camel@freestyler> Message-ID: Wouter Swierstra wrote: > > On 11 Jul 2007, at 08:38, Simon Peyton-Jones wrote: > >> Another alternative (which I got from Greg Morrisett) that I'm toying >> with is this. It's tiresome to write >> >> do { x <- >> ; y <- >> ; f x y } >> >> In ML I'd write simply >> >> f > > Using Control.Applicative you could already write: > > f <$> x <*> y No, since f is not a pure function, it's f :: x -> y -> m c. The correct form would be join $ f <$> x <*> y (Why doesn't haddock document infix precedences?) But maybe some type-class hackery can be used to eliminate the join. In any case, I'm *strongly against* further syntactic sugar for monads, including #1518. The more tiresome monads are, the more incentive you have to avoid them. Regards, apfelmus From bulat.ziganshin at gmail.com Wed Jul 11 06:32:20 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Wed Jul 11 06:30:14 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> <1184100012.20597.46.camel@freestyler> Message-ID: <1688665061.20070711143220@gmail.com> Hello Simon, Wednesday, July 11, 2007, 11:38:31 AM, you wrote: > So Greg's idea (or at least my understanding thereof) is to write it like this: > do { f $(stuff1) $(stuff2) } Simon, it is thing i dreamed for a years! Haskell has serious drawback for imperative programming compared to C - each action should be written as separate statement and this makes program too wordy - just try to rewrite something like x[i] += y[i]*z[i] in Haskell i need a way to perform actions and read data values inside calculations. there are two possible ways: * write pure expressions like we do in C and let's ghc guess yourself where evaluation should be added: x <- newIORef 1 y <- newIORef 1 z <- newIORef 1 f x (y*z) this means that any expression of type IORef a or IO a automatically translated into evaluation. the same should work for arrays, hashes and so on, so it probably should be a class. the problem, of course, is that IO/IORef/.. is a first class values so it's hard to distinguish where it should be evaluated and where used as is. another problem is its interaction with type inference - we may not know which concrete type this expression has * add an explicit operation which evaluates data, as you suggests. again, it should be a class which allows to add evaluation support for hashes/... actually, ML has something similar - it uses "." operation to evaluate variable values ============================================================================= and, while we on this topic, another problem for imperative programming style usability is control structures. how we can rewrite the following: delta=1000 while (delta>0.01) x = ... if (x<0) break delta = abs(n-x*x) ============================================================================= btw, proposal of "prefix expressions" also simplifies imperative programs a bit: now we should write something like this: when (a>0) $ do ..... while this proposal allows to omit "$" and make program look a bit more natural ============================================================================= one more complaint: the syntax for list $ \item -> do .... doesn't look too natural compared to other languages. it will be great to write it as for item in list do .... - of course, with 'for' still a plain function defined by user ============================================================================= may be, i should collect all these ideas on "imperative programming" page? -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ctm at cs.nott.ac.uk Wed Jul 11 08:25:15 2007 From: ctm at cs.nott.ac.uk (Conor McBride) Date: Wed Jul 11 08:18:59 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> <1184100012.20597.46.camel@freestyler> Message-ID: Hi On 11 Jul 2007, at 11:13, apfelmus wrote: > Wouter Swierstra wrote: >> >> >> Using Control.Applicative you could already write: >> >> f <$> x <*> y > > No, since f is not a pure function, it's f :: x -> y -> m c. The > correct > form would be > > join $ f <$> x <*> y > > (Why doesn't haddock document infix precedences?) But maybe some > type-class hackery can be used to eliminate the join. Indeed it can. Ignoring conventional wisdom about dirty linen, here are idiom brackets > class Applicative i => Idiomatic i f g | g -> f i where > idiomatic :: i f -> g > iI :: Idiomatic i f g => f -> g > iI = idiomatic . pure > data Ii = Ii > instance Applicative i => Idiomatic i x (Ii -> i x) where > idiomatic xi Ii = xi > instance Idiomatic i f g => Idiomatic i (s -> f) (i s -> g) where > idiomatic sfi si = idiomatic (sfi <*> si) So that iI f x y Ii = f <$> x <*> y Now add > data Ji = Ji > instance (Monad i, Applicative i) => Idiomatic i (i x) (Ji -> i x) where > idiomatic xii Ji = join xii and you've got iI f x y Ji = join $ f <$> x <*> y or, more flexibly, > data J = J > instance (Monad i, Idiomatic i f g) => Idiomatic i (i f) (J -> g) where > idiomatic fii J = idiomatic (join fii) so you can insert joins wherever you like, thus: iI f x y J z Ii = join (f <$> x <*> y) <*> z = do {x' <- x; y' <- y; f' <- f x y; z' <- z; return (f' z')} Of course, the implementation is an ugly hack, made uglier still by ASCII. Worse, for reasons I have never entirely understood, the type-class hackery doesn't allow these brackets to nest as they should. Even so, I find them a considerable convenience. I always assumed that was down to peculiarity on my part. I thought I'd present it as a curio illustrating part of the design space, but I don't imagine there's that big a market for an "idiom brackets done properly" proposal. All the best Conor From dons at cse.unsw.edu.au Wed Jul 11 08:33:56 2007 From: dons at cse.unsw.edu.au (Donald Bruce Stewart) Date: Wed Jul 11 08:27:29 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> <1184100012.20597.46.camel@freestyler> Message-ID: <20070711123356.GA2418@cse.unsw.EDU.AU> ctm: > Indeed it can. Ignoring conventional wisdom about dirty linen, here are > idiom brackets > > > class Applicative i => Idiomatic i f g | g -> f i where > > idiomatic :: i f -> g > > > iI :: Idiomatic i f g => f -> g > > iI = idiomatic . pure > > > data Ii = Ii > > > instance Applicative i => Idiomatic i x (Ii -> i x) where > > idiomatic xi Ii = xi > > instance Idiomatic i f g => Idiomatic i (s -> f) (i s -> g) where > > idiomatic sfi si = idiomatic (sfi <*> si) > > So that > > iI f x y Ii = f <$> x <*> y > > Now add > > > data Ji = Ji > > > instance (Monad i, Applicative i) => Idiomatic i (i x) (Ji -> i > x) where > > idiomatic xii Ji = join xii > > and you've got > > iI f x y Ji = join $ f <$> x <*> y Very nice! Just so we don't forget this, I created a wiki page, http://haskell.org/haskellwiki/Idiom_brackets -- Don From magnus at galois.com Wed Jul 11 16:43:33 2007 From: magnus at galois.com (Magnus Carlsson) Date: Wed Jul 11 16:37:10 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184078302.20597.39.camel@freestyler> <4693AFD3.9020201@charter.net> <20070710170447.19454.qmail@schroeder.cas.mcmaster.ca> <1184100012.20597.46.camel@freestyler> Message-ID: <469540F5.7060406@galois.com> It is actually easy to play with this idea using Template Haskell, modulo some syntax. I implemented a little library called MEval last year that exports a TH preprocessing function meval :: Meval a => Q a -> Q a and a "magic" variable p :: Monad m => m a -> a The preprocessing function will perform Greg's translation whenever it finds Meval.p applied to something inside a do statement. I find this approach useful especially when you want to evaluate monadic arguments inside arithmetic expressions or infix expressions in general. Then, the combinator approach provided with Control.Applicative tends to obscure the expressions. Other examples are case and if expressions in which you want to scrutinize monadic expressions. I attach a tar file with the library and an example program, feel free to hack away on them. Cheers, Magnus Simon Peyton-Jones wrote: > Another alternative (which I got from Greg Morrisett) that I'm toying with is this. It's tiresome to write > > do { x <- > ; y <- > ; f x y } > > In ML I'd write simply > > f > > So Greg's idea (or at least my understanding thereof) is to write it like this: > > do { f $(stuff1) $(stuff2) } > > The idea is that a "splice" $e must be lexically enclosed by a 'do', with no intervening lambda. It's desugared to the code above; that is, each splice it pulled out, in lexically left-right order, and given a name, which replaces the splice. > > Of course it doesn't have to look like the above; the rule applies to any do: > > do { v <- this; foo $(h v); y <- f $(t v v); ...etc } > > The "linearise the splices" rule is quite general. > > Don't burn any cycles on concrete syntax; I know the $ notation is used for Template Haskell; one would need to think of a good syntax. But the idea is to make it more convenient to write programs that make effectful calls, and then use the result exactly once. > > Anyway, this'd do what the original proposer wanted, but in a much more general way. > > Just a thought -- I have not implemented this. > > Simon > > | -----Original Message----- > | From: haskell-prime-bounces@haskell.org [mailto:haskell-prime-bounces@haskell.org] On Behalf Of Adde > | Sent: 10 July 2007 21:40 > | To: kahl@cas.mcmaster.ca > | Cc: haskell-prime@haskell.org > | Subject: Re: Make it possible to evaluate monadic actions when assigning record fields > | > | On Tue, 2007-07-10 at 17:04 +0000, kahl@cas.mcmaster.ca wrote: > | > Isaac Dupree wrote: > | > > > | > > Adde wrote: > | > > > tmp <- foo > | > > > return Bar { > | > > > barFoo = tmp > | > > > } > | > > > | > > There is a feature being worked on in GHC HEAD that would let you do > | > > > | > > do > | > > tmp <- foo > | > > return Bar{..} > | > > > | > > which captures fields from everything of the same name that's in scope. > | > > I think this would also satisfy your desire. > | > > > | > > | > I guess this means I could write: > | > > | > > | > data D = C {field1 :: Bool, field2 :: Char} > | > > | > f x = do > | > field1 <- foo1 > | > field2 <- foo2 > | > field3 <- foo3 > | > other stuff > | > return C{..} > | > > | > > | > instead of > | > > | > > | > f x = do > | > tmp1 <- foo1 > | > tmp2 <- foo2 > | > field3 <- foo3 > | > other stuff > | > return $ C { field1 = tmp1, field2 = tmp2 } > | > > | > > | > This has a dangerous feel to it --- > | > extending the definition of D to include a field field3 > | > may have quite unintended consequences. > | > > | > > | > What I am missing most in the record arena > | > is a functional notation for record update, for example: > | > > | > {^ field1 } = \ f r -> r {field1 = f (field1 r)} > | > | I agree, capturing variables without asking is just scary. > | While I'm pretty biased I still think my suggestion solves the problem > | in a cleaner, more consistent way. > | > | /Adde > | > | _______________________________________________ > | Haskell-prime mailing list > | Haskell-prime@haskell.org > | http://www.haskell.org/mailman/listinfo/haskell-prime -------------- next part -------------- A non-text attachment was scrubbed... Name: MEval.tar.gz Type: application/x-gzip Size: 2259 bytes Desc: not available Url : http://www.haskell.org/pipermail/haskell-prime/attachments/20070711/c2c4ecda/MEval.tar-0001.bin From adde at trialcode.com Wed Jul 11 17:39:51 2007 From: adde at trialcode.com (Adde) Date: Wed Jul 11 17:36:51 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields Message-ID: <1184189991.20597.101.camel@freestyler> Monads are a part of Haskell. The more tiresome monads are to use, the more tiresome Haskell is to use. I suggest we leave the decision of where and when to use them to each individual user of the language. /Adde > In any case, I'm *strongly against* further syntactic sugar for > monads, > including #1518. The more tiresome monads are, the more incentive you > have to avoid them. > > Regards, > apfelmus From apfelmus at quantentunnel.de Thu Jul 12 05:18:42 2007 From: apfelmus at quantentunnel.de (apfelmus) Date: Thu Jul 12 05:12:24 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: <1184189991.20597.101.camel@freestyler> References: <1184189991.20597.101.camel@freestyler> Message-ID: Adde wrote: > apfelmus wrote: >> In any case, I'm *strongly against* further syntactic sugar for >> monads, including #1518. The more tiresome monads are, the more >> incentive you have to avoid them. > > Monads are a part of Haskell. The more tiresome monads are to use, the > more tiresome Haskell is to use. I suggest we leave the decision of > where and when to use them to each individual user of the language. Well, only the monads will remain as "tiresome" as they are now. Also, the most intriguing fact about monads (or rather about Haskell) is that they are not a (built-in) part of the language, they are "just" a type class. Sure, there is do-notation, but >>= is not much clumsier than that. In the end, I think that applicatively used monads are the wrong abstraction. For occasional use, liftM2 and `ap` often suffice. If the applicative style becomes prevalent, then Applicative Functors are likely to be the conceptually better choice. This is especially true for MonadReader. Arithmetic expressions are a case for liftM, too. And an instance (Monad m, Num a) => Num (m a) allows to keep infix (+) and (*). Put differently, I don't see a compelling use-case for the proposed syntax extension. But I've seen many misused monads. Regards, apfelmus From simonpj at microsoft.com Thu Jul 12 06:55:04 2007 From: simonpj at microsoft.com (Simon Peyton-Jones) Date: Thu Jul 12 06:48:29 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184189991.20597.101.camel@freestyler> Message-ID: | In the end, I think that applicatively used monads are the wrong | abstraction. For occasional use, liftM2 and `ap` often suffice. If the | applicative style becomes prevalent, then Applicative Functors are | likely to be the conceptually better choice. This is especially true | for | MonadReader. Arithmetic expressions are a case for liftM, too. And an | instance (Monad m, Num a) => Num (m a) allows to keep infix (+) and | (*). | | Put differently, I don't see a compelling use-case for the proposed | syntax extension. But I've seen many misused monads. Can you be more explicit? Monadic code is often over-linearised. I want to generate fresh names, say, and suddenly I have to name sub-expressions. Not all sub-expressions, just the effectful ones. It'a a pain to define liftM_yes_no_yes which takes an effectful argument in first and third position, and a non-effectful one as the second arg: liftM_yes_no_yes :: (a->b->c->m d) -> m a -> b -> m c -> m d What a pain. So we have either do { ...; va <- a; vc <- c; f va b vc; ... } or do { ...; liftM_yes_no_yes f a b c; ...} or, with some syntactic sugar... do { ...; f $(a) b $(c); ...} The liftM solution is even more awkward if I want f (g $(a)) b c for example. I'm thinking of this as a very superficial piece of syntactic sugar, aimed at avoiding the excessive linearization of monadic code. Nothing deep. Of course adding more syntactic sugar has a cost; but this one looks like having a good power to weight ratio. Simon From ndmitchell at gmail.com Thu Jul 12 07:10:10 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Thu Jul 12 07:03:36 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184189991.20597.101.camel@freestyler> Message-ID: <404396ef0707120410i3753de78ud776cf670169df1f@mail.gmail.com> Hi > Put differently, I don't see a compelling use-case for the proposed > syntax extension. But I've seen many misused monads. A compelling use-case: http://darcs.haskell.org/yhc/src/libraries/core/Yhc/Core/Simplify.hs Look at coreSimplifyExprUniqueExt And from that file: -- helpers, ' is yes, _ is no coreCase__ x y = f $ CoreCase x y ; coreCase_' x y = f . CoreCase x =<< y coreLet__ x y = f $ CoreLet x y ; coreLet_' x y = f . CoreLet x =<< y coreLam__ x y = f $ CoreLam x y ; coreLam_' x y = f . CoreLam x =<< y coreApp__ x y = f $ CoreApp x y ; coreApp'_ x y = f . flip CoreApp y =<< x i.e. i've manually defined ' and _ variants to thread monadic effects through in quite horrible ways. The monad in question simply supplies free variables, so could be applied in any order. I think with this extension I can define: coreCase x y = f $ CoreCase x y coreLet x y = f $ CoreLet x y ... And taking just one rule, before: f (CoreApp (CoreLet bind xs) ys) = coreLet_' bind (coreApp__ xs ys) After: f (CoreApp (CoreLet bind xs) ys) = coreLet bind $(coreApp xs ys) Much nicer! This extension seems like a great idea - my only concern would be about the order of computations. Clearly left-to-right makes sense, but this may break some natural intuition in Haskell: flip f a b == f b a flip f $(a) $(b) /= f $(b) $(a) I don't think that is a show stopper though. Thanks Neil From bulat.ziganshin at gmail.com Thu Jul 12 07:46:21 2007 From: bulat.ziganshin at gmail.com (Bulat Ziganshin) Date: Thu Jul 12 07:44:29 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: <404396ef0707120410i3753de78ud776cf670169df1f@mail.gmail.com> References: <1184189991.20597.101.camel@freestyler> <404396ef0707120410i3753de78ud776cf670169df1f@mail.gmail.com> Message-ID: <8710475479.20070712154621@gmail.com> Hello Neil, Thursday, July 12, 2007, 3:10:10 PM, you wrote: > This extension seems like a great idea - my only concern would be > about the order of computations. Clearly left-to-right makes sense, > but this may break some natural intuition in Haskell: i think that undefined order will be a best one -- Best regards, Bulat mailto:Bulat.Ziganshin@gmail.com From ndmitchell at gmail.com Thu Jul 12 08:26:37 2007 From: ndmitchell at gmail.com (Neil Mitchell) Date: Thu Jul 12 08:20:02 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: <8710475479.20070712154621@gmail.com> References: <1184189991.20597.101.camel@freestyler> <404396ef0707120410i3753de78ud776cf670169df1f@mail.gmail.com> <8710475479.20070712154621@gmail.com> Message-ID: <404396ef0707120526p5e734d4am9261c9753da533f9@mail.gmail.com> Hi > > This extension seems like a great idea - my only concern would be > > about the order of computations. Clearly left-to-right makes sense, > > but this may break some natural intuition in Haskell: > > i think that undefined order will be a best one Using "undefined" does not make for great reading in a standard! You just know that Hugs will pick right to left, Yhc will pick left to right, and GHC will offer a flag to choose between them ;) We have to pick, and there is only one logical choice - left to right. Thanks Neil From claus.reinke at talk21.com Thu Jul 12 09:33:01 2007 From: claus.reinke at talk21.com (Claus Reinke) Date: Thu Jul 12 09:26:32 2007 Subject: Make it possible to evaluate monadic actions when assigningrecord fields References: <1184189991.20597.101.camel@freestyler> <404396ef0707120410i3753de78ud776cf670169df1f@mail.gmail.com> Message-ID: <00b701c7c489$2c6d6940$9c297ad5@cr3lt> >> Put differently, I don't see a compelling use-case for the proposed >> syntax extension. But I've seen many misused monads. > > A compelling use-case: > > http://darcs.haskell.org/yhc/src/libraries/core/Yhc/Core/Simplify.hs > > Look at coreSimplifyExprUniqueExt > -- helpers, ' is yes, _ is no > coreCase__ x y = f $ CoreCase x y coreCase_' x y = f . CoreCase x =<< y hmm. i'd say that is a compelling misuse-case!-) although apfelmus probably meant misuses in the sense that a different structure than monads would often have been a better fit, i just mean readability. why not simply define coreCaseM x y = f =<< liftM2 CoreCase x y etc. then this > f (CoreApp (CoreLet bind xs) ys) = coreLet_' bind (coreApp__ xs ys) would become somewhat lengthier, but much easier to read f (CoreApp (CoreLet bind xs) ys) = coreLetM (return bind) (coreAppM (return xs) (return ys)) in particular, there aren't 2^n variations of the functions, but simple return-wrappers around parameters that immediately tell me what is going on. if anything, i'd often like a quieter/shorter way to write (return x) - since this pattern usually requires parentheses, some form of semantic brackets would do nicely, to express lifting of pure values. that would serve the same overall purpose, without semantic ambiguities, wouldn't it? btw, this half-implicit recursion via an f embedded in constructors looks rather odd to me. why not separate rules and recursion? claus From apfelmus at quantentunnel.de Thu Jul 12 10:40:51 2007 From: apfelmus at quantentunnel.de (apfelmus) Date: Thu Jul 12 10:34:30 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184189991.20597.101.camel@freestyler> Message-ID: apfelmus wrote: > In the end, I think that applicatively used monads are the wrong > abstraction. Simon Peyton-Jones wrote: > Can you be more explicit? Monadic code is often over-linearised. > I want to generate fresh names, say, and suddenly I have to name > sub-expressions. Not all sub-expressions, just the effectful ones. Neil Mitchell wrote: > The monad in question simply supplies free variables, so could be > applied in any order. I see, the dreaded name-supply problem. Well, it just seems that monads are not quite the right abstraction for that one, right? (Despite that monads make up a good implementation). In other words, my opinion is that it's not the monadic code that is over-linearized but the code that is over-monadized. The main property of a "monad" for name-supply is of course f >> g = g >> f modulo alpha-conversion. Although we have to specify an order, it's completely immaterial. There _has_ to be a better abstraction than "monad" to capture this! SPJ: > It'a a pain to define liftM_yes_no_yes which takes an effectful > argument in first and third position, and a non-effectful one as > the second arg: > > liftM_yes_no_yes :: (a->b->c->m d) > -> m a -> b -> m c -> m d > > What a pain. So we have either > > do { ...; va <- a; vc <- c; f va b vc; ... } > > or > do { ...; liftM_yes_no_yes f a b c; ...} > > or, with some syntactic sugar... > > do { ...; f $(a) b $(c); ...} > > The liftM solution is even more awkward if I want > > f (g $(a)) b c > > for example. (the last one is already a typo, i guess you mean f $(g $(a)) b c) Neil: > -- helpers, ' is yes, _ is no > > coreLet__ x y = f $ CoreLet x y > coreLet_' x y = f . CoreLet x =<< y > > coreLet x y = f $ CoreLet x y > > f (CoreApp (CoreLet bind xs) ys) = coreLet bind $(coreApp xs ys) > Uhm, but you guys know that while (m a -> a) requires the proposed syntactic sugar, (a -> m a) is easy? r = return elevateM f x1 = join $ liftM f x1 elevateM3 f x1 x2 x3 = join $ liftM3 f x1 x2 x3 do { ...; elevateM3 f a (r$ b) c; ...} elevateM3 f (elevateM g a) (r$ b) (r$ c) coreLet x y = liftM2 CoreLet x y >>= f g (CoreApp (CoreLet bind xs) ys) = coreLet (r$ bind) (coreApp xs ys) In other words, you can avoid creating special yes_no_yes wrappers by creating a yes_yes_yes wrapper and turning a no into a yes here and there. No need for turning yes into no. One could even use left-associative infix operators ($@) :: (a -> b) -> a -> b ($@@) :: Monad m => (m a -> b) -> a -> b ($@) = id ($@@) = id . return and currying elevateM3 f $@@ (elevateM g $@@ a) $@ b $@ c g (CoreApp (CoreLet bind xs) ys) = coreLet $@ bind $@@ coreApp xs ys The intention is that a (mixed!) sequence of operators should parse as f $@ x1 $@@ x2 $@ x3 = ((f $@ x1) $@@ x2) $@ x3 Leaving such games aside, the fact that yes_yes_yes-wrappers subsumes the others is a hint that types like NameSupply Expr -> NameSupply Expr -> NameSupply Expr are fundamental. In other words, the right type for expressions is probably not Expr but NameSupply Expr with the interpretation that the latter represents expressions with "holes" where the concrete names for variables are filled in. The crucial point is that holes may be _shared_, i.e. supplying free variable names will fill several holes with the same name. Put differently, the question is: how to share names without giving concrete names too early? I think it's exactly the same question as How to make sharing observable? This is a problem that haunts many people and probably every DSL-embedder (Lava for Hardware, Pan for Images, Henning Thielemann's work on sound synthesis, Frisby for parser combinators). In a sense, writing a Haskell compiler is similar to embedding a DSL. I have no practical experiences with the name-supply problem. So, the first question is: can the name-supply problem indeed be solved by some form of observable sharing? Having a concrete toy-language showing common patterns of the name-supply problem would be ideal for that. The second task would be to solve the observable sharing problem, _that_ would require some syntactic sugar. Currently, one can use MonadFix to "solve" it. Let's take parser combinators as an example. The left-recursive grammar digit -> 0 | .. | 9 number -> number' digit number' -> ? | number can be represented by something like mdo digit <- newRule $ foldr1 (|||) [0...9] number <- newRule $ number' &&& digit number' <- newRule $ empty ||| number This way, we can observe the sharing and break the left recursion. But of course, the monad is nothing more than syntactic sugar here, the order does not matter at all. What we really want to write is a custom let-expression let' digit = foldr1 (|||) [0..9] number = number' &&& digit number' = empty ||| number and still be able to observe sharing. SPJ: > I'm thinking of this as a very superficial piece of syntactic sugar, > aimed at avoiding the excessive linearization of monadic code. Nothing deep. I don't agree, the excessive linearization is a feature, not a bug. Even if the sugar would be nothing deep, that shouldn't stop us from thinking deeply about it :) Regards, apfelmus From haskell.vivian.mcphail at gmail.com Sat Jul 14 17:04:16 2007 From: haskell.vivian.mcphail at gmail.com (Vivian McPhail) Date: Sat Jul 14 16:57:34 2007 Subject: (Succ Haskell') `and` $ dependent types Message-ID: <7b03b3c60707141404g7ea25b2bq1ddf825b93643b71@mail.gmail.com> Hello, As the authors point out [1], coal-face time needs to be expended before real world adoption of Dependently-Typed functional programming. But let's get the ball rolling. They say that haskell programmers are normally averse to dependent types. Is this true? It seems to me that one of the appeals of Haskell is the ability to program in a "prove perfect, write once" (elegant) style. Is not dependent typing a good move towards this goal?. It addresses a problem [2] with which we, in our everyday common inter-hominem usage, can deal -- with which (ideal) Haskell should deal. While the major Haskell implementations would require a substantial overhaul, the change at the syntactic level appears to be minimal. There also needs to be advance with respect to programmer development (automatic edit-time inference of (some) types). What are peoples' thoughts on adding dependent types to haskell as a non-incremental evolutionary step? Does the haskell community want to stick with conservative additions to Haskell and a static base, or does the haskell community want to stay in step with the best theoretical developments? Vivian [1] http://www.informatik.uni-bonn.de/~loeh/LambdaPi.html [2] http://thread.gmane.org/gmane.comp.lang.haskell.cafe/21314 -------------- next part -------------- An HTML attachment was scrubbed... URL: http://www.haskell.org/pipermail/haskell-prime/attachments/20070715/8d4d161e/attachment.htm From stefanor at cox.net Sat Jul 14 17:27:58 2007 From: stefanor at cox.net (Stefan O'Rear) Date: Sat Jul 14 17:21:16 2007 Subject: (Succ Haskell') `and` $ dependent types In-Reply-To: <7b03b3c60707141404g7ea25b2bq1ddf825b93643b71@mail.gmail.com> References: <7b03b3c60707141404g7ea25b2bq1ddf825b93643b71@mail.gmail.com> Message-ID: <20070714212758.GA4146@localhost.localdomain> On Sun, Jul 15, 2007 at 09:04:16AM +1200, Vivian McPhail wrote: > Hello, > > As the authors point out [1], coal-face time needs to be expended before > real world adoption of Dependently-Typed functional programming. But let's > get the ball rolling. They say that haskell programmers are normally > averse > to dependent types. Is this true? It seems to me that one of the appeals > of Haskell is the ability to program in a "prove perfect, write once" > (elegant) style. Is not dependent typing a good move towards this goal?. > It addresses a problem [2] with which we, in our everyday common > inter-hominem usage, can deal -- with which (ideal) Haskell should deal. > > While the major Haskell implementations would require a substantial > overhaul, the change at the syntactic level appears to be minimal. There > also needs to be advance with respect to programmer development (automatic > edit-time inference of (some) types). What are peoples' thoughts on adding > dependent types to haskell as a non-incremental evolutionary step? Does > the > haskell community want to stick with conservative additions to Haskell and > a > static base, or does the haskell community want to stay in step with the > best theoretical developments? > > Vivian > > [1] http://www.informatik.uni-bonn.de/~loeh/LambdaPi.html > [2] http://thread.gmane.org/gmane.comp.lang.haskell.cafe/21314 Dependant types aren't new, they're ten times older than Haskell ;) I don't even think that adding dependant types to Haskell would be that hard. Most of the needed infrastructure (notably the binder rule, lexically scoped type variables, and explicit instantiation) already exists in the implementation of rank-N types in GHC. I think much of the work would be in revising Core (currently it uses a variant of Barandregt's ??, which is strictly less powerful (IIUC) than the full dependant ?C) and flattening the typeinfer/kindinfer staging. Of course, since Haskell is not strongly normalizing, we would not be able to use a calculus where applications of CONV are implicit. Interaction with qualified types (type classes, MPTC, fundeps, implicit parameters, extensible records, associated type synonym equality predicates, etc) could be interesting, in both senses of the word. Stefan -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 189 bytes Desc: Digital signature Url : http://www.haskell.org/pipermail/haskell-prime/attachments/20070714/948a6e87/attachment.bin From isaacdupree at charter.net Sat Jul 14 19:04:26 2007 From: isaacdupree at charter.net (Isaac Dupree) Date: Sat Jul 14 18:59:01 2007 Subject: Make it possible to evaluate monadic actions when assigning record fields In-Reply-To: References: <1184189991.20597.101.camel@freestyler> Message-ID: <4699567A.9060609@charter.net> apfelmus wrote: > I see, the dreaded name-supply problem. Well, it just seems that monads > are not quite the right abstraction for that one, right? (Despite that > monads make up a good implementation). In other words, my opinion is > that it's not the monadic code that is over-linearized but the code that > is over-monadized. > > The main property of a "monad" for name-supply is of course > > f >> g = g >> f > > modulo alpha-conversion. Although we have to specify an order, it's > completely immaterial. There _has_ to be a better abstraction than > "monad" to capture this! I agree completely! It would be nice if the compiler could choose any order (or none at all, depending on implementation?) at its discretion. If serialization(where the gaps are filled with actual strings as names) produces different results depending on the order (similar to name-supply *monad*: not(f >> g = g >> f) in a too-significant way), we have a purity violation if the order is not well-defined. Big problem. So we need to make sure they are used in an abstracted enough manner - perhaps only an instance of Eq, to make sharing/uniqueness/identity detectable, no more. In dependently-typed languages I think we could have data structures that were fast but provably didn't depend in their operation on the material of ordering, for example, for lookup. Association-lists only need Eq but can be a little slow... So with this technique in Haskell, Frisby for example would examine the infinite tree starting at the returned root, and choose an order for internal use based on the shape of the tree (which represents a *cyclic* graph) -- it would be unable to use ordering provided by name-supply sequencing(monad). Which is just fine for it. (except for being O((number of rules)^2) to construct a parser, using association lists, I think.) Further abstraction could be added with a primitive UniqueNameMap of sorts, similar to (Map UniqueName a)... not enjoyable, so it might manage to be implemented in terms of some unsafe operations :-/. I hope my pessimism here is proved wrong :) Isaac From cdsmith at twu.net Sun Jul 15 22:01:22 2007 From: cdsmith at twu.net (Chris Smith) Date: Sun Jul 15 22:03:15 2007 Subject: Make it possible to evaluate monadic actions when assigningrecord fields References: <1184189991.20597.101.camel@freestyler> <404396ef0707120410i3753de78ud776cf670169df1f@mail.gmail.com> <00b701c7c489$2c6d6940$9c297ad5@cr3lt> Message-ID: Hope you don't mind my butting in. If you're looking for a "compelling use case" to make programming with monads more natural in Haskell, I'd say STM makes for a good one. There is no question there as to whether a monad is the right way to do STM; it is required. In working on some code recently that uses STM rather heavily, what I've found is that there are a couple things that make the experience somewhat painful despite the general promise of the technique. The most important is fixed by Simon's proposal for monad splices. I'd literally jump for joy if something like this were included in a future version of Haskell! Frankly, I don't think anyone will be convinced to use a more functional style by making programming in the STM monad more painful to do in Haskell. Instead, they will be convinced to be more hesitant about using Haskell for concurrent programming. -- Chris Smith From iavor.diatchki at gmail.com Mon Jul 16 23:22:14 2007 From: iavor.diatchki at gmail.com (Iavor Diatchki) Date: Mon Jul 16 23:15:25 2007 Subject: Make it possible to evaluate monadic actions when assigningrecord fields In-Reply-To: References: <1184189991.20597.101.camel@freestyler> <404396ef0707120410i3753de78ud776cf670169df1f@mail.gmail.com> <00b701c7c489$2c6d6940$9c297ad5@cr3lt> Message-ID: <5ab17e790707162022p3b2c7099oc796eb3d40222751@mail.gmail.com> Hello, I find the naming of values that is introduced by the "do" notation useful and I am not at all convinced that the extra sugar that is being proposed here makes the language simpler. It seems to me that the only way to know that a piece of code is safe would be to: i) do the translation in your head to convince yourself that the effects will be executed in the right order, ii) make sure that you are using a commutative monad, or the order of the effects is not important. I like the current status quo because: i) for values I can apply the usual pure reasoning that I am used to in Haskell, ii) this makes it easier to refactor code, at least for me (e.g., it is easy to insert a 'seq' here and there to control evaluation if I have to) iii) I find that it is easier to understand code that is a bit more explicit because I have to keep less translations in my head iv) I can use "fmap" and "ap" (and friends, e.g., like what Connor suggested) to achieve a style that is similar to the imperative one, when I think that the explicit naming is clumsy. -Iavor PS: Someone suggested that this syntactic sugar might be useful in the context of STM or concurrent programming but I am skeptical about that example because in that setting the order of effects is very important... I could be convinced with examples though :-) On 7/15/07, Chris Smith wrote: > Hope you don't mind my butting in. > > If you're looking for a "compelling use case" to make programming with > monads more natural in Haskell, I'd say STM makes for a good one. There > is no question there as to whether a monad is the right way to do STM; > it is required. > > In working on some code recently that uses STM rather heavily, what I've > found is that there are a couple things that make the experience > somewhat painful despite the general promise of the technique. The most > important is fixed by Simon's proposal for monad splices. I'd literally > jump for joy if something like this were included in a future version of > Haskell! > > Frankly, I don't think anyone will be convinced to use a more functional > style by making programming in the STM monad more painful to do in > Haskell. Instead, they will be convinced to be more hesitant about > using Haskell for concurrent programming. > > -- > Chris Smith > > _______________________________________________ > Haskell-prime mailing list > Haskell-prime@haskell.org > http://www.haskell.org/mailman/listinfo/haskell-prime >