From compl.yue at icloud.com Wed Sep 1 06:25:22 2021 From: compl.yue at icloud.com (YueCompl) Date: Wed, 1 Sep 2021 14:25:22 +0800 Subject: [Haskell-cafe] Examples of Continuation monad that impossible to understand and maintain? In-Reply-To: <40C9B7EE-3F6F-4A63-AEDA-E1B9B4E02C37@mac.com> References: <6E7245AA-AC07-4B68-BFBE-A1B012A8303F@icloud.com> <40C9B7EE-3F6F-4A63-AEDA-E1B9B4E02C37@mac.com> Message-ID: <1DDE28D3-0BAC-4B09-9286-D6106BC2C8E8@icloud.com> I can understand the purpose if it is advising against overusing surface syntax in CPS, but here the approach is to hide continuation beneath the beloved do notation on the surface, and monad laws plus possibly further laws to be added, will make it safer to program programs by end programmers. I do realize CPS is powerful yet dangerous (unsafe), abuse of CPS could be easy and quite unintentional, but what about abuse of "Continuation monad"? > On 2021-08-31, at 22:46, Jeff Clites via Haskell-Cafe wrote: > > Based on the preceding paragraph, I think that by “abuse” it means overuse, as in using CPS when you could have used straightforward code. I can imagine someone doing at the source code level the sort of things that would be done by a CPS-based compiler (converting everything possible to CPS), and ending up with a mess. > > For example, imagine you started with this code snippet: > > let x = f a > y = g x > in h x y > > If you fully convert that to CPS you’d end up with 3 continuations (I think) and it would be much harder to understand. And adding an additional let binding later might involve a bunch of restructuring. > > I assume it just means that sort of thing. When someone first learns about continuations and their generality, it can be tempting to go overboard. > > Jeff > > On Aug 31, 2021, at 3:03 AM, YueCompl via Haskell-Cafe > wrote: > >> Dear Cafe, >> >> I'm wrapping up my CPS codebase to provide some monadic interface, it appears almost the Cont monad, so the following statement is a pretty valid caveat to me now: >> >> > Abuse of the Continuation monad can produce code that is impossible to understand and maintain. >> >> Which can be viewed in context of Hackage at: https://hackage.haskell.org/package/mtl/docs/Control-Monad-Cont.html#:~:text=Abuse%20of%20the%20Continuation%20monad%20can%20produce%20code%20that%20is%20impossible%20to%20understand%20and%20maintain >> >> But I can't find concrete examples demonstrating the "impossible to understand and maintain" situation, in figuring out what pitfalls I'd rather to avoid. >> >> Please share what you know about it, many appreciations! >> >> Background of my CPS necessarity: >> >> Library code need to delegate STM transaction boundary delimitation to (scripting) application code, though `inlineSTM :: STM a -> m a` can be used to force some action to be within current tx, the usual `>>=` binding should honor whether a separate `atomically` tx should be issued for its rhs computation, as specified by the scripting context. >> >> Thanks, >> Compl >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From isaace71295 at gmail.com Wed Sep 1 07:55:11 2021 From: isaace71295 at gmail.com (Isaac Elliott) Date: Wed, 1 Sep 2021 17:55:11 +1000 Subject: [Haskell-cafe] Examples of Continuation monad that impossible to understand and maintain? In-Reply-To: <1DDE28D3-0BAC-4B09-9286-D6106BC2C8E8@icloud.com> References: <6E7245AA-AC07-4B68-BFBE-A1B012A8303F@icloud.com> <40C9B7EE-3F6F-4A63-AEDA-E1B9B4E02C37@mac.com> <1DDE28D3-0BAC-4B09-9286-D6106BC2C8E8@icloud.com> Message-ID: I don't have any examples. Given that Cont essentially implements unstructured control flow, I think that examples of `goto` misuse would apply by analogy. On Wed, 1 Sep 2021, 4:31 pm YueCompl via Haskell-Cafe, < haskell-cafe at haskell.org> wrote: > I can understand the purpose if it is advising against overusing surface > syntax in CPS, but here the approach is to hide continuation beneath the > beloved do notation on the surface, and monad laws plus possibly further > laws to be added, will make it safer to program programs by end > programmers. > > I do realize CPS is powerful yet dangerous (unsafe), abuse of CPS could be > easy and quite unintentional, but what about abuse of "Continuation monad"? > > On 2021-08-31, at 22:46, Jeff Clites via Haskell-Cafe < > haskell-cafe at haskell.org> wrote: > > Based on the preceding paragraph, I think that by “abuse” it means > overuse, as in using CPS when you could have used straightforward code. I > can imagine someone doing at the source code level the sort of things that > would be done by a CPS-based compiler (converting everything possible to > CPS), and ending up with a mess. > > For example, imagine you started with this code snippet: > > let x = f a > y = g x > in h x y > > If you fully convert that to CPS you’d end up with 3 continuations (I > think) and it would be much harder to understand. And adding an additional > let binding later might involve a bunch of restructuring. > > I assume it just means that sort of thing. When someone first learns about > continuations and their generality, it can be tempting to go overboard. > > Jeff > > On Aug 31, 2021, at 3:03 AM, YueCompl via Haskell-Cafe < > haskell-cafe at haskell.org> wrote: > > Dear Cafe, > > I'm wrapping up my CPS codebase to provide some monadic interface, it > appears almost the Cont monad, so the following statement is a pretty valid > caveat to me now: > > > Abuse of the Continuation monad can produce code that is impossible to > understand and maintain. > > Which can be viewed in context of Hackage at: > https://hackage.haskell.org/package/mtl/docs/Control-Monad-Cont.html#:~:text=Abuse%20of%20the%20Continuation%20monad%20can%20produce%20code%20that%20is%20impossible%20to%20understand%20and%20maintain > > > But I can't find concrete examples demonstrating the "impossible to > understand and maintain" situation, in figuring out what pitfalls I'd > rather to avoid. > > Please share what you know about it, many appreciations! > > Background of my CPS necessarity: > > Library code need to delegate STM transaction boundary delimitation to > (scripting) application code, though `inlineSTM :: STM a -> m a` can be > used to force some action to be within current tx, the usual `>>=` binding > should honor whether a separate `atomically` tx should be issued for its > rhs computation, as specified by the scripting context. > > Thanks, > Compl > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From compl.yue at icloud.com Wed Sep 1 08:31:56 2021 From: compl.yue at icloud.com (YueCompl) Date: Wed, 1 Sep 2021 16:31:56 +0800 Subject: [Haskell-cafe] Examples of Continuation monad that impossible to understand and maintain? In-Reply-To: References: <6E7245AA-AC07-4B68-BFBE-A1B012A8303F@icloud.com> <40C9B7EE-3F6F-4A63-AEDA-E1B9B4E02C37@mac.com> <1DDE28D3-0BAC-4B09-9286-D6106BC2C8E8@icloud.com> Message-ID: <8B090CEB-2D38-45C5-A657-AF8F8F393524@icloud.com> Am I understanding it right that all ways upward since the monad layer (assuming all laws are strictly followed) of "Continuation monad", the programmer is restricted to "structured programming" practices, unless he/she resort to the continuation mechanism beneath the monad layer, only in where `goto` is available? I think I can relax if that's the case, CPS is inevitable in this case of mine, and I can at least hide its unsafety beneath the Continuation monad from junior developers in my team. > On 2021-09-01, at 15:55, Isaac Elliott wrote: > > I don't have any examples. Given that Cont essentially implements unstructured control flow, I think that examples of `goto` misuse would apply by analogy. > > On Wed, 1 Sep 2021, 4:31 pm YueCompl via Haskell-Cafe, > wrote: > I can understand the purpose if it is advising against overusing surface syntax in CPS, but here the approach is to hide continuation beneath the beloved do notation on the surface, and monad laws plus possibly further laws to be added, will make it safer to program programs by end programmers. > > I do realize CPS is powerful yet dangerous (unsafe), abuse of CPS could be easy and quite unintentional, but what about abuse of "Continuation monad"? > >> On 2021-08-31, at 22:46, Jeff Clites via Haskell-Cafe > wrote: >> >> Based on the preceding paragraph, I think that by “abuse” it means overuse, as in using CPS when you could have used straightforward code. I can imagine someone doing at the source code level the sort of things that would be done by a CPS-based compiler (converting everything possible to CPS), and ending up with a mess. >> >> For example, imagine you started with this code snippet: >> >> let x = f a >> y = g x >> in h x y >> >> If you fully convert that to CPS you’d end up with 3 continuations (I think) and it would be much harder to understand. And adding an additional let binding later might involve a bunch of restructuring. >> >> I assume it just means that sort of thing. When someone first learns about continuations and their generality, it can be tempting to go overboard. >> >> Jeff >> >> On Aug 31, 2021, at 3:03 AM, YueCompl via Haskell-Cafe > wrote: >> >>> Dear Cafe, >>> >>> I'm wrapping up my CPS codebase to provide some monadic interface, it appears almost the Cont monad, so the following statement is a pretty valid caveat to me now: >>> >>> > Abuse of the Continuation monad can produce code that is impossible to understand and maintain. >>> >>> Which can be viewed in context of Hackage at: https://hackage.haskell.org/package/mtl/docs/Control-Monad-Cont.html#:~:text=Abuse%20of%20the%20Continuation%20monad%20can%20produce%20code%20that%20is%20impossible%20to%20understand%20and%20maintain >>> >>> But I can't find concrete examples demonstrating the "impossible to understand and maintain" situation, in figuring out what pitfalls I'd rather to avoid. >>> >>> Please share what you know about it, many appreciations! >>> >>> Background of my CPS necessarity: >>> >>> Library code need to delegate STM transaction boundary delimitation to (scripting) application code, though `inlineSTM :: STM a -> m a` can be used to force some action to be within current tx, the usual `>>=` binding should honor whether a separate `atomically` tx should be issued for its rhs computation, as specified by the scripting context. >>> >>> Thanks, >>> Compl >>> >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From isaace71295 at gmail.com Wed Sep 1 08:54:17 2021 From: isaace71295 at gmail.com (Isaac Elliott) Date: Wed, 1 Sep 2021 18:54:17 +1000 Subject: [Haskell-cafe] Examples of Continuation monad that impossible to understand and maintain? In-Reply-To: <8B090CEB-2D38-45C5-A657-AF8F8F393524@icloud.com> References: <6E7245AA-AC07-4B68-BFBE-A1B012A8303F@icloud.com> <40C9B7EE-3F6F-4A63-AEDA-E1B9B4E02C37@mac.com> <1DDE28D3-0BAC-4B09-9286-D6106BC2C8E8@icloud.com> <8B090CEB-2D38-45C5-A657-AF8F8F393524@icloud.com> Message-ID: If you hide the usages of callCC behind a sound API then it shouldn't be much of an issue, if that's what you're saying. On Wed, 1 Sep 2021, 6:32 pm YueCompl, wrote: > Am I understanding it right that all ways upward since the monad layer > (assuming all laws are strictly followed) of "Continuation monad", the > programmer is restricted to "structured programming" practices, unless > he/she resort to the continuation mechanism beneath the monad layer, only > in where `goto` is available? > > I think I can relax if that's the case, CPS is inevitable in this case of > mine, and I can at least hide its unsafety beneath the Continuation monad > from junior developers in my team. > > On 2021-09-01, at 15:55, Isaac Elliott wrote: > > I don't have any examples. Given that Cont essentially implements > unstructured control flow, I think that examples of `goto` misuse would > apply by analogy. > > On Wed, 1 Sep 2021, 4:31 pm YueCompl via Haskell-Cafe, < > haskell-cafe at haskell.org> wrote: > >> I can understand the purpose if it is advising against overusing surface >> syntax in CPS, but here the approach is to hide continuation beneath the >> beloved do notation on the surface, and monad laws plus possibly further >> laws to be added, will make it safer to program programs by end >> programmers. >> >> I do realize CPS is powerful yet dangerous (unsafe), abuse of CPS could >> be easy and quite unintentional, but what about abuse of "Continuation >> monad"? >> >> On 2021-08-31, at 22:46, Jeff Clites via Haskell-Cafe < >> haskell-cafe at haskell.org> wrote: >> >> Based on the preceding paragraph, I think that by “abuse” it means >> overuse, as in using CPS when you could have used straightforward code. I >> can imagine someone doing at the source code level the sort of things that >> would be done by a CPS-based compiler (converting everything possible to >> CPS), and ending up with a mess. >> >> For example, imagine you started with this code snippet: >> >> let x = f a >> y = g x >> in h x y >> >> If you fully convert that to CPS you’d end up with 3 continuations (I >> think) and it would be much harder to understand. And adding an additional >> let binding later might involve a bunch of restructuring. >> >> I assume it just means that sort of thing. When someone first learns >> about continuations and their generality, it can be tempting to go >> overboard. >> >> Jeff >> >> On Aug 31, 2021, at 3:03 AM, YueCompl via Haskell-Cafe < >> haskell-cafe at haskell.org> wrote: >> >> Dear Cafe, >> >> I'm wrapping up my CPS codebase to provide some monadic interface, it >> appears almost the Cont monad, so the following statement is a pretty valid >> caveat to me now: >> >> > Abuse of the Continuation monad can produce code that is impossible to >> understand and maintain. >> >> Which can be viewed in context of Hackage at: >> https://hackage.haskell.org/package/mtl/docs/Control-Monad-Cont.html#:~:text=Abuse%20of%20the%20Continuation%20monad%20can%20produce%20code%20that%20is%20impossible%20to%20understand%20and%20maintain >> >> >> But I can't find concrete examples demonstrating the "impossible to >> understand and maintain" situation, in figuring out what pitfalls I'd >> rather to avoid. >> >> Please share what you know about it, many appreciations! >> >> Background of my CPS necessarity: >> >> Library code need to delegate STM transaction boundary delimitation to >> (scripting) application code, though `inlineSTM :: STM a -> m a` can be >> used to force some action to be within current tx, the usual `>>=` binding >> should honor whether a separate `atomically` tx should be issued for its >> rhs computation, as specified by the scripting context. >> >> Thanks, >> Compl >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From compl.yue at icloud.com Wed Sep 1 09:10:08 2021 From: compl.yue at icloud.com (YueCompl) Date: Wed, 1 Sep 2021 17:10:08 +0800 Subject: [Haskell-cafe] Examples of Continuation monad that impossible to understand and maintain? In-Reply-To: References: <6E7245AA-AC07-4B68-BFBE-A1B012A8303F@icloud.com> <40C9B7EE-3F6F-4A63-AEDA-E1B9B4E02C37@mac.com> <1DDE28D3-0BAC-4B09-9286-D6106BC2C8E8@icloud.com> <8B090CEB-2D38-45C5-A657-AF8F8F393524@icloud.com> Message-ID: Ah, yes, I provide a couple of `callCC` equivalent APIs but I think I'll documented them clearly as "advanced" API, besides other more business-oriented, "safe" APIs. > On 2021-09-01, at 16:54, Isaac Elliott wrote: > > If you hide the usages of callCC behind a sound API then it shouldn't be much of an issue, if that's what you're saying. > > On Wed, 1 Sep 2021, 6:32 pm YueCompl, > wrote: > Am I understanding it right that all ways upward since the monad layer (assuming all laws are strictly followed) of "Continuation monad", the programmer is restricted to "structured programming" practices, unless he/she resort to the continuation mechanism beneath the monad layer, only in where `goto` is available? > > I think I can relax if that's the case, CPS is inevitable in this case of mine, and I can at least hide its unsafety beneath the Continuation monad from junior developers in my team. > >> On 2021-09-01, at 15:55, Isaac Elliott > wrote: >> >> I don't have any examples. Given that Cont essentially implements unstructured control flow, I think that examples of `goto` misuse would apply by analogy. >> >> On Wed, 1 Sep 2021, 4:31 pm YueCompl via Haskell-Cafe, > wrote: >> I can understand the purpose if it is advising against overusing surface syntax in CPS, but here the approach is to hide continuation beneath the beloved do notation on the surface, and monad laws plus possibly further laws to be added, will make it safer to program programs by end programmers. >> >> I do realize CPS is powerful yet dangerous (unsafe), abuse of CPS could be easy and quite unintentional, but what about abuse of "Continuation monad"? >> >>> On 2021-08-31, at 22:46, Jeff Clites via Haskell-Cafe > wrote: >>> >>> Based on the preceding paragraph, I think that by “abuse” it means overuse, as in using CPS when you could have used straightforward code. I can imagine someone doing at the source code level the sort of things that would be done by a CPS-based compiler (converting everything possible to CPS), and ending up with a mess. >>> >>> For example, imagine you started with this code snippet: >>> >>> let x = f a >>> y = g x >>> in h x y >>> >>> If you fully convert that to CPS you’d end up with 3 continuations (I think) and it would be much harder to understand. And adding an additional let binding later might involve a bunch of restructuring. >>> >>> I assume it just means that sort of thing. When someone first learns about continuations and their generality, it can be tempting to go overboard. >>> >>> Jeff >>> >>> On Aug 31, 2021, at 3:03 AM, YueCompl via Haskell-Cafe > wrote: >>> >>>> Dear Cafe, >>>> >>>> I'm wrapping up my CPS codebase to provide some monadic interface, it appears almost the Cont monad, so the following statement is a pretty valid caveat to me now: >>>> >>>> > Abuse of the Continuation monad can produce code that is impossible to understand and maintain. >>>> >>>> Which can be viewed in context of Hackage at: https://hackage.haskell.org/package/mtl/docs/Control-Monad-Cont.html#:~:text=Abuse%20of%20the%20Continuation%20monad%20can%20produce%20code%20that%20is%20impossible%20to%20understand%20and%20maintain >>>> >>>> But I can't find concrete examples demonstrating the "impossible to understand and maintain" situation, in figuring out what pitfalls I'd rather to avoid. >>>> >>>> Please share what you know about it, many appreciations! >>>> >>>> Background of my CPS necessarity: >>>> >>>> Library code need to delegate STM transaction boundary delimitation to (scripting) application code, though `inlineSTM :: STM a -> m a` can be used to force some action to be within current tx, the usual `>>=` binding should honor whether a separate `atomically` tx should be issued for its rhs computation, as specified by the scripting context. >>>> >>>> Thanks, >>>> Compl >>>> >>>> _______________________________________________ >>>> Haskell-Cafe mailing list >>>> To (un)subscribe, modify options or view archives go to: >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>>> Only members subscribed via the mailman list are allowed to post. >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From sperber at deinprogramm.de Wed Sep 1 10:47:20 2021 From: sperber at deinprogramm.de (Michael Sperber) Date: Wed, 01 Sep 2021 12:47:20 +0200 Subject: [Haskell-cafe] Type synonym involing quantified constraint? In-Reply-To: <010f017b9d66ad82-3e7746d7-e103-400f-92fb-f4edcabbd824-000000@us-east-2.amazonses.com> (Richard Eisenberg's message of "Tue, 31 Aug 2021 18:09:17 +0000") References: <010f017b9d66ad82-3e7746d7-e103-400f-92fb-f4edcabbd824-000000@us-east-2.amazonses.com> Message-ID: Thanks for looking at this! On Tue, Aug 31 2021, Richard Eisenberg wrote: > This looks like a bug, which I've now filed: https://gitlab.haskell.org/ghc/ghc/-/issues/20318 > > The workaround is to enable ImpredicativeTypes. So I did that and then tried defining it like this: type OkProd'' :: (Type -> Type -> Type) -> Constraint type OkProd'' k = forall okk. (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y)) ... but get: src/ConCat/Category.hs:228:1: error: • You can't specify an instance for a tuple constraint • In the quantified constraint ‘forall (okk :: * -> Constraint). (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y))’ In the type synonym declaration for ‘OkProd''’ (What does this message even mean? :-) ) -- Regards, Mike From olf at aatal-apotheke.de Wed Sep 1 14:44:38 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Wed, 01 Sep 2021 16:44:38 +0200 Subject: [Haskell-cafe] broadcasting stateful computations Message-ID: Dear Café, I have a sequence of state-modifying computations action :: MonadUnliftIO m => StateT s m () where the state s should be visible to other threads. Thus I created a TVar in which I keep track of this state s for other threads to read. The type system tells me it can't be done, which suggests I am using the wrong abstraction. The following type-checks but may be unsafe. import Control.Concurrent.STM import Control.Monad.IO.Unlift updateStateTVar :: MonadUnliftIO m => TVar s -> StateT s m () -> m () updateStateTVar var action = withRunInIO (\inIO -> do s0 <- atomically (readTVar var) s1 <- inIO (execStateT action s0) atomically (writeTVar var s1)) Yet the splitting into readTVar and writeTVar is dangerous if several threads have read/write access to the same TVar. I was hoping to write the above using modifyTVar. However, the action essentially gives me a Kleisli map s -> m s which I somehow have to turn into an m (s -> s) but it is not possible in general. (The reverse works for any functor.) What should I do? * Switch to WriterT (Endo s) m? This is not as powerful as StateT s m. * Do everything in the STM monad? But this disallows arbitrary IO because it would facilitate nested STM transactions. The code above is safe, I believe, if only one thread has read/write access and the others are read-only. Are there type-level abstractions of this kind? (I suppose one could easily make them with some newtypes.) Thanks in advance for any thoughts on this. Olaf From b at chreekat.net Wed Sep 1 15:12:01 2021 From: b at chreekat.net (Bryan Richter) Date: Wed, 1 Sep 2021 18:12:01 +0300 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: References: Message-ID: You've maybe already considered this, but what if the TVar is part of the state s? (StateT IO) can't give any guarantees about when or how the state is broadcast, but using STM within StateT actions still can. On Wed, 1 Sep 2021, 17.45 Olaf Klinke, wrote: > Dear Café, > > I have a sequence of state-modifying computations > > action :: MonadUnliftIO m => StateT s m () > > where the state s should be visible to other threads. Thus I created a > TVar in which I keep track of this state s for other threads to read. > > The type system tells me it can't be done, which suggests I am using > the wrong abstraction. The following type-checks but may be unsafe. > > import Control.Concurrent.STM > import Control.Monad.IO.Unlift > updateStateTVar :: MonadUnliftIO m => TVar s -> StateT s m () -> m () > updateStateTVar var action = withRunInIO (\inIO -> do > s0 <- atomically (readTVar var) > s1 <- inIO (execStateT action s0) > atomically (writeTVar var s1)) > > Yet the splitting into readTVar and writeTVar is dangerous if several > threads have read/write access to the same TVar. I was hoping to write > the above using modifyTVar. However, the action essentially gives me a > Kleisli map > s -> m s > which I somehow have to turn into an > m (s -> s) > but it is not possible in general. (The reverse works for any functor.) > > What should I do? > * Switch to WriterT (Endo s) m? > This is not as powerful as StateT s m. > * Do everything in the STM monad? But this disallows arbitrary IO > because it would facilitate nested STM transactions. > > The code above is safe, I believe, if only one thread has read/write > access and the others are read-only. Are there type-level abstractions > of this kind? (I suppose one could easily make them with some > newtypes.) > > Thanks in advance for any thoughts on this. > Olaf > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Wed Sep 1 15:21:03 2021 From: cdsmith at gmail.com (Chris Smith) Date: Wed, 1 Sep 2021 11:21:03 -0400 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: References: Message-ID: I had the same suggestion. However, you then no longer need StateT, as ReaderT is enough. Using a `ReaderT (TVar s) IO a` will allow atomic changes to the state s, along with interleaved IO when it's done safely rather than in the middle of a transaction. On Wed, Sep 1, 2021 at 11:17 AM Bryan Richter wrote: > You've maybe already considered this, but what if the TVar is part of the > state s? > > (StateT IO) can't give any guarantees about when or how the state is > broadcast, but using STM within StateT actions still can. > > On Wed, 1 Sep 2021, 17.45 Olaf Klinke, wrote: > >> Dear Café, >> >> I have a sequence of state-modifying computations >> >> action :: MonadUnliftIO m => StateT s m () >> >> where the state s should be visible to other threads. Thus I created a >> TVar in which I keep track of this state s for other threads to read. >> >> The type system tells me it can't be done, which suggests I am using >> the wrong abstraction. The following type-checks but may be unsafe. >> >> import Control.Concurrent.STM >> import Control.Monad.IO.Unlift >> updateStateTVar :: MonadUnliftIO m => TVar s -> StateT s m () -> m () >> updateStateTVar var action = withRunInIO (\inIO -> do >> s0 <- atomically (readTVar var) >> s1 <- inIO (execStateT action s0) >> atomically (writeTVar var s1)) >> >> Yet the splitting into readTVar and writeTVar is dangerous if several >> threads have read/write access to the same TVar. I was hoping to write >> the above using modifyTVar. However, the action essentially gives me a >> Kleisli map >> s -> m s >> which I somehow have to turn into an >> m (s -> s) >> but it is not possible in general. (The reverse works for any functor.) >> >> What should I do? >> * Switch to WriterT (Endo s) m? >> This is not as powerful as StateT s m. >> * Do everything in the STM monad? But this disallows arbitrary IO >> because it would facilitate nested STM transactions. >> >> The code above is safe, I believe, if only one thread has read/write >> access and the others are read-only. Are there type-level abstractions >> of this kind? (I suppose one could easily make them with some >> newtypes.) >> >> Thanks in advance for any thoughts on this. >> Olaf >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From isaace71295 at gmail.com Wed Sep 1 15:28:58 2021 From: isaace71295 at gmail.com (Isaac Elliott) Date: Thu, 2 Sep 2021 01:28:58 +1000 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: References: Message-ID: What about creating a MonadState instance for the TVar? newtype SharedStateT m a = SharedStateT (ReaderT (TVar s) m a) instance MonadIO m => MonadState s (SharedStateT s m) where get = SharedStateT $ liftIO . readTVarIO =<< ask put s = SharedStateT $ do tvar <- ask liftIO . atomically $ writeTVar tvar s state f = SharedStateT $ do tvar <- ask liftIO . atomically $ stateTVar tvar f On Thu, 2 Sep 2021, 12:50 am Olaf Klinke, wrote: > Dear Café, > > I have a sequence of state-modifying computations > > action :: MonadUnliftIO m => StateT s m () > > where the state s should be visible to other threads. Thus I created a > TVar in which I keep track of this state s for other threads to read. > > The type system tells me it can't be done, which suggests I am using > the wrong abstraction. The following type-checks but may be unsafe. > > import Control.Concurrent.STM > import Control.Monad.IO.Unlift > updateStateTVar :: MonadUnliftIO m => TVar s -> StateT s m () -> m () > updateStateTVar var action = withRunInIO (\inIO -> do > s0 <- atomically (readTVar var) > s1 <- inIO (execStateT action s0) > atomically (writeTVar var s1)) > > Yet the splitting into readTVar and writeTVar is dangerous if several > threads have read/write access to the same TVar. I was hoping to write > the above using modifyTVar. However, the action essentially gives me a > Kleisli map > s -> m s > which I somehow have to turn into an > m (s -> s) > but it is not possible in general. (The reverse works for any functor.) > > What should I do? > * Switch to WriterT (Endo s) m? > This is not as powerful as StateT s m. > * Do everything in the STM monad? But this disallows arbitrary IO > because it would facilitate nested STM transactions. > > The code above is safe, I believe, if only one thread has read/write > access and the others are read-only. Are there type-level abstractions > of this kind? (I suppose one could easily make them with some > newtypes.) > > Thanks in advance for any thoughts on this. > Olaf > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From compl.yue at icloud.com Thu Sep 2 08:45:48 2021 From: compl.yue at icloud.com (YueCompl) Date: Thu, 2 Sep 2021 16:45:48 +0800 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: References: Message-ID: I believe this is the use case for TMVar, use `takeTMVar` / `putTMVar` instead of `readTVar` / `writeTVar` will do. And maybe `finally` `tryPutTMVar` back the original value you took out, in case sth went wrong before you can put an updated result back. > On 2021-09-01, at 22:44, Olaf Klinke wrote: > > Dear Café, > > I have a sequence of state-modifying computations > > action :: MonadUnliftIO m => StateT s m () > > where the state s should be visible to other threads. Thus I created a > TVar in which I keep track of this state s for other threads to read. > > The type system tells me it can't be done, which suggests I am using > the wrong abstraction. The following type-checks but may be unsafe. > > import Control.Concurrent.STM > import Control.Monad.IO.Unlift > updateStateTVar :: MonadUnliftIO m => TVar s -> StateT s m () -> m () > updateStateTVar var action = withRunInIO (\inIO -> do > s0 <- atomically (readTVar var) > s1 <- inIO (execStateT action s0) > atomically (writeTVar var s1)) > > Yet the splitting into readTVar and writeTVar is dangerous if several > threads have read/write access to the same TVar. I was hoping to write > the above using modifyTVar. However, the action essentially gives me a > Kleisli map > s -> m s > which I somehow have to turn into an > m (s -> s) > but it is not possible in general. (The reverse works for any functor.) > > What should I do? > * Switch to WriterT (Endo s) m? > This is not as powerful as StateT s m. > * Do everything in the STM monad? But this disallows arbitrary IO > because it would facilitate nested STM transactions. > > The code above is safe, I believe, if only one thread has read/write > access and the others are read-only. Are there type-level abstractions > of this kind? (I suppose one could easily make them with some > newtypes.) > > Thanks in advance for any thoughts on this. > Olaf > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From olf at aatal-apotheke.de Thu Sep 2 15:25:12 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Thu, 02 Sep 2021 17:25:12 +0200 Subject: [Haskell-cafe] broadcasting stateful computations Message-ID: Thanks everyone for the helpful suggestions! Bryan Richer wrote: > what if the TVar is part of the > state s? > (StateT IO) can't give any guarantees about when or how the state is > broadcast, but using STM within StateT actions still can. I don't understand this, but it may go into the same direction as: Chris Smith wrote: > I had the same suggestion. However, you then no longer need StateT, as > ReaderT is enough. Using a `ReaderT (TVar s) IO a` will allow atomic > changes to the state s, along with interleaved IO when it's done safely > rather than in the middle of a transaction. ReaderT (TVar s) IO is interesting! It does not solve the problem of atomic modifications with side-effects, though. Currently I am implicity using ReaderT (TVar s), by explicitly passing the TVar around. In principle, for atomic modifications I have to get hold of a pure version (s -> s) of the modification. Maybe within a monadic context. But if determining this modification function is side-effectful, then it can not depend on the initial contents of the TVar! This leads me to the conclusion that either (a) atomic modification by a Kleisli map is impossible and another mechanism needs to ensure thread safety, or (b) we need to keep two versions of the state: one private, pure s and one public TVar s which we synchronize from time to time. The latter can be accomplished with atomic writes. More on that below. Isaac Elliott wrote: > What about creating a MonadState instance for the TVar? Very neat, but it would not solve the atomicity problem, since the update I have is not expressible as stateTVar. YueCompl wrote: > I believe this is the use case for TMVar, use `takeTMVar` / `putTMVar` instead of `readTVar` / `writeTVar` will do. TMVars appear non-empty for one thread only, as far as I understand. So any observer thread would be blocked while the worker thread is updating the state? Not good for my use case. The observer thread will be a webserver. I'd rather have the webserver report old states than block. I have neglected to mention one aspect of my problem that might be essential: All my state updates are monoidal. By that I mean that s is a monoid with s' <> s <> s = s' <> s and any effectful modification will be of the form f = \s -> (k s) >>= (\s' -> s' <> s) for some k :: s -> m s. This entails that instead of emitting modifications as functions I can emit modifications as values. emitModification :: (Monad m, Monoid s) => StateT s m a -> WriterT s (StateT s m) a emitModification (StateT f) = WriterT $ StateT $ \s -> do (a,s') <- f s return ((a,s'),s') broadcastModification :: (MonadIO m, Semigroup s) => TVar s -> (WriterT s m) a -> m a broadcastModification ref (WriterT m) = do (a,s') <- m (liftIO.atomically) (modifyTVar ref (\s -> s' <> s)) return a Then \ref -> broadcastModification ref . emitModification :: (MonadIO m, Monoid s) => TVar s -> StateT s m a -> StateT s m a This has the additional charm that I can explicitly control when writes to the TVar happen, by choosing which (StateT s m) blocks to enclose in this wrapper. I might even set up my communication as a TChan, if the observing thread maintains an own copy of state itself to merge the updates s' into. Olaf From compl.yue at icloud.com Thu Sep 2 16:00:10 2021 From: compl.yue at icloud.com (YueCompl) Date: Fri, 3 Sep 2021 00:00:10 +0800 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: References: Message-ID: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> Um, I'm not sure I understand your case right, but if the "mutation" instead of the "mutated result" can be (might non-trivially) computed from a possibly outdated state, and the "mutation" can be trivially applied, I think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an almost up-to-date state on demand, at low frequency. > On 2021-09-02, at 23:25, Olaf Klinke wrote: > > Thanks everyone for the helpful suggestions! > > Bryan Richer wrote: >> what if the TVar is part of the >> state s? >> (StateT IO) can't give any guarantees about when or how the state is >> broadcast, but using STM within StateT actions still can. > > I don't understand this, but it may go into the same direction as: > > Chris Smith wrote: >> I had the same suggestion. However, you then no longer need StateT, as >> ReaderT is enough. Using a `ReaderT (TVar s) IO a` will allow atomic >> changes to the state s, along with interleaved IO when it's done safely >> rather than in the middle of a transaction. > > ReaderT (TVar s) IO is interesting! It does not solve the problem of > atomic modifications with side-effects, though. Currently I am > implicity using ReaderT (TVar s), by explicitly passing the TVar > around. > > In principle, for atomic modifications I have to get hold of a pure > version (s -> s) of the modification. Maybe within a monadic context. > But if determining this modification function is side-effectful, then > it can not depend on the initial contents of the TVar! > > This leads me to the conclusion that either > (a) atomic modification by a Kleisli map is impossible and another > mechanism needs to ensure thread safety, or > (b) we need to keep two versions of the state: one private, pure s and > one public TVar s which we synchronize from time to time. The latter > can be accomplished with atomic writes. More on that below. > > Isaac Elliott wrote: >> What about creating a MonadState instance for the TVar? > Very neat, but it would not solve the atomicity problem, since the > update I have is not expressible as stateTVar. > > YueCompl wrote: >> I believe this is the use case for TMVar, use `takeTMVar` / `putTMVar` instead of `readTVar` / `writeTVar` will do. > > TMVars appear non-empty for one thread only, as far as I understand. > So any observer thread would be blocked while the worker thread is > updating the state? > Not good for my use case. The observer thread will be a webserver. > I'd rather have the webserver report old states than block. > > I have neglected to mention one aspect of my problem that might be > essential: All my state updates are monoidal. By that I mean that s is > a monoid with > s' <> s <> s = s' <> s > and any effectful modification will be of the form > f = \s -> (k s) >>= (\s' -> s' <> s) > for some k :: s -> m s. > This entails that instead of emitting modifications as functions I can > emit modifications as values. > > emitModification :: (Monad m, Monoid s) => > StateT s m a -> WriterT s (StateT s m) a > emitModification (StateT f) = WriterT $ StateT $ \s -> do > (a,s') <- f s > return ((a,s'),s') > > broadcastModification :: (MonadIO m, Semigroup s) => > TVar s -> (WriterT s m) a -> m a > broadcastModification ref (WriterT m) = do > (a,s') <- m > (liftIO.atomically) (modifyTVar ref (\s -> s' <> s)) > return a > > Then > \ref -> broadcastModification ref . emitModification > :: (MonadIO m, Monoid s) => > TVar s -> StateT s m a -> StateT s m a > > This has the additional charm that I can explicitly control when writes > to the TVar happen, by choosing which (StateT s m) blocks to enclose in > this wrapper. I might even set up my communication as a TChan, if the > observing thread maintains an own copy of state itself to merge the > updates s' into. > > Olaf > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From olf at aatal-apotheke.de Thu Sep 2 17:42:06 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Thu, 02 Sep 2021 19:42:06 +0200 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> References: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> Message-ID: <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> On Fri, 2021-09-03 at 00:00 +0800, YueCompl wrote: > Um, I'm not sure I understand your case right, but if the "mutation" instead of the "mutated result" can be (might non-trivially) computed from a possibly outdated state, and the "mutation" can be trivially applied, I think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an almost up-to-date state on demand, at low frequency. To be concrete, my state is a collection of time stamped values, where the monoid operation overwrites old values with new ones. But I need to know the current state (x,t) to determine the "mutation", because I'll be asking questions like "server, tell me if there is a value of x newer than t." Any observer whose initial state is synchronized with the worker thread can in principle re-construct the worker's internal state by observing the stream of emitted "mutations". The most general abstraction would be that of a monoid action on a type, but in my case the monoid (mutations) and the mutated type are identical. act :: m -> a -> a act memtpy = id act (x <> y) = act x . act y -- monoid homomorphism act (x <> x) = act x -- idempotent Olaf From lists at richarde.dev Thu Sep 2 18:04:48 2021 From: lists at richarde.dev (Richard Eisenberg) Date: Thu, 2 Sep 2021 18:04:48 +0000 Subject: [Haskell-cafe] Type synonym involing quantified constraint? In-Reply-To: References: <010f017b9d66ad82-3e7746d7-e103-400f-92fb-f4edcabbd824-000000@us-east-2.amazonses.com> Message-ID: <010f017ba7af4cf3-77ec4946-3867-40c6-ae94-5444852457e8-000000@us-east-2.amazonses.com> Hm. Interesting. You are trying to work around the fact that okk is not in scope. The problem is that GHC does not currently allow you to specify a tuple as the head of a quantified constraint. The thinking is that (forall x. premise => (conclusion1, conclusion2)) can always be refactored into (forall x. premise => conclusion1, forall x. premise => conclusion2). In your case, the refactoring is not so simple, but it can be done. Try > type OkProd k = forall (okk :: Type -> Constraint) x y. (okk ~ Ok k, okk x, okk y) => okk (Prod k x y) Does that work for you? If not, it may be helpful to see a function that uses the OkProd constraint somewhere. I hope this helps! Richard > On Sep 1, 2021, at 6:47 AM, Michael Sperber wrote: > > > Thanks for looking at this! > > On Tue, Aug 31 2021, Richard Eisenberg wrote: > >> This looks like a bug, which I've now filed: https://gitlab.haskell.org/ghc/ghc/-/issues/20318 >> >> The workaround is to enable ImpredicativeTypes. > > So I did that and then tried defining it like this: > > type OkProd'' :: (Type -> Type -> Type) -> Constraint > type OkProd'' k = forall okk. (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y)) > > ... but get: > > src/ConCat/Category.hs:228:1: error: > • You can't specify an instance for a tuple constraint > • In the quantified constraint ‘forall (okk :: * -> Constraint). > (okk ~ Ok k, forall x y. (okk x, okk y) => okk (Prod k x y))’ > In the type synonym declaration for ‘OkProd''’ > > (What does this message even mean? :-) ) > > -- > Regards, > Mike > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From isaace71295 at gmail.com Thu Sep 2 22:29:52 2021 From: isaace71295 at gmail.com (Isaac Elliott) Date: Fri, 3 Sep 2021 08:29:52 +1000 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> References: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> Message-ID: How about using a read-write lock? data Locked a = Locked { lockVar :: TVar Bool, valueVar :: TVar a } new :: a -> IO (Locked a) new val = Locked <$> newTVarIO False <*> newTVarIO val -- lock blocks until unlocked lock, unlock :: Locked a -> STM () -- never blocks read :: Locked a -> STM a -- blocks until unlocked write :: Locked a -> a -> STM () When you want to apply your effectful state trasition `f :: s -> m s`: l <- ask s <- liftIO . atomically $ lock l *> read l s' <- f s liftIO . atomically $ write l s' *> unlock l On Fri, 3 Sep 2021, 3:46 am Olaf Klinke, wrote: > On Fri, 2021-09-03 at 00:00 +0800, YueCompl wrote: > > Um, I'm not sure I understand your case right, but if the "mutation" > instead of the "mutated result" can be (might non-trivially) computed from > a possibly outdated state, and the "mutation" can be trivially applied, I > think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an > almost up-to-date state on demand, at low frequency. > > To be concrete, my state is a collection of time stamped values, where > the monoid operation overwrites old values with new ones. > But I need to know the current state (x,t) to determine the "mutation", > because I'll be asking questions like "server, tell me if there is a > value of x newer than t." > Any observer whose initial state is synchronized with the worker thread > can in principle re-construct the worker's internal state by observing > the stream of emitted "mutations". > > The most general abstraction would be that of a monoid action on a > type, but in my case the monoid (mutations) and the mutated type are > identical. > > act :: m -> a -> a > act memtpy = id > act (x <> y) = act x . act y -- monoid homomorphism > act (x <> x) = act x -- idempotent > > Olaf > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From compl.yue at icloud.com Fri Sep 3 08:26:10 2021 From: compl.yue at icloud.com (YueCompl) Date: Fri, 3 Sep 2021 16:26:10 +0800 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> References: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> Message-ID: <5111D395-F2CE-482F-AB5A-16F2A6E1F683@icloud.com> It's a bit sad that I'm not so mathematically minded to understand you in that abstract level. But I have a more imperative solution in my mind, wrt the question: > "server, tell me if there is a value of x newer than t." and do further mutate-or-giveup, like this: data ValueNode a = ValueNode { node'value :: a, node'timestamp :: Timestamp, node'next :: ValueSink a } type ValueSink a = TMVar (ValueNode a) type Timestamp = Int seekTail :: ValueSink a -> STM (ValueSink a, Maybe (ValueNode a)) seekTail sink = go sink Nothing where go ref ancestor = tryReadTMVar ref >>= \case Nothing -> return (ref, ancestor) Just self@(ValueNode _ _ nxt) -> go nxt $ Just self updateValue :: forall a m. MonadIO m => (Maybe (a, Timestamp) -> m (a, Timestamp)) -> ValueSink a -> m () updateValue f sink = do (tailRef, tailNode) <- liftIO $ atomically $ seekTail sink case tailNode of Nothing -> do (myVal, myTs) <- f Nothing liftIO $ atomically $ do nxt <- newEmptyTMVar void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt Just (ValueNode seenVal seenTs seenNxt) -> do (myVal, myTs) <- f $ Just (seenVal, seenTs) newNxt <- liftIO newEmptyTMVarIO let newTail = ValueNode myVal myTs newNxt putAsNewTailOrDiscard :: ValueSink a -> STM () putAsNewTailOrDiscard nodeRef = putTMVar nodeRef newTail `orElse` yetOther'sTail where yetOther'sTail = do (ValueNode _other'sVal other'sTs other'sNxt) <- readTMVar nodeRef if other'sTs >= myTs then return () else putAsNewTailOrDiscard other'sNxt liftIO $ atomically $ putAsNewTailOrDiscard seenNxt -- Each concurrent thread is supposed to have its local 'ValueSink' reference -- "cached" over time, but keep in mind that for any such thread who is slow -- in unfolding the value stream, the historical values will pile up in heap. > On 2021-09-03, at 01:42, Olaf Klinke wrote: > > On Fri, 2021-09-03 at 00:00 +0800, YueCompl wrote: >> Um, I'm not sure I understand your case right, but if the "mutation" instead of the "mutated result" can be (might non-trivially) computed from a possibly outdated state, and the "mutation" can be trivially applied, I think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an almost up-to-date state on demand, at low frequency. > > To be concrete, my state is a collection of time stamped values, where > the monoid operation overwrites old values with new ones. > But I need to know the current state (x,t) to determine the "mutation", > because I'll be asking questions like "server, tell me if there is a > value of x newer than t." > Any observer whose initial state is synchronized with the worker thread > can in principle re-construct the worker's internal state by observing > the stream of emitted "mutations". > > The most general abstraction would be that of a monoid action on a > type, but in my case the monoid (mutations) and the mutated type are > identical. > > act :: m -> a -> a > act memtpy = id > act (x <> y) = act x . act y -- monoid homomorphism > act (x <> x) = act x -- idempotent > > Olaf > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Fri Sep 3 09:58:27 2021 From: david.feuer at gmail.com (David Feuer) Date: Fri, 3 Sep 2021 05:58:27 -0400 Subject: [Haskell-cafe] New package: lazify Message-ID: Occasionally, it's useful to make things lazier. The utility-ht package has long offered forcePair :: (a,b) -> (a,b) forcePair ~(a,b) = (a,b) But that only works for pairs! If you want to work with records/tuples much more generally, now you can do so conveniently with the lazify package. Please take a look and let me know what you like and dislike, and whether there's anything more you want. https://hackage.haskell.org/package/lazify-0.1.0.1 From lemming at henning-thielemann.de Fri Sep 3 11:14:42 2021 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Fri, 3 Sep 2021 13:14:42 +0200 (CEST) Subject: [Haskell-cafe] New package: lazify In-Reply-To: References: Message-ID: <4f8d115a-1c7-625b-424e-4b5ccfe939d4@henning-thielemann.de> On Fri, 3 Sep 2021, David Feuer wrote: > Occasionally, it's useful to make things lazier. The utility-ht > package has long offered > > forcePair :: (a,b) -> (a,b) > forcePair ~(a,b) = (a,b) right :-) > But that only works for pairs! If you want to work with records/tuples > much more generally, now you can do so conveniently with the lazify > package. Please take a look and let me know what you like and dislike, > and whether there's anything more you want. > > https://hackage.haskell.org/package/lazify-0.1.0.1 It's shallow lazify, right? From david.feuer at gmail.com Fri Sep 3 11:21:47 2021 From: david.feuer at gmail.com (David Feuer) Date: Fri, 3 Sep 2021 07:21:47 -0400 Subject: [Haskell-cafe] New package: lazify In-Reply-To: <4f8d115a-1c7-625b-424e-4b5ccfe939d4@henning-thielemann.de> References: <4f8d115a-1c7-625b-424e-4b5ccfe939d4@henning-thielemann.de> Message-ID: Yes, shallow (but it looks through newtypes). To do it more deeply would require some way to mark where to stop. On Fri, Sep 3, 2021, 7:14 AM Henning Thielemann < lemming at henning-thielemann.de> wrote: > > On Fri, 3 Sep 2021, David Feuer wrote: > > > Occasionally, it's useful to make things lazier. The utility-ht > > package has long offered > > > > forcePair :: (a,b) -> (a,b) > > forcePair ~(a,b) = (a,b) > > right :-) > > > But that only works for pairs! If you want to work with records/tuples > > much more generally, now you can do so conveniently with the lazify > > package. Please take a look and let me know what you like and dislike, > > and whether there's anything more you want. > > > > https://hackage.haskell.org/package/lazify-0.1.0.1 > > It's shallow lazify, right? > -------------- next part -------------- An HTML attachment was scrubbed... URL: From dj112358 at outlook.com Fri Sep 3 12:02:53 2021 From: dj112358 at outlook.com (David James) Date: Fri, 3 Sep 2021 12:02:53 +0000 Subject: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows Message-ID: Hello all – I’m trying to debug a problem with asinh in Windows. On Linux (Ubuntu 18.04.5 LTS) running GHC 8.10.7, I get (I think correctly): GHCi, version 8.10.7: https://www.haskell.org/ghc/ :? for help Prelude> asinh 1.7976931348623157e308 710.4758600739439 But on Windows I get: GHCi, version 8.10.7: https://www.haskell.org/ghc/ :? for help Prelude> asinh 1.7976931348623157e308 NaN My understanding is that, since commit c6f4eb4f8 (released in GHC 8.8.1, I think), asinh is defined as a primop that just calls the c asinh function, so I tried the following code: In Main.hs: {-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE CApiFFI #-} module Main (main) where import Foreign import Foreign.C.Types foreign import ccall unsafe "math.h asinh" c_asinh :: Double -> Double foreign import ccall unsafe "CAsinh.c testFn" c_testFn :: IO () main :: IO () main = do putStrLn $ "asinh 1.7976931348623157e308 = " ++ show ( asinh 1.7976931348623157e308) putStrLn $ "c_asinh 1.7976931348623157e308 = " ++ show (c_asinh 1.7976931348623157e308) putStrLn "Calling c_testFn..." c_testFn In CAsinh.c: #include #include void testFn () { printf ("in testFn\n"); printf ("asinh(1.7976931348623157e308) = %f\n", asinh(1.7976931348623157e308)); double x = 1.7976931348623157e308; printf ("asinh(x) = %f\n", asinh(x)); } In Linux, this all works fine: asinh 1.7976931348623157e308 = 710.4758600739439 c_asinh 1.7976931348623157e308 = 710.4758600739439 Calling c_testFn... in testFn asinh(1.7976931348623157e308) = 710.475860 asinh(x) = 710.475860 But on Windows I get weird results: asinh 1.7976931348623157e308 = NaN c_asinh 1.7976931348623157e308 = NaN Calling c_testFn... in testFn asinh(1.7976931348623157e308) = 710.475860 asinh(x) = -1.#IND00 The primop call from Haskell to asinh and the FFI call to c_asinh give the same (incorrect) result, as I expected. But the first call to asinh from the c testFn gives the correct result. So why is that different to the FFI call from Haskell? And why doesn’t the second call from testFn return the right result? I also tested on 9.0.1 on Windows, with a slightly different result for the final asinh: ... asinh(x) = nan I’ve investigated the things I can think of (different foreign declarations, size of double being different, checking the code in cpp.sh), but can’t find an explanation. Am I doing something silly? Is this a (known) bug? Note that on Windows, values up to asinh 1.3407807929942596e154 work correctly. (As a little background: I was trying to implement the Kahan functions to give the correct branch cuts for complex trig functions, something I think the current Haskell implementation doesn’t do correctly. These depend on asinh, etc, on RealFloat numbers). Thanks very much for any help, David. * -------------- next part -------------- An HTML attachment was scrubbed... URL: From minorinoki at gmail.com Fri Sep 3 12:42:59 2021 From: minorinoki at gmail.com (arata, mizuki) Date: Fri, 3 Sep 2021 21:42:59 +0900 Subject: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows In-Reply-To: References: Message-ID: <8A7B2D58-37D0-4C29-88BF-7580BFF31064@gmail.com> Hi David, If I understand correctly, GHC uses mingw-w64’s libc implementation on Windows. Since mingw-w64’s math functions are not of very good quality, it is likely that asinh returns NaN for a very large input. As to why `asinh(1.7976931348623157e308)` in CAsinh.c produces (seemingly-correct) 710.4758, it is probably because the C compiler (GCC) uses a different implementation of asinh when doing constant folding. As a note, you may get a different (compile-time computed) result for `asinh(x)` if you set a more aggressive optimization flag. Mizuki From allbery.b at gmail.com Fri Sep 3 13:57:11 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 3 Sep 2021 09:57:11 -0400 Subject: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows In-Reply-To: <8A7B2D58-37D0-4C29-88BF-7580BFF31064@gmail.com> References: <8A7B2D58-37D0-4C29-88BF-7580BFF31064@gmail.com> Message-ID: I would also note that %f is the wrong printf flag to use with a double; you want %d. This shouldn't affect the result since you're only printing one value, but I don't know the Windows ABI so conceivably it might. On Fri, Sep 3, 2021 at 8:43 AM arata, mizuki wrote: > Hi David, > > If I understand correctly, GHC uses mingw-w64’s libc implementation on > Windows. > Since mingw-w64’s math functions are not of very good quality, it is > likely that asinh returns NaN for a very large input. > > As to why `asinh(1.7976931348623157e308)` in CAsinh.c produces > (seemingly-correct) 710.4758, it is probably because the C compiler (GCC) > uses a different implementation of asinh when doing constant folding. > As a note, you may get a different (compile-time computed) result for > `asinh(x)` if you set a more aggressive optimization flag. > > Mizuki > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From dj112358 at outlook.com Sat Sep 4 09:46:26 2021 From: dj112358 at outlook.com (David James) Date: Sat, 4 Sep 2021 09:46:26 +0000 Subject: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows In-Reply-To: <8A7B2D58-37D0-4C29-88BF-7580BFF31064@gmail.com> References: <8A7B2D58-37D0-4C29-88BF-7580BFF31064@gmail.com> Message-ID: Hi - thank you for this. I was unaware of the “constant folding” in GCC (and I’m surprised it works for functions like asinh), but I can see that it explains the difference in behaviour. So I think this is a (possibly minor) bug that Haskell inherits from mingw-w64. I guess I should raise a GHC issue – though I’m not sure whether it would be best to try to fix within Haskell or within mingw-w64. Also, I think the FloatFnInverses.hs test doesn’t should be showing as a fail somewhere in the CI testing. (It doesn’t give the expected output when I run it on Windows). Do you know whether/where I can see that? (I don’t know what CI happens or how to view its output). Thanks again, David. From: arata, mizuki Sent: 03 September 2021 13:43 To: David James Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows Hi David, If I understand correctly, GHC uses mingw-w64’s libc implementation on Windows. Since mingw-w64’s math functions are not of very good quality, it is likely that asinh returns NaN for a very large input. As to why `asinh(1.7976931348623157e308)` in CAsinh.c produces (seemingly-correct) 710.4758, it is probably because the C compiler (GCC) uses a different implementation of asinh when doing constant folding. As a note, you may get a different (compile-time computed) result for `asinh(x)` if you set a more aggressive optimization flag. Mizuki -------------- next part -------------- An HTML attachment was scrubbed... URL: From compl.yue at icloud.com Sat Sep 4 10:42:16 2021 From: compl.yue at icloud.com (YueCompl) Date: Sat, 4 Sep 2021 18:42:16 +0800 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: <5111D395-F2CE-482F-AB5A-16F2A6E1F683@icloud.com> References: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> <5111D395-F2CE-482F-AB5A-16F2A6E1F683@icloud.com> Message-ID: <83DE2F7E-2D61-429E-A90A-CC5AA5EB1814@icloud.com> I'd like to add a new feature that you can fold the historic value stream in deriving the new state value, then it becomes: data ValueNode a = ValueNode { node'value :: a, node'timestamp :: Timestamp, node'next :: ValueSink a } type ValueSink a = TMVar (ValueNode a) type Timestamp = Int seekTail :: forall a. (a -> Timestamp -> a -> Timestamp -> a) -> ValueSink a -> STM (ValueSink a, Maybe (ValueNode a)) seekTail f sink = go sink Nothing where go :: ValueSink a -> Maybe (ValueNode a) -> STM (ValueSink a, Maybe (ValueNode a)) go ref prevNode = tryReadTMVar ref >>= \case Nothing -> return (ref, prevNode) Just self@(ValueNode spotVal spotTs nxt) -> go nxt $ Just self { node'value = case prevNode of Nothing -> spotVal Just (ValueNode prevVal prevTs _prevNxt) -> f prevVal prevTs spotVal spotTs } updateValue :: forall a m. MonadIO m => (Maybe (a, Timestamp) -> m (a, Timestamp)) -> ValueSink a -> m () updateValue f sink = do (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink case tailNode of Nothing -> do (myVal, myTs) <- f Nothing liftIO $ atomically $ do nxt <- newEmptyTMVar void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt Just (ValueNode spotVal spotTs spotNxt) -> do (myVal, myTs) <- f $ Just (spotVal, spotTs) newNxt <- liftIO newEmptyTMVarIO let newTail = ValueNode myVal myTs newNxt putAsNewTailOrDiscard :: ValueSink a -> STM () putAsNewTailOrDiscard nodeRef = putTMVar nodeRef newTail `orElse` yetOther'sTail where yetOther'sTail = do (ValueNode _other'sVal other'sTs other'sNxt) <- readTMVar nodeRef if other'sTs >= myTs then return () else putAsNewTailOrDiscard other'sNxt liftIO $ atomically $ putAsNewTailOrDiscard spotNxt where justLatest :: (a -> Timestamp -> a -> Timestamp -> a) justLatest _prevVal _prevTs spotVal _spotTs = spotVal -- Each concurrent thread is supposed to have its local 'ValueSink' reference -- "cached" over time, but keep in mind that for any such thread who is slow -- in unfolding the value stream, the historical values will pile up in heap. > On 2021-09-03, at 16:26, YueCompl wrote: > > It's a bit sad that I'm not so mathematically minded to understand you in that abstract level. But I have a more imperative solution in my mind, wrt the question: > >> "server, tell me if there is a value of x newer than t." > > > and do further mutate-or-giveup, like this: > > > data ValueNode a = ValueNode > { node'value :: a, > node'timestamp :: Timestamp, > node'next :: ValueSink a > } > > type ValueSink a = TMVar (ValueNode a) > > type Timestamp = Int > > seekTail :: ValueSink a -> STM (ValueSink a, Maybe (ValueNode a)) > seekTail sink = go sink Nothing > where > go ref ancestor = > tryReadTMVar ref >>= \case > Nothing -> return (ref, ancestor) > Just self@(ValueNode _ _ nxt) -> go nxt $ Just self > > updateValue :: > forall a m. > MonadIO m => > (Maybe (a, Timestamp) -> m (a, Timestamp)) -> > ValueSink a -> > m () > updateValue f sink = do > (tailRef, tailNode) <- liftIO $ atomically $ seekTail sink > case tailNode of > Nothing -> do > (myVal, myTs) <- f Nothing > liftIO $ > atomically $ do > nxt <- newEmptyTMVar > void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt > Just (ValueNode seenVal seenTs seenNxt) -> do > (myVal, myTs) <- f $ Just (seenVal, seenTs) > newNxt <- liftIO newEmptyTMVarIO > let newTail = ValueNode myVal myTs newNxt > > putAsNewTailOrDiscard :: ValueSink a -> STM () > putAsNewTailOrDiscard nodeRef = > putTMVar nodeRef newTail `orElse` yetOther'sTail > where > yetOther'sTail = do > (ValueNode _other'sVal other'sTs other'sNxt) <- > readTMVar nodeRef > if other'sTs >= myTs > then return () > else putAsNewTailOrDiscard other'sNxt > > liftIO $ atomically $ putAsNewTailOrDiscard seenNxt > > -- Each concurrent thread is supposed to have its local 'ValueSink' reference > -- "cached" over time, but keep in mind that for any such thread who is slow > -- in unfolding the value stream, the historical values will pile up in heap. > > > >> On 2021-09-03, at 01:42, Olaf Klinke > wrote: >> >> On Fri, 2021-09-03 at 00:00 +0800, YueCompl wrote: >>> Um, I'm not sure I understand your case right, but if the "mutation" instead of the "mutated result" can be (might non-trivially) computed from a possibly outdated state, and the "mutation" can be trivially applied, I think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an almost up-to-date state on demand, at low frequency. >> >> To be concrete, my state is a collection of time stamped values, where >> the monoid operation overwrites old values with new ones. >> But I need to know the current state (x,t) to determine the "mutation", >> because I'll be asking questions like "server, tell me if there is a >> value of x newer than t." >> Any observer whose initial state is synchronized with the worker thread >> can in principle re-construct the worker's internal state by observing >> the stream of emitted "mutations". >> >> The most general abstraction would be that of a monoid action on a >> type, but in my case the monoid (mutations) and the mutated type are >> identical. >> >> act :: m -> a -> a >> act memtpy = id >> act (x <> y) = act x . act y -- monoid homomorphism >> act (x <> x) = act x -- idempotent >> >> Olaf >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From compl.yue at icloud.com Sat Sep 4 10:50:47 2021 From: compl.yue at icloud.com (YueCompl) Date: Sat, 4 Sep 2021 18:50:47 +0800 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: <83DE2F7E-2D61-429E-A90A-CC5AA5EB1814@icloud.com> References: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> <5111D395-F2CE-482F-AB5A-16F2A6E1F683@icloud.com> <83DE2F7E-2D61-429E-A90A-CC5AA5EB1814@icloud.com> Message-ID: <0D4B865D-3C17-4593-82A2-F6E2F1C6DDDA@icloud.com> Oh, a bugfix: the new tail reference should be returned after update, so a thread local stream reference can technically be cached. And I realize this is more than you originally need, never mind if it's not so useful to you. data ValueNode a = ValueNode { node'value :: a, node'timestamp :: Timestamp, node'next :: ValueSink a } type ValueSink a = TMVar (ValueNode a) type Timestamp = Int seekTail :: forall a. (a -> Timestamp -> a -> Timestamp -> a) -> ValueSink a -> STM (ValueSink a, Maybe (ValueNode a)) seekTail f sink = go sink Nothing where go :: ValueSink a -> Maybe (ValueNode a) -> STM (ValueSink a, Maybe (ValueNode a)) go ref prevNode = tryReadTMVar ref >>= \case Nothing -> return (ref, prevNode) Just self@(ValueNode spotVal spotTs nxt) -> go nxt $ Just self { node'value = case prevNode of Nothing -> spotVal Just (ValueNode prevVal prevTs _prevNxt) -> f prevVal prevTs spotVal spotTs } updateValue :: forall a m. MonadIO m => (Maybe (a, Timestamp) -> m (a, Timestamp)) -> ValueSink a -> m (ValueSink a) updateValue f sink = do (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink case tailNode of Nothing -> do (myVal, myTs) <- f Nothing liftIO $ atomically $ do nxt <- newEmptyTMVar void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt return nxt Just (ValueNode spotVal spotTs spotNxt) -> do (myVal, myTs) <- f $ Just (spotVal, spotTs) newNxt <- liftIO newEmptyTMVarIO let newTail = ValueNode myVal myTs newNxt putAsNewTailOrDiscard :: ValueSink a -> STM () putAsNewTailOrDiscard nodeRef = putTMVar nodeRef newTail `orElse` yetOther'sTail where yetOther'sTail = do (ValueNode _other'sVal other'sTs other'sNxt) <- readTMVar nodeRef if other'sTs >= myTs then return () else putAsNewTailOrDiscard other'sNxt liftIO $ atomically $ putAsNewTailOrDiscard spotNxt return spotNxt where justLatest :: (a -> Timestamp -> a -> Timestamp -> a) justLatest _prevVal _prevTs spotVal _spotTs = spotVal -- Each concurrent thread is supposed to have its local 'ValueSink' reference -- "cached" over time, but keep in mind that for any such thread who is slow -- in unfolding the value stream, the historical values will pile up in heap. > On 2021-09-04, at 18:42, YueCompl wrote: > > I'd like to add a new feature that you can fold the historic value stream in deriving the new state value, then it becomes: > > > data ValueNode a = ValueNode > { node'value :: a, > node'timestamp :: Timestamp, > node'next :: ValueSink a > } > > type ValueSink a = TMVar (ValueNode a) > > type Timestamp = Int > > seekTail :: > forall a. > (a -> Timestamp -> a -> Timestamp -> a) -> > ValueSink a -> > STM (ValueSink a, Maybe (ValueNode a)) > seekTail f sink = go sink Nothing > where > go :: > ValueSink a -> > Maybe (ValueNode a) -> > STM (ValueSink a, Maybe (ValueNode a)) > go ref prevNode = > tryReadTMVar ref >>= \case > Nothing -> return (ref, prevNode) > Just self@(ValueNode spotVal spotTs nxt) -> > go nxt $ > Just > self > { node'value = case prevNode of > Nothing -> spotVal > Just (ValueNode prevVal prevTs _prevNxt) -> > f prevVal prevTs spotVal spotTs > } > > updateValue :: > forall a m. > MonadIO m => > (Maybe (a, Timestamp) -> m (a, Timestamp)) -> > ValueSink a -> > m () > updateValue f sink = do > (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink > case tailNode of > Nothing -> do > (myVal, myTs) <- f Nothing > liftIO $ > atomically $ do > nxt <- newEmptyTMVar > void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt > Just (ValueNode spotVal spotTs spotNxt) -> do > (myVal, myTs) <- f $ Just (spotVal, spotTs) > newNxt <- liftIO newEmptyTMVarIO > let newTail = ValueNode myVal myTs newNxt > > putAsNewTailOrDiscard :: ValueSink a -> STM () > putAsNewTailOrDiscard nodeRef = > putTMVar nodeRef newTail `orElse` yetOther'sTail > where > yetOther'sTail = do > (ValueNode _other'sVal other'sTs other'sNxt) <- > readTMVar nodeRef > if other'sTs >= myTs > then return () > else putAsNewTailOrDiscard other'sNxt > > liftIO $ atomically $ putAsNewTailOrDiscard spotNxt > where > justLatest :: (a -> Timestamp -> a -> Timestamp -> a) > justLatest _prevVal _prevTs spotVal _spotTs = spotVal > > -- Each concurrent thread is supposed to have its local 'ValueSink' reference > -- "cached" over time, but keep in mind that for any such thread who is slow > -- in unfolding the value stream, the historical values will pile up in heap. > > > >> On 2021-09-03, at 16:26, YueCompl > wrote: >> >> It's a bit sad that I'm not so mathematically minded to understand you in that abstract level. But I have a more imperative solution in my mind, wrt the question: >> >>> "server, tell me if there is a value of x newer than t." >> >> >> and do further mutate-or-giveup, like this: >> >> >> data ValueNode a = ValueNode >> { node'value :: a, >> node'timestamp :: Timestamp, >> node'next :: ValueSink a >> } >> >> type ValueSink a = TMVar (ValueNode a) >> >> type Timestamp = Int >> >> seekTail :: ValueSink a -> STM (ValueSink a, Maybe (ValueNode a)) >> seekTail sink = go sink Nothing >> where >> go ref ancestor = >> tryReadTMVar ref >>= \case >> Nothing -> return (ref, ancestor) >> Just self@(ValueNode _ _ nxt) -> go nxt $ Just self >> >> updateValue :: >> forall a m. >> MonadIO m => >> (Maybe (a, Timestamp) -> m (a, Timestamp)) -> >> ValueSink a -> >> m () >> updateValue f sink = do >> (tailRef, tailNode) <- liftIO $ atomically $ seekTail sink >> case tailNode of >> Nothing -> do >> (myVal, myTs) <- f Nothing >> liftIO $ >> atomically $ do >> nxt <- newEmptyTMVar >> void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt >> Just (ValueNode seenVal seenTs seenNxt) -> do >> (myVal, myTs) <- f $ Just (seenVal, seenTs) >> newNxt <- liftIO newEmptyTMVarIO >> let newTail = ValueNode myVal myTs newNxt >> >> putAsNewTailOrDiscard :: ValueSink a -> STM () >> putAsNewTailOrDiscard nodeRef = >> putTMVar nodeRef newTail `orElse` yetOther'sTail >> where >> yetOther'sTail = do >> (ValueNode _other'sVal other'sTs other'sNxt) <- >> readTMVar nodeRef >> if other'sTs >= myTs >> then return () >> else putAsNewTailOrDiscard other'sNxt >> >> liftIO $ atomically $ putAsNewTailOrDiscard seenNxt >> >> -- Each concurrent thread is supposed to have its local 'ValueSink' reference >> -- "cached" over time, but keep in mind that for any such thread who is slow >> -- in unfolding the value stream, the historical values will pile up in heap. >> >> >> >>> On 2021-09-03, at 01:42, Olaf Klinke > wrote: >>> >>> On Fri, 2021-09-03 at 00:00 +0800, YueCompl wrote: >>>> Um, I'm not sure I understand your case right, but if the "mutation" instead of the "mutated result" can be (might non-trivially) computed from a possibly outdated state, and the "mutation" can be trivially applied, I think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an almost up-to-date state on demand, at low frequency. >>> >>> To be concrete, my state is a collection of time stamped values, where >>> the monoid operation overwrites old values with new ones. >>> But I need to know the current state (x,t) to determine the "mutation", >>> because I'll be asking questions like "server, tell me if there is a >>> value of x newer than t." >>> Any observer whose initial state is synchronized with the worker thread >>> can in principle re-construct the worker's internal state by observing >>> the stream of emitted "mutations". >>> >>> The most general abstraction would be that of a monoid action on a >>> type, but in my case the monoid (mutations) and the mutated type are >>> identical. >>> >>> act :: m -> a -> a >>> act memtpy = id >>> act (x <> y) = act x . act y -- monoid homomorphism >>> act (x <> x) = act x -- idempotent >>> >>> Olaf >>> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From minorinoki at gmail.com Sat Sep 4 11:41:45 2021 From: minorinoki at gmail.com (arata, mizuki) Date: Sat, 4 Sep 2021 20:41:45 +0900 Subject: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows In-Reply-To: References: <8A7B2D58-37D0-4C29-88BF-7580BFF31064@gmail.com> Message-ID: <74A1C636-FBA7-4E24-BD98-3FBF6193D9DE@gmail.com> FloatFnInverses is marked as ‘expect_broken’ on Windows: https://gitlab.haskell.org/ghc/ghc/-/blob/922c6bc8dd8d089cfe4b90ec2120cb48959ba2b5/testsuite/tests/numeric/should_run/all.T#L44-45 And there’s a relevant issue: https://gitlab.haskell.org/ghc/ghc/-/issues/15670 Mizuki > 2021/09/04 18:46、David James のメール: > > Hi - thank you for this. I was unaware of the “constant folding” in GCC (and I’m surprised it works for functions like asinh), but I can see that it explains the difference in behaviour. > > So I think this is a (possibly minor) bug that Haskell inherits from mingw-w64. I guess I should raise a GHC issue – though I’m not sure whether it would be best to try to fix within Haskell or within mingw-w64. > > Also, I think the FloatFnInverses.hs test doesn’t should be showing as a fail somewhere in the CI testing. (It doesn’t give the expected output when I run it on Windows). Do you know whether/where I can see that? (I don’t know what CI happens or how to view its output). > > Thanks again, > David. > > From: arata, mizuki > Sent: 03 September 2021 13:43 > To: David James > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows > > Hi David, > > If I understand correctly, GHC uses mingw-w64’s libc implementation on Windows. > Since mingw-w64’s math functions are not of very good quality, it is likely that asinh returns NaN for a very large input. > > As to why `asinh(1.7976931348623157e308)` in CAsinh.c produces (seemingly-correct) 710.4758, it is probably because the C compiler (GCC) uses a different implementation of asinh when doing constant folding. > As a note, you may get a different (compile-time computed) result for `asinh(x)` if you set a more aggressive optimization flag. > > Mizuki > -------------- next part -------------- An HTML attachment was scrubbed... URL: From olf at aatal-apotheke.de Mon Sep 6 09:04:52 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Mon, 06 Sep 2021 11:04:52 +0200 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: <0D4B865D-3C17-4593-82A2-F6E2F1C6DDDA@icloud.com> References: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> <5111D395-F2CE-482F-AB5A-16F2A6E1F683@icloud.com> <83DE2F7E-2D61-429E-A90A-CC5AA5EB1814@icloud.com> <0D4B865D-3C17-4593-82A2-F6E2F1C6DDDA@icloud.com> Message-ID: Dear Compl, thanks for putting so much thought into this. Regarding your suggestion, I'm afraid I misled you somehow or I don't understand the purpose of your code. I don't need the entire history of each value, only the most recent one. Remark: The ValueNode looks like a ListT (like in list-t package) over the STM monad. We're developing a gateway between two data protocols. We have a Python implementation, but it is not parallel enough and message parsing is too slow. Therefore we hired MLabs to implement the source protocol in Haskell [1]. The gateway does the following. 1. Parent thread reads a config and forks several concurrent child threads, each talking to a different server. The state of the children is read through TVars. 2. The child thread polls data from its assigned server, decodes the message and executes pre-defined callbacks [2], which are functions type Callback m = Value -> UTCTime -> m (). 3. Each data packet can contain several data items and I want these callbacks to be executed in parallel, too. This is because we expect the network IO to be the slowest part in the entire process. I use the parallel-io package for that. import Control.Monad.Reader import Control.Monad.IO.Unlift (MonadUnliftIO(..)) import Control.Concurrent.ParallelIO.Local (Pool,parallel_) type CallbackStrategy m n = forall f. Foldable f => f (m ()) -> n () sequentialStrategy :: Applicative m => CallbackStrategy m m sequentialStrategy = Data.Foldable.sequenceA_ -- ^ just sequence the callbacks concurrentStrategy :: MonadUnliftIO m => CallbackStrategy m (ReaderT Pool m) concurrentStrategy = execConcurrently . Data.Foldable.toList where execConcurrently actionlist = ReaderT (\pool -> withRunInIO (\asIO -> parallel_ pool (map asIO actionlist))) -- ^ execute the callbacks concurrently on a pool of worker threads I'd be quite happy with m = StateT s IO where s holds the most recent time stamp and value for each data address. The simplest way to broadcast state in this monad would be: broadcast :: Monoid s => TVar s -> StateT s IO () -> StateT s IO () broadcast var (StateT f) = StateT (\s -> do s' <- f s atomically (modifyTVar ref (\s -> s <> s'))) That is, we run the StateT action and send the changes to the TVar afterwards. But there are two more problems with this: (1) The concurrent callbacks all want to atomically modify the same TVar. This is a concurrency bottleneck and effectively implements Isaac Elliott's Locks. Hence it seems that giving each data address its own value TVar could allow more parallelism. (2) StateT is inherently sequential, which defeats concurrentStrategy. In fact the unliftio-core package states: > Note that, in order to meet the laws given below, the intuition is that a monad must have no monadic state, but may have monadic context. This essentially limits MonadUnliftIO to ReaderT and IdentityT transformers on top of IO. Intuitively, there is no way to safely and concurrently modify the same state. Nice example of how the type system guides you towards doing the right thing. Therefore I will go back to what Chris Smith and Bryan Richter suggested, and use ReaderT (TVar s) individually for each value. And your suggestion of TMVars is also good in finer granularity, I think. In the following, m can have a MonadUnliftIO instance. unStateT :: MonadIO m => TMVar s -> Callback (StateT s m) -> Callback m unStateT var cb = \value time -> do before <- (liftIO.atomically) (takeTMVar var) -- TMVar is now empty, no other thread can access it after <- execStateT (cb value time) before (liftIO.atomically) (putTMVar var after) -- TMVar now full again Thanks everyone for helping! Olaf [1] https://github.com/mlabs-haskell/opc-xml-da-client [2] I suppose in FP-land we'd name these continuations, not callbacks. Not sure whether the continuation monad abstraction buys me any advantage here, though. On Sat, 2021-09-04 at 18:50 +0800, YueCompl wrote: > Oh, a bugfix: the new tail reference should be returned after update, so a thread local stream reference can technically be cached. > > And I realize this is more than you originally need, never mind if it's not so useful to you. > > > data ValueNode a = ValueNode > { node'value :: a, > node'timestamp :: Timestamp, > node'next :: ValueSink a > } > > type ValueSink a = TMVar (ValueNode a) > > type Timestamp = Int > > seekTail :: > forall a. > (a -> Timestamp -> a -> Timestamp -> a) -> > ValueSink a -> > STM (ValueSink a, Maybe (ValueNode a)) > seekTail f sink = go sink Nothing > where > go :: > ValueSink a -> > Maybe (ValueNode a) -> > STM (ValueSink a, Maybe (ValueNode a)) > go ref prevNode = > tryReadTMVar ref >>= \case > Nothing -> return (ref, prevNode) > Just self@(ValueNode spotVal spotTs nxt) -> > go nxt $ > Just > self > { node'value = case prevNode of > Nothing -> spotVal > Just (ValueNode prevVal prevTs _prevNxt) -> > f prevVal prevTs spotVal spotTs > } > > updateValue :: > forall a m. > MonadIO m => > (Maybe (a, Timestamp) -> m (a, Timestamp)) -> > ValueSink a -> > m (ValueSink a) > updateValue f sink = do > (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink > case tailNode of > Nothing -> do > (myVal, myTs) <- f Nothing > liftIO $ > atomically $ do > nxt <- newEmptyTMVar > void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt > return nxt > Just (ValueNode spotVal spotTs spotNxt) -> do > (myVal, myTs) <- f $ Just (spotVal, spotTs) > newNxt <- liftIO newEmptyTMVarIO > let newTail = ValueNode myVal myTs newNxt > > putAsNewTailOrDiscard :: ValueSink a -> STM () > putAsNewTailOrDiscard nodeRef = > putTMVar nodeRef newTail `orElse` yetOther'sTail > where > yetOther'sTail = do > (ValueNode _other'sVal other'sTs other'sNxt) <- > readTMVar nodeRef > if other'sTs >= myTs > then return () > else putAsNewTailOrDiscard other'sNxt > > liftIO $ atomically $ putAsNewTailOrDiscard spotNxt > return spotNxt > where > justLatest :: (a -> Timestamp -> a -> Timestamp -> a) > justLatest _prevVal _prevTs spotVal _spotTs = spotVal > > -- Each concurrent thread is supposed to have its local 'ValueSink' reference > -- "cached" over time, but keep in mind that for any such thread who is slow > -- in unfolding the value stream, the historical values will pile up in heap. > > > > On 2021-09-04, at 18:42, YueCompl wrote: > > > > I'd like to add a new feature that you can fold the historic value stream in deriving the new state value, then it becomes: > > > > > > data ValueNode a = ValueNode > > { node'value :: a, > > node'timestamp :: Timestamp, > > node'next :: ValueSink a > > } > > > > type ValueSink a = TMVar (ValueNode a) > > > > type Timestamp = Int > > > > seekTail :: > > forall a. > > (a -> Timestamp -> a -> Timestamp -> a) -> > > ValueSink a -> > > STM (ValueSink a, Maybe (ValueNode a)) > > seekTail f sink = go sink Nothing > > where > > go :: > > ValueSink a -> > > Maybe (ValueNode a) -> > > STM (ValueSink a, Maybe (ValueNode a)) > > go ref prevNode = > > tryReadTMVar ref >>= \case > > Nothing -> return (ref, prevNode) > > Just self@(ValueNode spotVal spotTs nxt) -> > > go nxt $ > > Just > > self > > { node'value = case prevNode of > > Nothing -> spotVal > > Just (ValueNode prevVal prevTs _prevNxt) -> > > f prevVal prevTs spotVal spotTs > > } > > > > updateValue :: > > forall a m. > > MonadIO m => > > (Maybe (a, Timestamp) -> m (a, Timestamp)) -> > > ValueSink a -> > > m () > > updateValue f sink = do > > (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink > > case tailNode of > > Nothing -> do > > (myVal, myTs) <- f Nothing > > liftIO $ > > atomically $ do > > nxt <- newEmptyTMVar > > void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt > > Just (ValueNode spotVal spotTs spotNxt) -> do > > (myVal, myTs) <- f $ Just (spotVal, spotTs) > > newNxt <- liftIO newEmptyTMVarIO > > let newTail = ValueNode myVal myTs newNxt > > > > putAsNewTailOrDiscard :: ValueSink a -> STM () > > putAsNewTailOrDiscard nodeRef = > > putTMVar nodeRef newTail `orElse` yetOther'sTail > > where > > yetOther'sTail = do > > (ValueNode _other'sVal other'sTs other'sNxt) <- > > readTMVar nodeRef > > if other'sTs >= myTs > > then return () > > else putAsNewTailOrDiscard other'sNxt > > > > liftIO $ atomically $ putAsNewTailOrDiscard spotNxt > > where > > justLatest :: (a -> Timestamp -> a -> Timestamp -> a) > > justLatest _prevVal _prevTs spotVal _spotTs = spotVal > > > > -- Each concurrent thread is supposed to have its local 'ValueSink' reference > > -- "cached" over time, but keep in mind that for any such thread who is slow > > -- in unfolding the value stream, the historical values will pile up in heap. > > > > > > > > > On 2021-09-03, at 16:26, YueCompl > wrote: > > > > > > It's a bit sad that I'm not so mathematically minded to understand you in that abstract level. But I have a more imperative solution in my mind, wrt the question: > > > > > > > "server, tell me if there is a value of x newer than t." > > > > > > and do further mutate-or-giveup, like this: > > > > > > > > > data ValueNode a = ValueNode > > > { node'value :: a, > > > node'timestamp :: Timestamp, > > > node'next :: ValueSink a > > > } > > > > > > type ValueSink a = TMVar (ValueNode a) > > > > > > type Timestamp = Int > > > > > > seekTail :: ValueSink a -> STM (ValueSink a, Maybe (ValueNode a)) > > > seekTail sink = go sink Nothing > > > where > > > go ref ancestor = > > > tryReadTMVar ref >>= \case > > > Nothing -> return (ref, ancestor) > > > Just self@(ValueNode _ _ nxt) -> go nxt $ Just self > > > > > > updateValue :: > > > forall a m. > > > MonadIO m => > > > (Maybe (a, Timestamp) -> m (a, Timestamp)) -> > > > ValueSink a -> > > > m () > > > updateValue f sink = do > > > (tailRef, tailNode) <- liftIO $ atomically $ seekTail sink > > > case tailNode of > > > Nothing -> do > > > (myVal, myTs) <- f Nothing > > > liftIO $ > > > atomically $ do > > > nxt <- newEmptyTMVar > > > void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt > > > Just (ValueNode seenVal seenTs seenNxt) -> do > > > (myVal, myTs) <- f $ Just (seenVal, seenTs) > > > newNxt <- liftIO newEmptyTMVarIO > > > let newTail = ValueNode myVal myTs newNxt > > > > > > putAsNewTailOrDiscard :: ValueSink a -> STM () > > > putAsNewTailOrDiscard nodeRef = > > > putTMVar nodeRef newTail `orElse` yetOther'sTail > > > where > > > yetOther'sTail = do > > > (ValueNode _other'sVal other'sTs other'sNxt) <- > > > readTMVar nodeRef > > > if other'sTs >= myTs > > > then return () > > > else putAsNewTailOrDiscard other'sNxt > > > > > > liftIO $ atomically $ putAsNewTailOrDiscard seenNxt > > > > > > -- Each concurrent thread is supposed to have its local 'ValueSink' reference > > > -- "cached" over time, but keep in mind that for any such thread who is slow > > > -- in unfolding the value stream, the historical values will pile up in heap. > > > > > > > > > > > > > On 2021-09-03, at 01:42, Olaf Klinke > wrote: > > > > > > > > On Fri, 2021-09-03 at 00:00 +0800, YueCompl wrote: > > > > > Um, I'm not sure I understand your case right, but if the "mutation" instead of the "mutated result" can be (might non-trivially) computed from a possibly outdated state, and the "mutation" can be trivially applied, I think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an almost up-to-date state on demand, at low frequency. > > > > > > > > To be concrete, my state is a collection of time stamped values, where > > > > the monoid operation overwrites old values with new ones. > > > > But I need to know the current state (x,t) to determine the "mutation", > > > > because I'll be asking questions like "server, tell me if there is a > > > > value of x newer than t." > > > > Any observer whose initial state is synchronized with the worker thread > > > > can in principle re-construct the worker's internal state by observing > > > > the stream of emitted "mutations". > > > > > > > > The most general abstraction would be that of a monoid action on a > > > > type, but in my case the monoid (mutations) and the mutated type are > > > > identical. > > > > > > > > act :: m -> a -> a > > > > act memtpy = id > > > > act (x <> y) = act x . act y -- monoid homomorphism > > > > act (x <> x) = act x -- idempotent > > > > > > > > Olaf > > > > From compl.yue at icloud.com Mon Sep 6 10:27:24 2021 From: compl.yue at icloud.com (YueCompl) Date: Mon, 6 Sep 2021 18:27:24 +0800 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: References: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> <5111D395-F2CE-482F-AB5A-16F2A6E1F683@icloud.com> <83DE2F7E-2D61-429E-A90A-CC5AA5EB1814@icloud.com> <0D4B865D-3C17-4593-82A2-F6E2F1C6DDDA@icloud.com> Message-ID: I happen to be pondering with ideas about mutable yet shared data/state, unlike the actor model, a Turing machine has no notation of external change notification, I wonder this limitation propagates to lambda calculus, so there seem be no approved ways in pure functional paradigm, to handle concurrent mutation on shared state, since it's not modeled in the first place. From your updated description, I guess `atomicModifyIORef` (or maybe the strict version `atomicModifyIORef'` more desirable?) might work for you as well, and it's further more performant than 'TVar' based. Btw, just come to my mind about the timestamps, if they are of high precision and come from different server nodes, you would not trust their total ordering, since small drifts are allowed/inevitable even the clocks are actively synchronized. > On 2021-09-06, at 17:04, Olaf Klinke wrote: > > Dear Compl, > > thanks for putting so much thought into this. Regarding your > suggestion, I'm afraid I misled you somehow or I don't understand the > purpose of your code. I don't need the entire history of each value, > only the most recent one. Remark: The ValueNode looks like a ListT > (like in list-t package) over the STM monad. > > We're developing a gateway between two data protocols. We have a Python > implementation, but it is not parallel enough and message parsing is > too slow. Therefore we hired MLabs to implement the source protocol in > Haskell [1]. The gateway does the following. > > 1. Parent thread reads a config and forks several concurrent child > threads, each talking to a different server. The state of the children > is read through TVars. > 2. The child thread polls data from its assigned server, decodes the > message and executes pre-defined callbacks [2], which are functions > type Callback m = Value -> UTCTime -> m (). > 3. Each data packet can contain several data items and I want these > callbacks to be executed in parallel, too. This is because we expect > the network IO to be the slowest part in the entire process. I use the > parallel-io package for that. > > import Control.Monad.Reader > import Control.Monad.IO.Unlift (MonadUnliftIO(..)) > import Control.Concurrent.ParallelIO.Local (Pool,parallel_) > > type CallbackStrategy m n = forall f. Foldable f => > f (m ()) -> n () > sequentialStrategy :: Applicative m => CallbackStrategy m m > sequentialStrategy = Data.Foldable.sequenceA_ > -- ^ just sequence the callbacks > > concurrentStrategy :: MonadUnliftIO m => > CallbackStrategy m (ReaderT Pool m) > concurrentStrategy = execConcurrently . > Data.Foldable.toList where > execConcurrently actionlist = ReaderT (\pool -> > withRunInIO (\asIO -> parallel_ pool (map asIO actionlist))) > -- ^ execute the callbacks concurrently on a pool of worker threads > > I'd be quite happy with m = StateT s IO where s holds the most recent > time stamp and value for each data address. The simplest way to > broadcast state in this monad would be: > > broadcast :: Monoid s => TVar s -> StateT s IO () -> StateT s IO () > broadcast var (StateT f) = StateT (\s -> do > s' <- f s > atomically (modifyTVar ref (\s -> s <> s'))) > > That is, we run the StateT action and send the changes to the TVar > afterwards. But there are two more problems with this: > > (1) The concurrent callbacks all want to atomically modify the same > TVar. This is a concurrency bottleneck and effectively implements Isaac > Elliott's Locks. Hence it seems that giving each data address its own > value TVar could allow more parallelism. > > (2) StateT is inherently sequential, which defeats concurrentStrategy. > In fact the unliftio-core package states: >> Note that, in order to meet the laws given below, the intuition is that a monad must have no monadic state, but may have monadic context. This essentially limits MonadUnliftIO to ReaderT and IdentityT transformers on top of IO. > Intuitively, there is no way to safely and concurrently modify the same > state. Nice example of how the type system guides you towards doing the > right thing. > > Therefore I will go back to what Chris Smith and Bryan Richter > suggested, and use ReaderT (TVar s) individually for each value. And > your suggestion of TMVars is also good in finer granularity, I think. > In the following, m can have a MonadUnliftIO instance. > > unStateT :: MonadIO m => TMVar s -> > Callback (StateT s m) -> Callback m > unStateT var cb = \value time -> do > before <- (liftIO.atomically) (takeTMVar var) > -- TMVar is now empty, no other thread can access it > after <- execStateT (cb value time) before > (liftIO.atomically) (putTMVar var after) > -- TMVar now full again > > Thanks everyone for helping! > Olaf > > > [1] https://github.com/mlabs-haskell/opc-xml-da-client > [2] I suppose in FP-land we'd name these continuations, not callbacks. > Not sure whether the continuation monad abstraction buys me any > advantage here, though. > > On Sat, 2021-09-04 at 18:50 +0800, YueCompl wrote: >> Oh, a bugfix: the new tail reference should be returned after update, so a thread local stream reference can technically be cached. >> >> And I realize this is more than you originally need, never mind if it's not so useful to you. >> >> >> data ValueNode a = ValueNode >> { node'value :: a, >> node'timestamp :: Timestamp, >> node'next :: ValueSink a >> } >> >> type ValueSink a = TMVar (ValueNode a) >> >> type Timestamp = Int >> >> seekTail :: >> forall a. >> (a -> Timestamp -> a -> Timestamp -> a) -> >> ValueSink a -> >> STM (ValueSink a, Maybe (ValueNode a)) >> seekTail f sink = go sink Nothing >> where >> go :: >> ValueSink a -> >> Maybe (ValueNode a) -> >> STM (ValueSink a, Maybe (ValueNode a)) >> go ref prevNode = >> tryReadTMVar ref >>= \case >> Nothing -> return (ref, prevNode) >> Just self@(ValueNode spotVal spotTs nxt) -> >> go nxt $ >> Just >> self >> { node'value = case prevNode of >> Nothing -> spotVal >> Just (ValueNode prevVal prevTs _prevNxt) -> >> f prevVal prevTs spotVal spotTs >> } >> >> updateValue :: >> forall a m. >> MonadIO m => >> (Maybe (a, Timestamp) -> m (a, Timestamp)) -> >> ValueSink a -> >> m (ValueSink a) >> updateValue f sink = do >> (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink >> case tailNode of >> Nothing -> do >> (myVal, myTs) <- f Nothing >> liftIO $ >> atomically $ do >> nxt <- newEmptyTMVar >> void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt >> return nxt >> Just (ValueNode spotVal spotTs spotNxt) -> do >> (myVal, myTs) <- f $ Just (spotVal, spotTs) >> newNxt <- liftIO newEmptyTMVarIO >> let newTail = ValueNode myVal myTs newNxt >> >> putAsNewTailOrDiscard :: ValueSink a -> STM () >> putAsNewTailOrDiscard nodeRef = >> putTMVar nodeRef newTail `orElse` yetOther'sTail >> where >> yetOther'sTail = do >> (ValueNode _other'sVal other'sTs other'sNxt) <- >> readTMVar nodeRef >> if other'sTs >= myTs >> then return () >> else putAsNewTailOrDiscard other'sNxt >> >> liftIO $ atomically $ putAsNewTailOrDiscard spotNxt >> return spotNxt >> where >> justLatest :: (a -> Timestamp -> a -> Timestamp -> a) >> justLatest _prevVal _prevTs spotVal _spotTs = spotVal >> >> -- Each concurrent thread is supposed to have its local 'ValueSink' reference >> -- "cached" over time, but keep in mind that for any such thread who is slow >> -- in unfolding the value stream, the historical values will pile up in heap. >> >> >>> On 2021-09-04, at 18:42, YueCompl wrote: >>> >>> I'd like to add a new feature that you can fold the historic value stream in deriving the new state value, then it becomes: >>> >>> >>> data ValueNode a = ValueNode >>> { node'value :: a, >>> node'timestamp :: Timestamp, >>> node'next :: ValueSink a >>> } >>> >>> type ValueSink a = TMVar (ValueNode a) >>> >>> type Timestamp = Int >>> >>> seekTail :: >>> forall a. >>> (a -> Timestamp -> a -> Timestamp -> a) -> >>> ValueSink a -> >>> STM (ValueSink a, Maybe (ValueNode a)) >>> seekTail f sink = go sink Nothing >>> where >>> go :: >>> ValueSink a -> >>> Maybe (ValueNode a) -> >>> STM (ValueSink a, Maybe (ValueNode a)) >>> go ref prevNode = >>> tryReadTMVar ref >>= \case >>> Nothing -> return (ref, prevNode) >>> Just self@(ValueNode spotVal spotTs nxt) -> >>> go nxt $ >>> Just >>> self >>> { node'value = case prevNode of >>> Nothing -> spotVal >>> Just (ValueNode prevVal prevTs _prevNxt) -> >>> f prevVal prevTs spotVal spotTs >>> } >>> >>> updateValue :: >>> forall a m. >>> MonadIO m => >>> (Maybe (a, Timestamp) -> m (a, Timestamp)) -> >>> ValueSink a -> >>> m () >>> updateValue f sink = do >>> (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink >>> case tailNode of >>> Nothing -> do >>> (myVal, myTs) <- f Nothing >>> liftIO $ >>> atomically $ do >>> nxt <- newEmptyTMVar >>> void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt >>> Just (ValueNode spotVal spotTs spotNxt) -> do >>> (myVal, myTs) <- f $ Just (spotVal, spotTs) >>> newNxt <- liftIO newEmptyTMVarIO >>> let newTail = ValueNode myVal myTs newNxt >>> >>> putAsNewTailOrDiscard :: ValueSink a -> STM () >>> putAsNewTailOrDiscard nodeRef = >>> putTMVar nodeRef newTail `orElse` yetOther'sTail >>> where >>> yetOther'sTail = do >>> (ValueNode _other'sVal other'sTs other'sNxt) <- >>> readTMVar nodeRef >>> if other'sTs >= myTs >>> then return () >>> else putAsNewTailOrDiscard other'sNxt >>> >>> liftIO $ atomically $ putAsNewTailOrDiscard spotNxt >>> where >>> justLatest :: (a -> Timestamp -> a -> Timestamp -> a) >>> justLatest _prevVal _prevTs spotVal _spotTs = spotVal >>> >>> -- Each concurrent thread is supposed to have its local 'ValueSink' reference >>> -- "cached" over time, but keep in mind that for any such thread who is slow >>> -- in unfolding the value stream, the historical values will pile up in heap. >>> >>> >>> >>>> On 2021-09-03, at 16:26, YueCompl >> wrote: >>>> >>>> It's a bit sad that I'm not so mathematically minded to understand you in that abstract level. But I have a more imperative solution in my mind, wrt the question: >>>> >>>>> "server, tell me if there is a value of x newer than t." >>>> >>>> and do further mutate-or-giveup, like this: >>>> >>>> >>>> data ValueNode a = ValueNode >>>> { node'value :: a, >>>> node'timestamp :: Timestamp, >>>> node'next :: ValueSink a >>>> } >>>> >>>> type ValueSink a = TMVar (ValueNode a) >>>> >>>> type Timestamp = Int >>>> >>>> seekTail :: ValueSink a -> STM (ValueSink a, Maybe (ValueNode a)) >>>> seekTail sink = go sink Nothing >>>> where >>>> go ref ancestor = >>>> tryReadTMVar ref >>= \case >>>> Nothing -> return (ref, ancestor) >>>> Just self@(ValueNode _ _ nxt) -> go nxt $ Just self >>>> >>>> updateValue :: >>>> forall a m. >>>> MonadIO m => >>>> (Maybe (a, Timestamp) -> m (a, Timestamp)) -> >>>> ValueSink a -> >>>> m () >>>> updateValue f sink = do >>>> (tailRef, tailNode) <- liftIO $ atomically $ seekTail sink >>>> case tailNode of >>>> Nothing -> do >>>> (myVal, myTs) <- f Nothing >>>> liftIO $ >>>> atomically $ do >>>> nxt <- newEmptyTMVar >>>> void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt >>>> Just (ValueNode seenVal seenTs seenNxt) -> do >>>> (myVal, myTs) <- f $ Just (seenVal, seenTs) >>>> newNxt <- liftIO newEmptyTMVarIO >>>> let newTail = ValueNode myVal myTs newNxt >>>> >>>> putAsNewTailOrDiscard :: ValueSink a -> STM () >>>> putAsNewTailOrDiscard nodeRef = >>>> putTMVar nodeRef newTail `orElse` yetOther'sTail >>>> where >>>> yetOther'sTail = do >>>> (ValueNode _other'sVal other'sTs other'sNxt) <- >>>> readTMVar nodeRef >>>> if other'sTs >= myTs >>>> then return () >>>> else putAsNewTailOrDiscard other'sNxt >>>> >>>> liftIO $ atomically $ putAsNewTailOrDiscard seenNxt >>>> >>>> -- Each concurrent thread is supposed to have its local 'ValueSink' reference >>>> -- "cached" over time, but keep in mind that for any such thread who is slow >>>> -- in unfolding the value stream, the historical values will pile up in heap. >>>> >>>> >>>> >>>>> On 2021-09-03, at 01:42, Olaf Klinke >> wrote: >>>>> >>>>> On Fri, 2021-09-03 at 00:00 +0800, YueCompl wrote: >>>>>> Um, I'm not sure I understand your case right, but if the "mutation" instead of the "mutated result" can be (might non-trivially) computed from a possibly outdated state, and the "mutation" can be trivially applied, I think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an almost up-to-date state on demand, at low frequency. >>>>> >>>>> To be concrete, my state is a collection of time stamped values, where >>>>> the monoid operation overwrites old values with new ones. >>>>> But I need to know the current state (x,t) to determine the "mutation", >>>>> because I'll be asking questions like "server, tell me if there is a >>>>> value of x newer than t." >>>>> Any observer whose initial state is synchronized with the worker thread >>>>> can in principle re-construct the worker's internal state by observing >>>>> the stream of emitted "mutations". >>>>> >>>>> The most general abstraction would be that of a monoid action on a >>>>> type, but in my case the monoid (mutations) and the mutated type are >>>>> identical. >>>>> >>>>> act :: m -> a -> a >>>>> act memtpy = id >>>>> act (x <> y) = act x . act y -- monoid homomorphism >>>>> act (x <> x) = act x -- idempotent >>>>> >>>>> Olaf -------------- next part -------------- An HTML attachment was scrubbed... URL: From olf at aatal-apotheke.de Mon Sep 6 16:10:27 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Mon, 06 Sep 2021 18:10:27 +0200 Subject: [Haskell-cafe] broadcasting stateful computations In-Reply-To: References: <154494FB-2A8E-4E4D-9353-9A0D93BB9162@icloud.com> <41b64a854eb774fe8ba8ec7c6f5366a4c8ad65c9.camel@aatal-apotheke.de> <5111D395-F2CE-482F-AB5A-16F2A6E1F683@icloud.com> <83DE2F7E-2D61-429E-A90A-CC5AA5EB1814@icloud.com> <0D4B865D-3C17-4593-82A2-F6E2F1C6DDDA@icloud.com> Message-ID: On Mon, 2021-09-06 at 18:27 +0800, YueCompl wrote: > I happen to be pondering with ideas about mutable yet shared data/state, unlike the actor model, a Turing machine has no notation of external change notification, I wonder this limitation propagates to lambda calculus, so there seem be no approved ways in pure functional paradigm, to handle concurrent mutation on shared state, since it's not modeled in the first place. > Concurrency is hard. All we can do is provide shorthand notation for commonly used idioms. Consider another widely used shared state modifier: Version control systems like SVN or git. For true concurrency you need a way of conflict resolution, which your state may or may not support. Databases (and STM) have rollbacks in case of conflicts as a simple kind of conflict resolution. My conflict resolution now comprises fragmentation of the state into small data address components, akin to row locks in a database. > From your updated description, I guess `atomicModifyIORef` (or maybe the strict version `atomicModifyIORef'` more desirable?) might work for you as well, and it's further more performant than 'TVar' based. > I am a newbie to STM. I was hoping that STM provides some of the aforementioned commonly used idioms and is therefore safer to use than naked IORef. I do not want to worry about race conditions and deadlocks, the library should to that for me. > Btw, just come to my mind about the timestamps, if they are of high precision and come from different server nodes, you would not trust their total ordering, since small drifts are allowed/inevitable even the clocks are actively synchronized. Indeed I do not trust the timestamps and I never compare timestamps obatained from different servers. However, I do trust that if I obtain a timestamp t0 from server A and later ask server A for a timestamp t1, then t1 >= t0 holds. Olaf > > > On 2021-09-06, at 17:04, Olaf Klinke wrote: > > > > Dear Compl, > > > > thanks for putting so much thought into this. Regarding your > > suggestion, I'm afraid I misled you somehow or I don't understand the > > purpose of your code. I don't need the entire history of each value, > > only the most recent one. Remark: The ValueNode looks like a ListT > > (like in list-t package) over the STM monad. > > > > We're developing a gateway between two data protocols. We have a Python > > implementation, but it is not parallel enough and message parsing is > > too slow. Therefore we hired MLabs to implement the source protocol in > > Haskell [1]. The gateway does the following. > > > > 1. Parent thread reads a config and forks several concurrent child > > threads, each talking to a different server. The state of the children > > is read through TVars. > > 2. The child thread polls data from its assigned server, decodes the > > message and executes pre-defined callbacks [2], which are functions > > type Callback m = Value -> UTCTime -> m (). > > 3. Each data packet can contain several data items and I want these > > callbacks to be executed in parallel, too. This is because we expect > > the network IO to be the slowest part in the entire process. I use the > > parallel-io package for that. > > > > import Control.Monad.Reader > > import Control.Monad.IO.Unlift (MonadUnliftIO(..)) > > import Control.Concurrent.ParallelIO.Local (Pool,parallel_) > > > > type CallbackStrategy m n = forall f. Foldable f => > > f (m ()) -> n () > > sequentialStrategy :: Applicative m => CallbackStrategy m m > > sequentialStrategy = Data.Foldable.sequenceA_ > > -- ^ just sequence the callbacks > > > > concurrentStrategy :: MonadUnliftIO m => > > CallbackStrategy m (ReaderT Pool m) > > concurrentStrategy = execConcurrently . > > Data.Foldable.toList where > > execConcurrently actionlist = ReaderT (\pool -> > > withRunInIO (\asIO -> parallel_ pool (map asIO actionlist))) > > -- ^ execute the callbacks concurrently on a pool of worker threads > > > > I'd be quite happy with m = StateT s IO where s holds the most recent > > time stamp and value for each data address. The simplest way to > > broadcast state in this monad would be: > > > > broadcast :: Monoid s => TVar s -> StateT s IO () -> StateT s IO () > > broadcast var (StateT f) = StateT (\s -> do > > s' <- f s > > atomically (modifyTVar ref (\s -> s <> s'))) > > > > That is, we run the StateT action and send the changes to the TVar > > afterwards. But there are two more problems with this: > > > > (1) The concurrent callbacks all want to atomically modify the same > > TVar. This is a concurrency bottleneck and effectively implements Isaac > > Elliott's Locks. Hence it seems that giving each data address its own > > value TVar could allow more parallelism. > > > > (2) StateT is inherently sequential, which defeats concurrentStrategy. > > In fact the unliftio-core package states: > > > Note that, in order to meet the laws given below, the intuition is that a monad must have no monadic state, but may have monadic context. This essentially limits MonadUnliftIO to ReaderT and IdentityT transformers on top of IO. > > Intuitively, there is no way to safely and concurrently modify the same > > state. Nice example of how the type system guides you towards doing the > > right thing. > > > > Therefore I will go back to what Chris Smith and Bryan Richter > > suggested, and use ReaderT (TVar s) individually for each value. And > > your suggestion of TMVars is also good in finer granularity, I think. > > In the following, m can have a MonadUnliftIO instance. > > > > unStateT :: MonadIO m => TMVar s -> > > Callback (StateT s m) -> Callback m > > unStateT var cb = \value time -> do > > before <- (liftIO.atomically) (takeTMVar var) > > -- TMVar is now empty, no other thread can access it > > after <- execStateT (cb value time) before > > (liftIO.atomically) (putTMVar var after) > > -- TMVar now full again > > > > Thanks everyone for helping! > > Olaf > > > > > > [1] https://github.com/mlabs-haskell/opc-xml-da-client > > [2] I suppose in FP-land we'd name these continuations, not callbacks. > > Not sure whether the continuation monad abstraction buys me any > > advantage here, though. > > > > On Sat, 2021-09-04 at 18:50 +0800, YueCompl wrote: > > > Oh, a bugfix: the new tail reference should be returned after update, so a thread local stream reference can technically be cached. > > > > > > And I realize this is more than you originally need, never mind if it's not so useful to you. > > > > > > > > > data ValueNode a = ValueNode > > > { node'value :: a, > > > node'timestamp :: Timestamp, > > > node'next :: ValueSink a > > > } > > > > > > type ValueSink a = TMVar (ValueNode a) > > > > > > type Timestamp = Int > > > > > > seekTail :: > > > forall a. > > > (a -> Timestamp -> a -> Timestamp -> a) -> > > > ValueSink a -> > > > STM (ValueSink a, Maybe (ValueNode a)) > > > seekTail f sink = go sink Nothing > > > where > > > go :: > > > ValueSink a -> > > > Maybe (ValueNode a) -> > > > STM (ValueSink a, Maybe (ValueNode a)) > > > go ref prevNode = > > > tryReadTMVar ref >>= \case > > > Nothing -> return (ref, prevNode) > > > Just self@(ValueNode spotVal spotTs nxt) -> > > > go nxt $ > > > Just > > > self > > > { node'value = case prevNode of > > > Nothing -> spotVal > > > Just (ValueNode prevVal prevTs _prevNxt) -> > > > f prevVal prevTs spotVal spotTs > > > } > > > > > > updateValue :: > > > forall a m. > > > MonadIO m => > > > (Maybe (a, Timestamp) -> m (a, Timestamp)) -> > > > ValueSink a -> > > > m (ValueSink a) > > > updateValue f sink = do > > > (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink > > > case tailNode of > > > Nothing -> do > > > (myVal, myTs) <- f Nothing > > > liftIO $ > > > atomically $ do > > > nxt <- newEmptyTMVar > > > void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt > > > return nxt > > > Just (ValueNode spotVal spotTs spotNxt) -> do > > > (myVal, myTs) <- f $ Just (spotVal, spotTs) > > > newNxt <- liftIO newEmptyTMVarIO > > > let newTail = ValueNode myVal myTs newNxt > > > > > > putAsNewTailOrDiscard :: ValueSink a -> STM () > > > putAsNewTailOrDiscard nodeRef = > > > putTMVar nodeRef newTail `orElse` yetOther'sTail > > > where > > > yetOther'sTail = do > > > (ValueNode _other'sVal other'sTs other'sNxt) <- > > > readTMVar nodeRef > > > if other'sTs >= myTs > > > then return () > > > else putAsNewTailOrDiscard other'sNxt > > > > > > liftIO $ atomically $ putAsNewTailOrDiscard spotNxt > > > return spotNxt > > > where > > > justLatest :: (a -> Timestamp -> a -> Timestamp -> a) > > > justLatest _prevVal _prevTs spotVal _spotTs = spotVal > > > > > > -- Each concurrent thread is supposed to have its local 'ValueSink' reference > > > -- "cached" over time, but keep in mind that for any such thread who is slow > > > -- in unfolding the value stream, the historical values will pile up in heap. > > > > > > > > > > On 2021-09-04, at 18:42, YueCompl wrote: > > > > > > > > I'd like to add a new feature that you can fold the historic value stream in deriving the new state value, then it becomes: > > > > > > > > > > > > data ValueNode a = ValueNode > > > > { node'value :: a, > > > > node'timestamp :: Timestamp, > > > > node'next :: ValueSink a > > > > } > > > > > > > > type ValueSink a = TMVar (ValueNode a) > > > > > > > > type Timestamp = Int > > > > > > > > seekTail :: > > > > forall a. > > > > (a -> Timestamp -> a -> Timestamp -> a) -> > > > > ValueSink a -> > > > > STM (ValueSink a, Maybe (ValueNode a)) > > > > seekTail f sink = go sink Nothing > > > > where > > > > go :: > > > > ValueSink a -> > > > > Maybe (ValueNode a) -> > > > > STM (ValueSink a, Maybe (ValueNode a)) > > > > go ref prevNode = > > > > tryReadTMVar ref >>= \case > > > > Nothing -> return (ref, prevNode) > > > > Just self@(ValueNode spotVal spotTs nxt) -> > > > > go nxt $ > > > > Just > > > > self > > > > { node'value = case prevNode of > > > > Nothing -> spotVal > > > > Just (ValueNode prevVal prevTs _prevNxt) -> > > > > f prevVal prevTs spotVal spotTs > > > > } > > > > > > > > updateValue :: > > > > forall a m. > > > > MonadIO m => > > > > (Maybe (a, Timestamp) -> m (a, Timestamp)) -> > > > > ValueSink a -> > > > > m () > > > > updateValue f sink = do > > > > (tailRef, tailNode) <- liftIO $ atomically $ seekTail justLatest sink > > > > case tailNode of > > > > Nothing -> do > > > > (myVal, myTs) <- f Nothing > > > > liftIO $ > > > > atomically $ do > > > > nxt <- newEmptyTMVar > > > > void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt > > > > Just (ValueNode spotVal spotTs spotNxt) -> do > > > > (myVal, myTs) <- f $ Just (spotVal, spotTs) > > > > newNxt <- liftIO newEmptyTMVarIO > > > > let newTail = ValueNode myVal myTs newNxt > > > > > > > > putAsNewTailOrDiscard :: ValueSink a -> STM () > > > > putAsNewTailOrDiscard nodeRef = > > > > putTMVar nodeRef newTail `orElse` yetOther'sTail > > > > where > > > > yetOther'sTail = do > > > > (ValueNode _other'sVal other'sTs other'sNxt) <- > > > > readTMVar nodeRef > > > > if other'sTs >= myTs > > > > then return () > > > > else putAsNewTailOrDiscard other'sNxt > > > > > > > > liftIO $ atomically $ putAsNewTailOrDiscard spotNxt > > > > where > > > > justLatest :: (a -> Timestamp -> a -> Timestamp -> a) > > > > justLatest _prevVal _prevTs spotVal _spotTs = spotVal > > > > > > > > -- Each concurrent thread is supposed to have its local 'ValueSink' reference > > > > -- "cached" over time, but keep in mind that for any such thread who is slow > > > > -- in unfolding the value stream, the historical values will pile up in heap. > > > > > > > > > > > > > > > > > On 2021-09-03, at 16:26, YueCompl >> wrote: > > > > > > > > > > It's a bit sad that I'm not so mathematically minded to understand you in that abstract level. But I have a more imperative solution in my mind, wrt the question: > > > > > > > > > > > "server, tell me if there is a value of x newer than t." > > > > > > > > > > and do further mutate-or-giveup, like this: > > > > > > > > > > > > > > > data ValueNode a = ValueNode > > > > > { node'value :: a, > > > > > node'timestamp :: Timestamp, > > > > > node'next :: ValueSink a > > > > > } > > > > > > > > > > type ValueSink a = TMVar (ValueNode a) > > > > > > > > > > type Timestamp = Int > > > > > > > > > > seekTail :: ValueSink a -> STM (ValueSink a, Maybe (ValueNode a)) > > > > > seekTail sink = go sink Nothing > > > > > where > > > > > go ref ancestor = > > > > > tryReadTMVar ref >>= \case > > > > > Nothing -> return (ref, ancestor) > > > > > Just self@(ValueNode _ _ nxt) -> go nxt $ Just self > > > > > > > > > > updateValue :: > > > > > forall a m. > > > > > MonadIO m => > > > > > (Maybe (a, Timestamp) -> m (a, Timestamp)) -> > > > > > ValueSink a -> > > > > > m () > > > > > updateValue f sink = do > > > > > (tailRef, tailNode) <- liftIO $ atomically $ seekTail sink > > > > > case tailNode of > > > > > Nothing -> do > > > > > (myVal, myTs) <- f Nothing > > > > > liftIO $ > > > > > atomically $ do > > > > > nxt <- newEmptyTMVar > > > > > void $ tryPutTMVar tailRef $ ValueNode myVal myTs nxt > > > > > Just (ValueNode seenVal seenTs seenNxt) -> do > > > > > (myVal, myTs) <- f $ Just (seenVal, seenTs) > > > > > newNxt <- liftIO newEmptyTMVarIO > > > > > let newTail = ValueNode myVal myTs newNxt > > > > > > > > > > putAsNewTailOrDiscard :: ValueSink a -> STM () > > > > > putAsNewTailOrDiscard nodeRef = > > > > > putTMVar nodeRef newTail `orElse` yetOther'sTail > > > > > where > > > > > yetOther'sTail = do > > > > > (ValueNode _other'sVal other'sTs other'sNxt) <- > > > > > readTMVar nodeRef > > > > > if other'sTs >= myTs > > > > > then return () > > > > > else putAsNewTailOrDiscard other'sNxt > > > > > > > > > > liftIO $ atomically $ putAsNewTailOrDiscard seenNxt > > > > > > > > > > -- Each concurrent thread is supposed to have its local 'ValueSink' reference > > > > > -- "cached" over time, but keep in mind that for any such thread who is slow > > > > > -- in unfolding the value stream, the historical values will pile up in heap. > > > > > > > > > > > > > > > > > > > > > On 2021-09-03, at 01:42, Olaf Klinke >> wrote: > > > > > > > > > > > > On Fri, 2021-09-03 at 00:00 +0800, YueCompl wrote: > > > > > > > Um, I'm not sure I understand your case right, but if the "mutation" instead of the "mutated result" can be (might non-trivially) computed from a possibly outdated state, and the "mutation" can be trivially applied, I think `modifyTVar'` is the way to go. `readTVar` can be used to obtain an almost up-to-date state on demand, at low frequency. > > > > > > > > > > > > To be concrete, my state is a collection of time stamped values, where > > > > > > the monoid operation overwrites old values with new ones. > > > > > > But I need to know the current state (x,t) to determine the "mutation", > > > > > > because I'll be asking questions like "server, tell me if there is a > > > > > > value of x newer than t." > > > > > > Any observer whose initial state is synchronized with the worker thread > > > > > > can in principle re-construct the worker's internal state by observing > > > > > > the stream of emitted "mutations". > > > > > > > > > > > > The most general abstraction would be that of a monoid action on a > > > > > > type, but in my case the monoid (mutations) and the mutated type are > > > > > > identical. > > > > > > > > > > > > act :: m -> a -> a > > > > > > act memtpy = id > > > > > > act (x <> y) = act x . act y -- monoid homomorphism > > > > > > act (x <> x) = act x -- idempotent > > > > > > > > > > > > Olaf From dj112358 at outlook.com Tue Sep 7 09:01:50 2021 From: dj112358 at outlook.com (David James) Date: Tue, 7 Sep 2021 09:01:50 +0000 Subject: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows In-Reply-To: <74A1C636-FBA7-4E24-BD98-3FBF6193D9DE@gmail.com> References: <8A7B2D58-37D0-4C29-88BF-7580BFF31064@gmail.com> <74A1C636-FBA7-4E24-BD98-3FBF6193D9DE@gmail.com> Message-ID: Thanks again. I��ve added a note to the issue, and raised a bug against mingw. (And also updated another related one.) Is the right solution here to get it fixed in mingw? (And would that then be picked up in some future Haskell release?). I��m also still a bit confused about ming-w64 and GCC (which are all very new to me). Per Wikipedia ��Mingw-w64 includes a port of the GNU Compiler Collection (GCC)��. So why does it have two different implementations of asinh? �C one for use by GCC (that gives good results), and one that is called at runtime (that gives bad results)?. Thanks! David. From: arata, mizuki Sent: 04 September 2021 12:41 To: David James Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows FloatFnInverses is marked as ��expect_broken�� on Windows: https://gitlab.haskell.org/ghc/ghc/-/blob/922c6bc8dd8d089cfe4b90ec2120cb48959ba2b5/testsuite/tests/numeric/should_run/all.T#L44-45 And there��s a relevant issue: https://gitlab.haskell.org/ghc/ghc/-/issues/15670 Mizuki 2021/09/04 18:46��David James >�Υ�`��: Hi - thank you for this. I was unaware of the ��constant folding�� in GCC (and I��m surprised it works for functions like asinh), but I can see that it explains the difference in behaviour. So I think this is a (possibly minor) bug that Haskell inherits from mingw-w64. I guess I should raise a GHC issue �C though I��m not sure whether it would be best to try to fix within Haskell or within mingw-w64. Also, I think the FloatFnInverses.hs test doesn��t should be showing as a fail somewhere in the CI testing. (It doesn��t give the expected output when I run it on Windows). Do you know whether/where I can see that? (I don��t know what CI happens or how to view its output). Thanks again, David. From: arata, mizuki Sent: 03 September 2021 13:43 To: David James Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows Hi David, If I understand correctly, GHC uses mingw-w64��s libc implementation on Windows. Since mingw-w64��s math functions are not of very good quality, it is likely that asinh returns NaN for a very large input. As to why `asinh(1.7976931348623157e308)` in CAsinh.c produces (seemingly-correct) 710.4758, it is probably because the C compiler (GCC) uses a different implementation of asinh when doing constant folding. As a note, you may get a different (compile-time computed) result for `asinh(x)` if you set a more aggressive optimization flag. Mizuki -------------- next part -------------- An HTML attachment was scrubbed... URL: From sperber at deinprogramm.de Tue Sep 7 11:21:44 2021 From: sperber at deinprogramm.de (Michael Sperber) Date: Tue, 07 Sep 2021 13:21:44 +0200 Subject: [Haskell-cafe] Type synonym involing quantified constraint? In-Reply-To: <010f017ba7af4cf3-77ec4946-3867-40c6-ae94-5444852457e8-000000@us-east-2.amazonses.com> (Richard Eisenberg's message of "Thu, 2 Sep 2021 18:04:48 +0000") References: <010f017b9d66ad82-3e7746d7-e103-400f-92fb-f4edcabbd824-000000@us-east-2.amazonses.com> <010f017ba7af4cf3-77ec4946-3867-40c6-ae94-5444852457e8-000000@us-east-2.amazonses.com> Message-ID: On Thu, Sep 02 2021, Richard Eisenberg wrote: > Hm. Interesting. You are trying to work around the fact that okk is not in scope. > > The problem is that GHC does not currently allow you to specify a tuple as the head of a quantified constraint. The thinking is that (forall x. premise => (conclusion1, conclusion2)) can always be refactored into (forall x. premise => conclusion1, forall x. premise => conclusion2). > > In your case, the refactoring is not so simple, but it can be done. Try > >> type OkProd k = forall (okk :: Type -> Constraint) x y. (okk ~ Ok k, okk x, okk y) => okk (Prod k x y) > > Does that work for you? If not, it may be helpful to see a function that uses the OkProd constraint somewhere. Unfortunately, no. I've attached a self-contained example. It works as-is. But when I replace, in the ProductCat (Same k) instance, OkProdInstance (CPP FTW) by OkProdInstance' (the definition you suggested), I get: classes/src/ConCat/Constraints.hs:55:10: error: • Could not deduce: Ok k ~ Ok' (Same k) arising from the superclasses of an instance declaration from the context: (Ok' (Same k) x, Ok' (Same k) y) bound by a quantified context at classes/src/ConCat/Constraints.hs:1:1 • In the instance declaration for ‘ProductCat (Same k)’ | 55 | instance (ProductCat k, OkProdInstance'(k)) => ProductCat (Same k) where | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- Regards, Mike {-# LANGUAGE CPP #-} {-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableSuperClasses #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE ConstraintKinds #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE QuantifiedConstraints #-} {-# LANGUAGE StandaloneKindSignatures #-} module ConCat.Constraints where import Prelude hiding (id,(.)) import GHC.Types (Constraint, Type) class Yes1 a instance Yes1 a class Category k where type Ok k :: Type -> Constraint type Ok k = Yes1 id :: Ok k a => a `k` a infixr 9 . (.) :: forall b c a. (Ok k a, Ok k b, Ok k c) => (b `k` c) -> (a `k` b) -> (a `k` c) class Ok k a => Ok' k a instance Ok k a => Ok' k a type OkProd :: (Type -> Type -> Type) -> Constraint type OkProd k = forall x y. (Ok' k x, Ok' k y) => Ok' k (x, y) #define OkProdInstance(k) okk ~ Ok (k), forall x y. (okk x, okk y) => okk (x, y) type OkProdInstance' :: (Type -> Type -> Type) -> Constraint type OkProdInstance' k = forall (okk :: Type -> Constraint) x y. (okk ~ Ok k, okk x, okk y) => okk (x, y) class (Category k, OkProd k) => ProductCat k where exl :: (Ok k a, Ok k b) => (a, b) `k` a exr :: (Ok k a, Ok k b) => (a, b) `k` b dup :: Ok k a => a `k` (a, a) data Same k a b = Same (a `k` b) instance Category k => Category (Same k) where type Ok (Same k) = Ok k id = Same id Same g . Same f = Same (g . f) instance (ProductCat k, OkProdInstance'(k)) => ProductCat (Same k) where exl = Same exl exr = Same exr dup = Same dup From keith.wygant at gmail.com Wed Sep 8 17:12:30 2021 From: keith.wygant at gmail.com (Keith) Date: Wed, 08 Sep 2021 17:12:30 +0000 Subject: [Haskell-cafe] Bundle patterns with type aliases Message-ID: <0EC9C321-12FF-405B-B9BC-10E8DE9D165E@gmail.com> Is there currently a way to 'bundle' a pattern with a type alias? And if not, could that capability be added to the PatternSynonyms GHC extension? (Is this the right place to ask, or should I be asking a GHC list?) --Keith Sent from my phone with K-9 Mail. -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Wed Sep 8 17:24:24 2021 From: david.feuer at gmail.com (David Feuer) Date: Wed, 8 Sep 2021 13:24:24 -0400 Subject: [Haskell-cafe] Bundle patterns with type aliases In-Reply-To: <0EC9C321-12FF-405B-B9BC-10E8DE9D165E@gmail.com> References: <0EC9C321-12FF-405B-B9BC-10E8DE9D165E@gmail.com> Message-ID: I would like that, along with the ability to bundle patterns with classes. On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > Is there currently a way to 'bundle' a pattern with a type alias? And if > not, could that capability be added to the PatternSynonyms GHC extension? > (Is this the right place to ask, or should I be asking a GHC list?) > > --Keith > Sent from my phone with K-9 Mail. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ruben.astud at gmail.com Thu Sep 9 15:35:47 2021 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Thu, 9 Sep 2021 11:35:47 -0400 Subject: [Haskell-cafe] Using a non fully saturated type family Message-ID: Hello Cafe. I am trying to encode a version of sigma types using GADTs for the tag and a type family as the function between the GADT and the universe of types. My code looks like this (notice the use of StandaloneKindSignatures). --- | dependent.hs {-# language RankNTypes, PolyKinds, TypeFamilies, GADTs #-} {-# language StandaloneKindSignatures, DataKinds #-} module Main where import Data.Kind (Type) import Data.Functor.Identity main :: IO () main = return () type Tag :: Bool -> Type data Tag b where STrue :: Tag True SFalse :: Tag False type ApplyTag :: Bool -> Type type family ApplyTag t where ApplyTag 'True = Int ApplyTag 'False = Char type Sigma :: forall k. (k -> Type) -> (k -> Type) -> Type data Sigma t f where (:&:) :: forall t f a. t a -> f a -> Sigma t f ex :: Sigma Tag ApplyTag ex = STrue :&: 27 The error I get is dependent.hs:24:7: error: • The type family ‘ApplyTag’ should have 1 argument, but has been given none • In the type signature: ex :: Sigma Tag ApplyTag | 24 | ex :: Sigma Tag ApplyTag | ^^^^^^^^^^^^^^^^^^ which is true! How can I recover the intuition of type families being functions at the type level? -- Rubén. (pgp: 4EE9 28F7 932E F4AD) From oleg.grenrus at iki.fi Thu Sep 9 15:55:49 2021 From: oleg.grenrus at iki.fi (Oleg Grenrus) Date: Thu, 9 Sep 2021 18:55:49 +0300 Subject: [Haskell-cafe] Using a non fully saturated type family In-Reply-To: References: Message-ID: <2af89e7b-4296-2f69-6d91-6aaaf5c6aedd@iki.fi> You cannot without a hacks until https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0242-unsaturated-type-families.rst is implemented. One hack is to use defunctionalisation, as in singletons library. Check  their definition for Sigma https://hackage.haskell.org/package/singletons-3.0/docs/Data-Singletons-Sigma.html where (@@) is a synonym for Apply type family, and your Tag is essentially Sing for Bool. - Oleg On 9.9.2021 18.35, Ruben Astudillo wrote: > Hello Cafe. > > I am trying to encode a version of sigma types using GADTs for the tag and a > type family as the function between the GADT and the universe of types. My > code looks like this (notice the use of StandaloneKindSignatures). > > --- | dependent.hs > {-# language RankNTypes, PolyKinds, TypeFamilies, GADTs #-} > {-# language StandaloneKindSignatures, DataKinds #-} > module Main where > > import Data.Kind (Type) > import Data.Functor.Identity > > main :: IO () > main = return () > > type Tag :: Bool -> Type > data Tag b where > STrue :: Tag True > SFalse :: Tag False > > type ApplyTag :: Bool -> Type > type family ApplyTag t where > ApplyTag 'True = Int > ApplyTag 'False = Char > > type Sigma :: forall k. (k -> Type) -> (k -> Type) -> Type > data Sigma t f where > (:&:) :: forall t f a. t a -> f a -> Sigma t f > > ex :: Sigma Tag ApplyTag > ex = STrue :&: 27 > > The error I get is > > dependent.hs:24:7: error: > • The type family ‘ApplyTag’ should have 1 argument, but has been > given none > • In the type signature: ex :: Sigma Tag ApplyTag > | > 24 | ex :: Sigma Tag ApplyTag > | ^^^^^^^^^^^^^^^^^^ > > which is true! How can I recover the intuition of type families being > functions at the type level? > From lysxia at gmail.com Thu Sep 9 16:00:17 2021 From: lysxia at gmail.com (Li-yao Xia) Date: Thu, 9 Sep 2021 12:00:17 -0400 Subject: [Haskell-cafe] Using a non fully saturated type family In-Reply-To: <2af89e7b-4296-2f69-6d91-6aaaf5c6aedd@iki.fi> References: <2af89e7b-4296-2f69-6d91-6aaaf5c6aedd@iki.fi> Message-ID: <33062f60-06e9-a861-4b14-8e9caebc4e98@gmail.com> Hi Ruben, Oleg mentioned defunctionalization as one solution. Another is to wrap the type family in a newtype. newtype ApplyTagT t = ApplyTagT (ApplyTag t) Sigma Tag ApplyTagT is now a well-formed type, though there must be an explicit ApplyTagT constructor for constructing dependent pairs. Li-yao On 9/9/2021 11:55 AM, Oleg Grenrus wrote: > You cannot without a hacks until > https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0242-unsaturated-type-families.rst > is implemented. > > One hack is to use defunctionalisation, as in singletons library. Check > their definition for Sigma > https://hackage.haskell.org/package/singletons-3.0/docs/Data-Singletons-Sigma.html > where (@@) is a synonym for Apply type family, and your Tag is > essentially Sing for Bool. > > - Oleg > > On 9.9.2021 18.35, Ruben Astudillo wrote: >> Hello Cafe. >> >> I am trying to encode a version of sigma types using GADTs for the tag and a >> type family as the function between the GADT and the universe of types. My >> code looks like this (notice the use of StandaloneKindSignatures). >> >> --- | dependent.hs >> {-# language RankNTypes, PolyKinds, TypeFamilies, GADTs #-} >> {-# language StandaloneKindSignatures, DataKinds #-} >> module Main where >> >> import Data.Kind (Type) >> import Data.Functor.Identity >> >> main :: IO () >> main = return () >> >> type Tag :: Bool -> Type >> data Tag b where >> STrue :: Tag True >> SFalse :: Tag False >> >> type ApplyTag :: Bool -> Type >> type family ApplyTag t where >> ApplyTag 'True = Int >> ApplyTag 'False = Char >> >> type Sigma :: forall k. (k -> Type) -> (k -> Type) -> Type >> data Sigma t f where >> (:&:) :: forall t f a. t a -> f a -> Sigma t f >> >> ex :: Sigma Tag ApplyTag >> ex = STrue :&: 27 >> >> The error I get is >> >> dependent.hs:24:7: error: >> • The type family ‘ApplyTag’ should have 1 argument, but has been >> given none >> • In the type signature: ex :: Sigma Tag ApplyTag >> | >> 24 | ex :: Sigma Tag ApplyTag >> | ^^^^^^^^^^^^^^^^^^ >> >> which is true! How can I recover the intuition of type families being >> functions at the type level? >> > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > From ruben.astud at gmail.com Thu Sep 9 16:22:12 2021 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Thu, 9 Sep 2021 12:22:12 -0400 Subject: [Haskell-cafe] Using a non fully saturated type family In-Reply-To: <33062f60-06e9-a861-4b14-8e9caebc4e98@gmail.com> References: <2af89e7b-4296-2f69-6d91-6aaaf5c6aedd@iki.fi> <33062f60-06e9-a861-4b14-8e9caebc4e98@gmail.com> Message-ID: <5eabe8e1-874d-e1be-866e-2106f8947d4f@gmail.com> On 09-09-21 12:00, Li-yao Xia wrote: > Another is to wrap the type family in a newtype. > > newtype ApplyTagT t = ApplyTagT (ApplyTag t) > > Sigma Tag ApplyTagT is now a well-formed type, though there must be an > explicit ApplyTagT constructor for constructing dependent pairs. This is a great hack! -- Rubén. (pgp: 4EE9 28F7 932E F4AD) From emilypi at cohomolo.gy Fri Sep 10 01:22:09 2021 From: emilypi at cohomolo.gy (Emily Pillmore) Date: Fri, 10 Sep 2021 01:22:09 +0000 Subject: [Haskell-cafe] [ANN] Cabal-3.6.1.0 and cabal-install-3.6.0.0 Message-ID: Hello all, The Cabal team is excited to announce the release of both `Cabal-3.6.1.0`, and `cabal-install-3.6.0.0`! ## Changelog for `Cabal-3.6.1.0` This release of `Cabal` is a point release that allowed us to get some important features out into the ecosystem that just couldn't wait: - Include cmm-sources when linking shared objects - Prefer canonicalized path when guessing tools from GHC path - Fix `cabal test --enable-library-coverage` for modules in the `other-modules` field - set the PATH_SEPARATOR value to `;` when calling `./configure` on Windows (this is necessary for autoconf >=2.7) - Significant speedups to the solver ## Changelog for `cabal-install-3.6.0.0` This is the fourth release of the 3.0 release series for `cabal-install`, introducing features and quality of life improvements including: - Better support for `hsc2hs`, allowing users to pass additional options - Added an `--only-download` flag - extra-packages now works properly - `cabal init` UX improvements - GHC 9.2 support - Fixes to the backpack UX - Removing the spurious warnings for extraneous versions on internal packages - Alerts and spelling suggestions for mispelled comands - Massive improvements to code organization and repository health For a full set of release notes, see https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.6.0.0.md. If you have issues, we'd love to hear about them here: https://github.com/haskell/cabal/issues. ## Plans for 3.8 The 3.6 release marks the first in a series where we work to modernize the Cabal project by means of doing away with the idiosyncratic and historical cruft built up, improving the contribution experience. Over the next 6 months, we'll be working hard to improve the state of the repository, including onboarding more maintainers and welcoming new contributors with clearer contribution requirements. To start, we've identified issues and new features that we aim to tackle for the 3.8 release spanning the following: - Better build info for tool creators - Support for stable package sets like LTS - Dropping build/test support for GHCs outside of the 5 year window - Finishing the multilib work - a byte-for-byte bidirectional parser - etc. You can find the full list of 3.8 project issues here: https://github.com/haskell/cabal/issues?q=is%3Aopen+is%3Aissue+project%3Ahaskell%2Fcabal%2F14. I'd also like to thank the many contributors who offered patches, tickets, and other help in the preparation of this release. We appreciate all of your help! And a special thank you to the Haskell Language Server team for working with us and the Haskell Foundation to help fund work needed to improve the IDE. Happy hacking! Emily -------------- next part -------------- An HTML attachment was scrubbed... URL: From hecate at glitchbra.in Fri Sep 10 07:22:57 2021 From: hecate at glitchbra.in (=?UTF-8?Q?H=c3=a9cate?=) Date: Fri, 10 Sep 2021 09:22:57 +0200 Subject: [Haskell-cafe] [ANN] Cabal-3.6.1.0 and cabal-install-3.6.0.0 In-Reply-To: References: Message-ID: <162bda1e-8fe4-2f7c-3d69-4bc1484e32ea@glitchbra.in> Congratulations for the release!! Le 10/09/2021 à 03:22, Emily Pillmore a écrit : > Hello all, > > The Cabal team is excited to announce the release of both > `Cabal-3.6.1.0`, and `cabal-install-3.6.0.0`! > > ## Changelog for `Cabal-3.6.1.0` > > This release of `Cabal` is a point release that allowed us to get some > important features out into the ecosystem that just couldn't wait: > > > - Include cmm-sources when linking shared objects > - Prefer canonicalized path when guessing tools from GHC path > - Fix `cabal test --enable-library-coverage` for modules in the > `other-modules` field > - set the PATH_SEPARATOR value to `;` when calling `./configure` on > Windows (this is necessary for autoconf >=2.7) > - Significant speedups to the solver > > ## Changelog for `cabal-install-3.6.0.0` > > This is the fourth release of the 3.0 release series for > `cabal-install`, introducing features and quality of life improvements > including: > > - Better support for `hsc2hs`, allowing users to pass additional options > - Added an `--only-download` flag > - extra-packages now works properly > - `cabal init` UX improvements > - GHC 9.2 support > - Fixes to the backpack UX > - Removing the spurious warnings for extraneous versions on internal > packages > - Alerts and spelling suggestions for mispelled comands > - Massive improvements to code organization and repository health > > For a full set of release notes, see > https://github.com/haskell/cabal/blob/master/release-notes/cabal-install-3.6.0.0.md > . > If you have issues, we'd love to hear about them here: > https://github.com/haskell/cabal/issues > . > > ## Plans for 3.8 > > The 3.6 release marks the first in a series where we work to modernize > the Cabal project by means of doing away with the idiosyncratic and > historical cruft built up, improving the contribution experience. > > Over the next 6 months, we'll be working hard to improve the state of > the repository, including onboarding more maintainers and welcoming > new contributors with clearer contribution requirements. To start, > we've identified issues and new features that we aim to tackle for the > 3.8 release spanning the following: > > - Better build info for tool creators > - Support for stable package sets like LTS > - Dropping build/test support for GHCs outside of the 5 year window > - Finishing the multilib work > - a byte-for-byte bidirectional parser > - etc. > > You can find the full list of 3.8 project issues here: > https://github.com/haskell/cabal/issues?q=is%3Aopen+is%3Aissue+project%3Ahaskell%2Fcabal%2F14 > . > > I'd also like to thank the many contributors who offered patches, > tickets, and other help in the preparation of this release. We > appreciate all of your help! And a special thank you to the Haskell > Language Server team for working with us and the Haskell Foundation to > help fund work needed to improve the IDE. > > Happy hacking! > Emily > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- Hécate ✨ 🐦: @TechnoEmpress IRC: Hecate WWW: https://glitchbra.in RUN: BSD -------------- next part -------------- An HTML attachment was scrubbed... URL: From persiantiger at yandex.ru Fri Sep 10 11:00:03 2021 From: persiantiger at yandex.ru (Andrey Prokopenko) Date: Fri, 10 Sep 2021 13:00:03 +0200 Subject: [Haskell-cafe] [ANN] vector-hashtables-0.1.0.1 Message-ID: Hello All, We would like to announce the release of yet another implementation of efficient mutable hashtables in Haskell. - It was created long time ago, GitHub: https://github.com/klapaucius/vector-hashtables . - And it finally got its way to the Hackage: https://hackage.haskell.org/package/vector-hashtables . - Benchmark report (HTML) could be also found via this link: https://an-pro.org/html/vhc.html . Best Regards, Andrey Prokopenko -------------- next part -------------- An HTML attachment was scrubbed... URL: From jaro.reinders at gmail.com Sat Sep 11 09:58:26 2021 From: jaro.reinders at gmail.com (Jaro Reinders) Date: Sat, 11 Sep 2021 11:58:26 +0200 Subject: [Haskell-cafe] Backpack: polymorphic instantation? Message-ID: <3fb19986-f998-61c7-8c56-482b1647e2eb@gmail.com> I'm playing around with backpack, trying to rewrite existing libraries. My end goal is to see if Backpack could improve the primitive library. Right now, the primitive library (in my opinion) relies too heavily on specialization of its type classes, so I think Backpack could help. However, I seem to be running into a limitation. I am wondering if it is a fundamental limitation, if perhaps there is a workaround, or if Backpack could be improved to support this use-case. Instead of primitive, I will take the simpler example: semigroup, which also shows this limitation. Let's convert the Semigroup class to a backpack signature: unit indef where signature Semigroup where import Prelude hiding ((<>)) data T (<>) :: T -> T -> T The problem is how to implement this signature with the type of polymorphic lists. It is easy to implement it for concrete lists like strings: unit string where module Semigroup where import Prelude hiding ((<>)) type T = String (<>) :: T -> T -> T (<>) = (++) It is also possible to implement it in terms of another signature: unit list where signature Elem where data A module Semigroup where import Prelude hiding ((<>)) import Elem type T = [A] (<>) :: T -> T -> T (<>) = (++) This is still problematic, because it is annoying that this new type A needs to be instantiated each time you want to use it. However, even more importantly, if I want to translate the 'PrimMonad' class to a Backpack signature then the 'ST s' instance needs a polymorphic type variable 's', which cannot be made concrete. And do note that I want the monad to be concrete for performance reasons, but the 's' parameter doesn't have to be concrete, because it is a phantom parameter anyway. And for lists making the 'a' parameter concrete also would not improve performance as far as I know. One possible way to fix this is to add a type variable in the 'Semigroup' signature, but then I think it becomes impossible to write the 'String' instance and sometimes you need more than one new type variable such as with the 'ReaderT r (ST s)' instance of 'PrimMonad'. In OCaml you can still kind of work around this problem by creating local instances inside functions. That trick still allows you to write a polymorphic concatenation function using a monoid signature (taken from [1]): let concat (type a) xs = let module MU = MonoidUtils (ListMonoid(struct type t = a end)) in MU.concat xs;; So, I'm wondering if it would be possible to "generalise" over indefinite Backpack types such as 'A' in the 'Elem' signature above or if we can at least implement something which enables the same trick that you can use in OCaml. Thanks, Jaro [1] https://blog.shaynefletcher.org/2017/05/more-type-classes-in-ocaml.html From diaz.carrete at gmail.com Sat Sep 11 13:51:25 2021 From: diaz.carrete at gmail.com (=?UTF-8?B?RGFuaWVsIETDrWF6?=) Date: Sat, 11 Sep 2021 15:51:25 +0200 Subject: [Haskell-cafe] Backpack: polymorphic instantation? In-Reply-To: References: Message-ID: Perhaps this is not what you had in mind, but we could write a signature like {-# LANGUAGE KindSignatures #-} > signature Mystery where > import Data.Kind > import Control.Monad > data MysteryMonad :: Type -> Type > instance Functor MysteryMonad > instance Applicative MysteryMonad > instance Monad MysteryMonad > instance PrimMonad MysteryMonad that reused the existing PrimMonad class. Code could depend on that signature without being tied to a concrete monad (this would make the package that has the code "indefinite"). Once we compiled the indefinite code against an actual implementation, it would be optimized as if we had used concrete types from the beginning. One problem with this solution is that it leaves out ST. If we wanted to make it work with ST, one possible hack would be to define the signature like this data MysteryMonad :: Type -> Type -> Type > instance Functor (MysteryMonad s) > instance Applicative (MysteryMonad s) > instance Monad (MysteryMonad s) > instance PrimMonad (MysteryMonad s) And then use some kind of newtype adapter with a phantom type for non-ST monads: module Mystery where type MysteryMonad = W IO > newtype W m a b = W (m b) deriving newtype (Functor, Applicative, Monad) But perhaps it would complicate things too much. On Sat, Sep 11, 2021 at 2:08 PM wrote: > Send Haskell-Cafe mailing list submissions to > haskell-cafe at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > or, via email, send a message with subject or body 'help' to > haskell-cafe-request at haskell.org > > You can reach the person managing the list at > haskell-cafe-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Haskell-Cafe digest..." > > > Today's Topics: > > 1. Backpack: polymorphic instantation? (Jaro Reinders) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Sat, 11 Sep 2021 11:58:26 +0200 > From: Jaro Reinders > To: Haskell Cafe > Subject: [Haskell-cafe] Backpack: polymorphic instantation? > Message-ID: <3fb19986-f998-61c7-8c56-482b1647e2eb at gmail.com> > Content-Type: text/plain; charset=utf-8; format=flowed > > I'm playing around with backpack, trying to rewrite existing libraries. My > end > goal is to see if Backpack could improve the primitive library. Right now, > the > primitive library (in my opinion) relies too heavily on specialization of > its > type classes, so I think Backpack could help. However, I seem to be > running > into a limitation. I am wondering if it is a fundamental limitation, if > perhaps > there is a workaround, or if Backpack could be improved to support this > use-case. > > Instead of primitive, I will take the simpler example: semigroup, which > also > shows this limitation. Let's convert the Semigroup class to a backpack > signature: > > unit indef where > signature Semigroup where > import Prelude hiding ((<>)) > data T > (<>) :: T -> T -> T > > The problem is how to implement this signature with the type of > polymorphic > lists. It is easy to implement it for concrete lists like strings: > > unit string where > module Semigroup where > import Prelude hiding ((<>)) > type T = String > (<>) :: T -> T -> T > (<>) = (++) > > It is also possible to implement it in terms of another signature: > > unit list where > signature Elem where > data A > > module Semigroup where > import Prelude hiding ((<>)) > import Elem > type T = [A] > (<>) :: T -> T -> T > (<>) = (++) > > This is still problematic, because it is annoying that this new type A > needs to > be instantiated each time you want to use it. However, even more > importantly, > if I want to translate the 'PrimMonad' class to a Backpack signature then > the > 'ST s' instance needs a polymorphic type variable 's', which cannot be > made > concrete. > > And do note that I want the monad to be concrete for performance reasons, > but > the 's' parameter doesn't have to be concrete, because it is a phantom > parameter anyway. And for lists making the 'a' parameter concrete also > would > not improve performance as far as I know. > > One possible way to fix this is to add a type variable in the 'Semigroup' > signature, but then I think it becomes impossible to write the 'String' > instance and sometimes you need more than one new type variable such as > with > the 'ReaderT r (ST s)' instance of 'PrimMonad'. > > In OCaml you can still kind of work around this problem by creating local > instances inside functions. That trick still allows you to write a > polymorphic > concatenation function using a monoid signature (taken from [1]): > > let concat (type a) xs = > let module MU = MonoidUtils (ListMonoid(struct type t = a end)) in > MU.concat xs;; > > So, I'm wondering if it would be possible to "generalise" over indefinite > Backpack types such as 'A' in the 'Elem' signature above or if we can at > least > implement something which enables the same trick that you can use in OCaml. > > Thanks, > > Jaro > > [1] > https://blog.shaynefletcher.org/2017/05/more-type-classes-in-ocaml.html > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > ------------------------------ > > End of Haskell-Cafe Digest, Vol 217, Issue 10 > ********************************************* > -------------- next part -------------- An HTML attachment was scrubbed... URL: From jaro.reinders at gmail.com Sat Sep 11 14:56:58 2021 From: jaro.reinders at gmail.com (Jaro Reinders) Date: Sat, 11 Sep 2021 16:56:58 +0200 Subject: [Haskell-cafe] Backpack: polymorphic instantation? In-Reply-To: References: Message-ID: Thanks, but I really don't think the newtype wrapper will useful in practice, and the IO & ST support is absolutely necessary. I also intend to completely replace the primitive library, so I don't want to reuse the existing PrimMonad class, and I also don't see why that would be necessary or useful. You can do the same without it: {-# LANGUAGE MagicHash, UnboxedTuples #-} signature PrimMonad where import GHC.Prim data PrimMonad a instance Functor PrimMonad instance Applicative PrimMonad instance Monad PrimMonad data PrimState primitive :: (State# PrimState -> (# State# PrimState, a #)) -> PrimMonad a Which can be instantiated by IO, and for ST you could do: {-# LANGUAGE MagicHash, UnboxedTuples, TypeFamilies #-} signature PrimMonad where import GHC.Prim data PrimMonad s a instance Functor (PrimMonad s) instance Applicative (PrimMonad s) instance Monad (PrimMonad s) type family PrimState s primitive :: (State# (PrimState s) -> (# State# (PrimState s), a #)) -> PrimMonad s a But then you need a newtype wrapper to implement it with IO. And with both of these approaches I think it is impossible to instantiate the signature with types like 'ReaderT r (ST s)', which is probably also essential to replacing the current primitive library. You can also use type families for both PrimMonad and PrimState, which allows instantiating it with IO and ST (and maybe even ReaderT), but then you can no longer require a Monad instance in the signature. On 11-09-2021 15:51, Daniel Díaz wrote: > Perhaps this is not what you had in mind, but we could write a signature like > >     {-# LANGUAGE KindSignatures #-} >     signature Mystery where >     import Data.Kind >     import Control.Monad >     data MysteryMonad :: Type -> Type >     instance Functor MysteryMonad >     instance Applicative MysteryMonad >     instance Monad MysteryMonad >     instance PrimMonad MysteryMonad > > > that reused the existing PrimMonad class. Code could depend on that signature > without being tied to a concrete monad (this would make the package that has > the code "indefinite"). Once we compiled the indefinite code against an actual > implementation, it would be optimized as if we had used concrete types from the > beginning. > > One problem with this solution is that it leaves out ST. If we wanted to make > it work with ST, one possible hack would be to define the signature like this > >     data MysteryMonad :: Type -> Type -> Type >     instance Functor (MysteryMonad s) >     instance Applicative (MysteryMonad s) >     instance Monad (MysteryMonad s) >     instance PrimMonad (MysteryMonad s) > > > And then use some kind of newtype adapter with a phantom type for non-ST monads: > > module Mystery where > > type MysteryMonad = W IO > newtype W m a b = W (m b) deriving newtype (Functor, Applicative, Monad) > > > But perhaps it would complicate things too much. > On Sat, Sep 11, 2021 at 2:08 PM > wrote: > > Send Haskell-Cafe mailing list submissions to > haskell-cafe at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > or, via email, send a message with subject or body 'help' to > haskell-cafe-request at haskell.org > > You can reach the person managing the list at > haskell-cafe-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Haskell-Cafe digest..." > > > Today's Topics: > >    1. Backpack: polymorphic instantation? (Jaro Reinders) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Sat, 11 Sep 2021 11:58:26 +0200 > From: Jaro Reinders > > To: Haskell Cafe > > Subject: [Haskell-cafe] Backpack: polymorphic instantation? > Message-ID: <3fb19986-f998-61c7-8c56-482b1647e2eb at gmail.com > > > Content-Type: text/plain; charset=utf-8; format=flowed > > I'm playing around with backpack, trying to rewrite existing libraries. My end > goal is to see if Backpack could improve the primitive library. Right now, the > primitive library (in my opinion) relies too heavily on specialization of its > type classes, so I think Backpack could help. However, I seem to be running > into a limitation. I am wondering if it is a fundamental limitation, if > perhaps > there is a workaround, or if Backpack could be improved to support this > use-case. > > Instead of primitive, I will take the simpler example: semigroup, which also > shows this limitation. Let's convert the Semigroup class to a backpack > signature: > >      unit indef where >        signature Semigroup where >          import Prelude hiding ((<>)) >          data T >          (<>) :: T -> T -> T > > The problem is how to implement this signature with the type of polymorphic > lists. It is easy to implement it for concrete lists like strings: > >      unit string where >       module Semigroup where >        import Prelude hiding ((<>)) >        type T = String >        (<>) :: T -> T -> T >        (<>) = (++) > > It is also possible to implement it in terms of another signature: > >      unit list where >        signature Elem where >          data A > >        module Semigroup where >          import Prelude hiding ((<>)) >          import Elem >          type T = [A] >          (<>) :: T -> T -> T >          (<>) = (++) > > This is still problematic, because it is annoying that this new type A > needs to > be instantiated each time you want to use it. However, even more importantly, > if I want to translate the 'PrimMonad' class to a Backpack signature then the > 'ST s' instance needs a polymorphic type variable 's', which cannot be made > concrete. > > And do note that I want the monad to be concrete for performance reasons, but > the 's' parameter doesn't have to be concrete, because it is a phantom > parameter anyway. And for lists making the 'a' parameter concrete also would > not improve performance as far as I know. > > One possible way to fix this is to add a type variable in the 'Semigroup' > signature, but then I think it becomes impossible to write the 'String' > instance and sometimes you need more than one new type variable such as with > the 'ReaderT r (ST s)' instance of 'PrimMonad'. > > In OCaml you can still kind of work around this problem by creating local > instances inside functions. That trick still allows you to write a polymorphic > concatenation function using a monoid signature (taken from [1]): > >      let concat (type a) xs = >        let module MU = MonoidUtils (ListMonoid(struct type t = a end)) in >        MU.concat xs;; > > So, I'm wondering if it would be possible to "generalise" over indefinite > Backpack types such as 'A' in the 'Elem' signature above or if we can at least > implement something which enables the same trick that you can use in OCaml. > > Thanks, > > Jaro > > [1] https://blog.shaynefletcher.org/2017/05/more-type-classes-in-ocaml.html > > > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > > ------------------------------ > > End of Haskell-Cafe Digest, Vol 217, Issue 10 > ********************************************* > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > From dominik.schrempf at gmail.com Sun Sep 12 04:21:01 2021 From: dominik.schrempf at gmail.com (Dominik Schrempf) Date: Sun, 12 Sep 2021 06:21:01 +0200 Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman Message-ID: <871r5ujr25.fsf@gmail.com> Hi! I am referring to the impressive talk/show/thought-provoking message about "The Historical Futurism of Haskell" delivered by Andrew Boardman at the Haskell Love Conference. I am not sure if I am allowed to link to the talk myself, since it is password protected, and was part of a conference. Maybe this can be done by the conference organizers, or by Andrew himself, if they please. In summary, and please add your comments or correct me, Andrew discusses that we truly believe that Haskell --- as a statically typed, lazy, pure, and functional language -- is an incredibly powerful tool, that should be made available to everybody now and for the next thirty years. However, he argues that this power is hard to access because we have a lot of "adequate" tooling for a fantastic language. He adds that we need superb tooling in order for "beginners to learn faster, and experienced programmers to accelerate productivity". He refers to overhauling programming environments to reflect data flow across and within functions and to "setting higher standards" for ourselves so that we finally "lift ourselves out of the pit of adequacy". He also asks whether it is really necessary to be in "crisis mode" to invest into fundamental changes of the ecosystem (escalation of commitment). I deeply agree, and wanted to thank Andrew for his talk. Personally, to me it seemed that Andrew was more referring to the programming environment than to the set of available libraries, although this may not have been his intention. I wanted to express that in my opinion, and in order to drive Haskell forward, we need a qualitative, reliable, performant, and well maintained "standard" library. Haskell has many "adequate" libraries but few superb ones. And while I understand that the immense advantages of being an open source community also come at a cost: a lot of work we do in our free time, because we have limited funding for improving libraries or development environments. Many libraries are maintained by one individual who may have the time and resources (or not) to look at standing issues or possibilities for improvements. In particular, I am a mathematician/statistician working in evolutionary biology. I work with multivariate distributions (hardly any of those are readily available on Hackage), I work with a lot of random numbers (the support for random sampling is mediocre, at best; 'splitmix' is standard by now but not supported by the most important statistics library of Haskell), I work with numerical optimization (I envy Pythonians for their libraries, although I still prefer Haskell because what I achieve, at least I get right), I work with Markov chains (yes, I had to write my own MCMC library in order to run proper Markov chains), I need to plot my data (there is no superb standard plotting library available in Haskell). By now, I do maintain library packages providing answers to some of these problems, but it was (and is) a lot of work. Finally, I want to thank all library developers for their impressive work, thank you! And still, I think it is not enough. In my opinion, these are all examples where Haskell needs to improve if we want to broaden the adoption among the general public. Do we have the resources? Thank you! Dominik From david.feuer at gmail.com Sun Sep 12 06:12:49 2021 From: david.feuer at gmail.com (David Feuer) Date: Sun, 12 Sep 2021 02:12:49 -0400 Subject: [Haskell-cafe] Backpack: polymorphic instantation? In-Reply-To: <3fb19986-f998-61c7-8c56-482b1647e2eb@gmail.com> References: <3fb19986-f998-61c7-8c56-482b1647e2eb@gmail.com> Message-ID: The main challenge is that, last I checked, stack didn't support backpack at all. This makes it a hard sell. On Sat, Sep 11, 2021, 5:59 AM Jaro Reinders wrote: > I'm playing around with backpack, trying to rewrite existing libraries. My > end > goal is to see if Backpack could improve the primitive library. Right now, > the > primitive library (in my opinion) relies too heavily on specialization of > its > type classes, so I think Backpack could help. However, I seem to be > running > into a limitation. I am wondering if it is a fundamental limitation, if > perhaps > there is a workaround, or if Backpack could be improved to support this > use-case. > > Instead of primitive, I will take the simpler example: semigroup, which > also > shows this limitation. Let's convert the Semigroup class to a backpack > signature: > > unit indef where > signature Semigroup where > import Prelude hiding ((<>)) > data T > (<>) :: T -> T -> T > > The problem is how to implement this signature with the type of > polymorphic > lists. It is easy to implement it for concrete lists like strings: > > unit string where > module Semigroup where > import Prelude hiding ((<>)) > type T = String > (<>) :: T -> T -> T > (<>) = (++) > > It is also possible to implement it in terms of another signature: > > unit list where > signature Elem where > data A > > module Semigroup where > import Prelude hiding ((<>)) > import Elem > type T = [A] > (<>) :: T -> T -> T > (<>) = (++) > > This is still problematic, because it is annoying that this new type A > needs to > be instantiated each time you want to use it. However, even more > importantly, > if I want to translate the 'PrimMonad' class to a Backpack signature then > the > 'ST s' instance needs a polymorphic type variable 's', which cannot be > made > concrete. > > And do note that I want the monad to be concrete for performance reasons, > but > the 's' parameter doesn't have to be concrete, because it is a phantom > parameter anyway. And for lists making the 'a' parameter concrete also > would > not improve performance as far as I know. > > One possible way to fix this is to add a type variable in the 'Semigroup' > signature, but then I think it becomes impossible to write the 'String' > instance and sometimes you need more than one new type variable such as > with > the 'ReaderT r (ST s)' instance of 'PrimMonad'. > > In OCaml you can still kind of work around this problem by creating local > instances inside functions. That trick still allows you to write a > polymorphic > concatenation function using a monoid signature (taken from [1]): > > let concat (type a) xs = > let module MU = MonoidUtils (ListMonoid(struct type t = a end)) in > MU.concat xs;; > > So, I'm wondering if it would be possible to "generalise" over indefinite > Backpack types such as 'A' in the 'Elem' signature above or if we can at > least > implement something which enables the same trick that you can use in OCaml. > > Thanks, > > Jaro > > [1] > https://blog.shaynefletcher.org/2017/05/more-type-classes-in-ocaml.html > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From tikhon at jelv.is Sun Sep 12 06:32:17 2021 From: tikhon at jelv.is (Tikhon Jelvis) Date: Sat, 11 Sep 2021 23:32:17 -0700 Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman In-Reply-To: <871r5ujr25.fsf@gmail.com> References: <871r5ujr25.fsf@gmail.com> Message-ID: Let me second this. I've worked on a few different supply chain problems over the last five years and Haskell *as a language* would have been perfect—if it only had more libraries. I did do some work in Haskell (which was great), but it just didn't make sense in other areas :/. Modeling problems have a combination of mathematical and domain-specific complexity that lets Haskell's types and expressiveness really shine. Functional programming is a natural fit for this area; most of the Numpy/Python code I see at work sticks to immutable operations. It would not be much of an exaggeration to call Pandas a purely functional DSL embedded in Python. I taught Haskell to one of my colleagues with a PhD in operations research, and he said it was the first time a programming language matched how he thought about his work. Tooling wouldn't necessarily be a bottleneck either. I still believe that friendly and stable tooling is important, but the state of Python tooling—somehow less consistent and more confusing than Haskell's tools—shows that people will work around tooling issues if everything else falls into place. Missing foundational libraries? Not so much. On Sat, Sep 11, 2021 at 10:53 PM Dominik Schrempf < dominik.schrempf at gmail.com> wrote: > Hi! > > I am referring to the impressive talk/show/thought-provoking message about > "The > Historical Futurism of Haskell" delivered by Andrew Boardman at the > Haskell Love > Conference. I am not sure if I am allowed to link to the talk myself, > since it > is password protected, and was part of a conference. Maybe this can be > done by > the conference organizers, or by Andrew himself, if they please. > > In summary, and please add your comments or correct me, Andrew discusses > that we > truly believe that Haskell --- as a statically typed, lazy, pure, and > functional > language -- is an incredibly powerful tool, that should be made available > to > everybody now and for the next thirty years. However, he argues that this > power > is hard to access because we have a lot of "adequate" tooling for a > fantastic > language. He adds that we need superb tooling in order for > "beginners to learn faster, and experienced programmers to accelerate > productivity". He refers to overhauling programming environments to > reflect data > flow across and within functions and to "setting higher standards" for > ourselves > so that we finally "lift ourselves out of the pit of adequacy". He also > asks > whether it is really necessary to be in "crisis mode" to invest into > fundamental > changes of the ecosystem (escalation of commitment). > > I deeply agree, and wanted to thank Andrew for his talk. Personally, to me > it > seemed that Andrew was more referring to the programming environment than > to the > set of available libraries, although this may not have been his intention. > I > wanted to express that in my opinion, and in order to drive Haskell > forward, we > need a qualitative, reliable, performant, and well maintained "standard" > library. Haskell has many "adequate" libraries but few superb ones. And > while I > understand that the immense advantages of being an open source community > also > come at a cost: a lot of work we do in our free time, because we have > limited > funding for improving libraries or development environments. Many > libraries are > maintained by one individual who may have the time and resources (or not) > to > look at standing issues or possibilities for improvements. > > In particular, I am a mathematician/statistician working in evolutionary > biology. I work with multivariate distributions (hardly any of those are > readily > available on Hackage), I work with a lot of random numbers (the support for > random sampling is mediocre, at best; 'splitmix' is standard by now but not > supported by the most important statistics library of Haskell), I work with > numerical optimization (I envy Pythonians for their libraries, although I > still > prefer Haskell because what I achieve, at least I get right), I work with > Markov > chains (yes, I had to write my own MCMC library in order to run proper > Markov > chains), I need to plot my data (there is no superb standard plotting > library > available in Haskell). By now, I do maintain library packages providing > answers > to some of these problems, but it was (and is) a lot of work. > > Finally, I want to thank all library developers for their impressive work, > thank > you! And still, I think it is not enough. In my opinion, these are all > examples > where Haskell needs to improve if we want to broaden the adoption among the > general public. Do we have the resources? > > Thank you! > Dominik > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lemming at henning-thielemann.de Sun Sep 12 08:24:36 2021 From: lemming at henning-thielemann.de (Henning Thielemann) Date: Sun, 12 Sep 2021 10:24:36 +0200 (CEST) Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman In-Reply-To: <871r5ujr25.fsf@gmail.com> References: <871r5ujr25.fsf@gmail.com> Message-ID: <2bf0f131-7687-c29-8ca0-b18424466fa3@henning-thielemann.de> On Sun, 12 Sep 2021, Dominik Schrempf wrote: > I work with Markov chains (yes, I had to write my own MCMC library in > order to run proper Markov chains), I don't know what proper Markov chains are, at least I wrote my own simple lazy Markov chain generator years ago that fulfilled my needs: https://hackage.haskell.org/package/markov-chain I have also written a package for Hidden Markov models: https://hackage.haskell.org/package/hmm-lapack > I need to plot my data (there is no superb standard plotting library > available in Haskell). By now, I do maintain library packages providing > answers to some of these problems, but it was (and is) a lot of work. If you write packages that fulfill the needs of your applications, that's certainly better than writing impressive frameworks where no one knows whether it is usable, at all. :-) From jaro.reinders at gmail.com Sun Sep 12 08:32:21 2021 From: jaro.reinders at gmail.com (Jaro Reinders) Date: Sun, 12 Sep 2021 10:32:21 +0200 Subject: [Haskell-cafe] Backpack: polymorphic instantation? In-Reply-To: References: <3fb19986-f998-61c7-8c56-482b1647e2eb@gmail.com> Message-ID: <5933a99d-46d2-c822-2146-112730b33867@gmail.com> I don't worry about Stack support, because, for now, this is still just some research, so whether it can immediately be used in practice is not important. It is much more important to determine whether this is possible at all. On 12-09-2021 08:12, David Feuer wrote: > The main challenge is that, last I checked, stack didn't support backpack at > all. This makes it a hard sell. From jaro.reinders at gmail.com Sun Sep 12 10:13:59 2021 From: jaro.reinders at gmail.com (Jaro Reinders) Date: Sun, 12 Sep 2021 12:13:59 +0200 Subject: [Haskell-cafe] Backpack: polymorphic instantation? In-Reply-To: <3fb19986-f998-61c7-8c56-482b1647e2eb@gmail.com> References: <3fb19986-f998-61c7-8c56-482b1647e2eb@gmail.com> Message-ID: <91473a0f-fc94-fbd5-b9eb-773ad0f5b145@gmail.com> I have now found a way to implement a PrimMonad signature using type (constraint) families and equality constraints. It supports IO, ST, and ReaderT. The code is here: https://gist.github.com/noughtmare/3aaef4bce58154f47afe6941ea74ac4f It still feels like a hack (and maybe even a bug with the GHC implementation of Backpack), but it seems to work (it compiles, so it must work :P). I would love to know if there is an easier way. Now, I'll try to see if this is actually practical to use. Cheers, Jaro On 11-09-2021 11:58, Jaro Reinders wrote: > I'm playing around with backpack, trying to rewrite existing libraries. My end > goal is to see if Backpack could improve the primitive library. Right now, the > primitive library (in my opinion) relies too heavily on specialization of its > type classes, so I think Backpack could help. However, I seem to be running > into a limitation. I am wondering if it is a fundamental limitation, if perhaps > there is a workaround, or if Backpack could be improved to support this use-case. > > Instead of primitive, I will take the simpler example: semigroup, which also > shows this limitation. Let's convert the Semigroup class to a backpack signature: > >     unit indef where >       signature Semigroup where >         import Prelude hiding ((<>)) >         data T >         (<>) :: T -> T -> T > > The problem is how to implement this signature with the type of polymorphic > lists. It is easy to implement it for concrete lists like strings: > >     unit string where >      module Semigroup where >       import Prelude hiding ((<>)) >       type T = String >       (<>) :: T -> T -> T >       (<>) = (++) > > It is also possible to implement it in terms of another signature: > >     unit list where >       signature Elem where >         data A > >       module Semigroup where >         import Prelude hiding ((<>)) >         import Elem >         type T = [A] >         (<>) :: T -> T -> T >         (<>) = (++) > > This is still problematic, because it is annoying that this new type A needs to > be instantiated each time you want to use it. However, even more importantly, > if I want to translate the 'PrimMonad' class to a Backpack signature then the > 'ST s' instance needs a polymorphic type variable 's', which cannot be made > concrete. > > And do note that I want the monad to be concrete for performance reasons, but > the 's' parameter doesn't have to be concrete, because it is a phantom > parameter anyway. And for lists making the 'a' parameter concrete also would > not improve performance as far as I know. > > One possible way to fix this is to add a type variable in the 'Semigroup' > signature, but then I think it becomes impossible to write the 'String' > instance and sometimes you need more than one new type variable such as with > the 'ReaderT r (ST s)' instance of 'PrimMonad'. > > In OCaml you can still kind of work around this problem by creating local > instances inside functions. That trick still allows you to write a polymorphic > concatenation function using a monoid signature (taken from [1]): > >     let concat (type a) xs = >       let module MU = MonoidUtils (ListMonoid(struct type t = a end)) in >       MU.concat xs;; > > So, I'm wondering if it would be possible to "generalise" over indefinite > Backpack types such as 'A' in the 'Elem' signature above or if we can at least > implement something which enables the same trick that you can use in OCaml. > > Thanks, > > Jaro > > [1] https://blog.shaynefletcher.org/2017/05/more-type-classes-in-ocaml.html From jaro.reinders at gmail.com Sun Sep 12 10:29:30 2021 From: jaro.reinders at gmail.com (Jaro Reinders) Date: Sun, 12 Sep 2021 12:29:30 +0200 Subject: [Haskell-cafe] Backpack: polymorphic instantation? In-Reply-To: <91473a0f-fc94-fbd5-b9eb-773ad0f5b145@gmail.com> References: <3fb19986-f998-61c7-8c56-482b1647e2eb@gmail.com> <91473a0f-fc94-fbd5-b9eb-773ad0f5b145@gmail.com> Message-ID: <9ad40237-1999-0d53-d666-36d0e327bf76@gmail.com> Nevermind. The PrimReaderT module doesn't actually implement the signature. On 12-09-2021 12:13, Jaro Reinders wrote: > I have now found a way to implement a PrimMonad signature using type > (constraint) families and equality constraints. It supports IO, ST, and > ReaderT. The code is here: > > https://gist.github.com/noughtmare/3aaef4bce58154f47afe6941ea74ac4f > > It still feels like a hack (and maybe even a bug with the GHC implementation of > Backpack), but it seems to work (it compiles, so it must work :P). I would love > to know if there is an easier way. > > Now, I'll try to see if this is actually practical to use. > > Cheers, > > Jaro > > On 11-09-2021 11:58, Jaro Reinders wrote: >> I'm playing around with backpack, trying to rewrite existing libraries. My >> end goal is to see if Backpack could improve the primitive library. Right >> now, the primitive library (in my opinion) relies too heavily on >> specialization of its type classes, so I think Backpack could help. However, >> I seem to be running into a limitation. I am wondering if it is a fundamental >> limitation, if perhaps there is a workaround, or if Backpack could be >> improved to support this use-case. >> >> Instead of primitive, I will take the simpler example: semigroup, which also >> shows this limitation. Let's convert the Semigroup class to a backpack >> signature: >> >>      unit indef where >>        signature Semigroup where >>          import Prelude hiding ((<>)) >>          data T >>          (<>) :: T -> T -> T >> >> The problem is how to implement this signature with the type of polymorphic >> lists. It is easy to implement it for concrete lists like strings: >> >>      unit string where >>       module Semigroup where >>        import Prelude hiding ((<>)) >>        type T = String >>        (<>) :: T -> T -> T >>        (<>) = (++) >> >> It is also possible to implement it in terms of another signature: >> >>      unit list where >>        signature Elem where >>          data A >> >>        module Semigroup where >>          import Prelude hiding ((<>)) >>          import Elem >>          type T = [A] >>          (<>) :: T -> T -> T >>          (<>) = (++) >> >> This is still problematic, because it is annoying that this new type A needs >> to be instantiated each time you want to use it. However, even more >> importantly, if I want to translate the 'PrimMonad' class to a Backpack >> signature then the 'ST s' instance needs a polymorphic type variable 's', >> which cannot be made concrete. >> >> And do note that I want the monad to be concrete for performance reasons, but >> the 's' parameter doesn't have to be concrete, because it is a phantom >> parameter anyway. And for lists making the 'a' parameter concrete also would >> not improve performance as far as I know. >> >> One possible way to fix this is to add a type variable in the 'Semigroup' >> signature, but then I think it becomes impossible to write the 'String' >> instance and sometimes you need more than one new type variable such as with >> the 'ReaderT r (ST s)' instance of 'PrimMonad'. >> >> In OCaml you can still kind of work around this problem by creating local >> instances inside functions. That trick still allows you to write a >> polymorphic concatenation function using a monoid signature (taken from [1]): >> >>      let concat (type a) xs = >>        let module MU = MonoidUtils (ListMonoid(struct type t = a end)) in >>        MU.concat xs;; >> >> So, I'm wondering if it would be possible to "generalise" over indefinite >> Backpack types such as 'A' in the 'Elem' signature above or if we can at >> least implement something which enables the same trick that you can use in >> OCaml. >> >> Thanks, >> >> Jaro >> >> [1] https://blog.shaynefletcher.org/2017/05/more-type-classes-in-ocaml.html From dominik.schrempf at gmail.com Sun Sep 12 15:56:30 2021 From: dominik.schrempf at gmail.com (Dominik Schrempf) Date: Sun, 12 Sep 2021 17:56:30 +0200 Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman In-Reply-To: <2bf0f131-7687-c29-8ca0-b18424466fa3@henning-thielemann.de> References: <871r5ujr25.fsf@gmail.com> <2bf0f131-7687-c29-8ca0-b18424466fa3@henning-thielemann.de> Message-ID: <87wnnlixbn.fsf@gmail.com> Henning Thielemann writes: > On Sun, 12 Sep 2021, Dominik Schrempf wrote: > >> I work with Markov chains (yes, I had to write my own MCMC library in order to >> run proper Markov chains), > > I don't know what proper Markov chains are, at least I wrote my own simple lazy > Markov chain generator years ago that fulfilled my needs: > https://hackage.haskell.org/package/markov-chain > > I have also written a package for Hidden Markov models: > https://hackage.haskell.org/package/hmm-lapack Thank you for mentioning this. I was playing around with 'markov-chain' some time ago! I was referring for something more generic, for example, where the transition rate/probability matrices can be directly defined. I am not so familiar with hidden Markov models. With respect to the term "proper", thanks for picking that up :); I should have been more specific: I was referring to Markov chain Monte Carlo samplers. For a reference implementation, please see the 'mcmc' library in R [1], for a feature-rich one, e.g., 'PyMC3' [2]. > >> I need to plot my data (there is no superb standard plotting library available >> in Haskell). By now, I do maintain library packages providing answers to some >> of these problems, but it was (and is) a lot of work. > > If you write packages that fulfill the needs of your applications, that's > certainly better than writing impressive frameworks where no one knows > whether it is usable, at all. :-) You are right, we want to avoid impressive but unusable frameworks. I was referring to the following question: "For a given goal, which features do I have to implement myself in order achieve the goal?" With the existing set of Haskell libraries, I make the following observation too often (or too early in my stack of requirements): "This feature is not available (or not readily available), I need to implement it myself." For example, at the moment I am working on a library for estimating covariance matrices from sample data. This is not at all my area of expertise. In Python and R, well maintained state-of-the-art methods are readily available (e.g., shrinkage based estimators such as the Ledoit-Wolf estimator, or oracle approximating shrinkage, as well as estimators based on Gaussian graphical models such as the graphical lasso --- actually, there is a glasso library on Hackage but it seems unmaintained, lacks documentation, and improvements from newer findings in the last 10 years). I hope I made myself clear. I don't want to naysay. I really enjoy Haskell per se! I am a big fan. Dominik [1] https://mran.microsoft.com/snapshot/2015-02-27/web/packages/mcmc/index.html [2] https://docs.pymc.io/ From cdsmith at gmail.com Sun Sep 12 16:42:55 2021 From: cdsmith at gmail.com (Chris Smith) Date: Sun, 12 Sep 2021 12:42:55 -0400 Subject: [Haskell-cafe] Virtual Haskell CoHack on Sep 25 Message-ID: For the second time, I'm hosting a virtual Haskell CoHack on September 25. If you've wanted to meet new Haskellers, give or hear lightning talks, and hack together on Haskell projects, this is your chance. Sign up at https://www.meetup.com/NY-Haskell/events/280727563/ The event will be held via Zoom. I've tried to time it to be reasonable for people across the Americas and Europe. Sadly, time zones cannot accommodate everyone. :( But if you can, please consider coming! -------------- next part -------------- An HTML attachment was scrubbed... URL: From dominic at steinitz.org Mon Sep 13 12:23:58 2021 From: dominic at steinitz.org (Dominic Steinitz) Date: Mon, 13 Sep 2021 13:23:58 +0100 Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman In-Reply-To: References: Message-ID: > On 12 Sep 2021, at 13:00, haskell-cafe-request at haskell.org wrote: > > In particular, I am a mathematician/statistician working in evolutionary > biology. I work with multivariate distributions (hardly any of those are readily > available on Hackage), I work with a lot of random numbers (the support for > random sampling is mediocre, at best; 'splitmix' is standard by now but not > supported by the most important statistics library of Haskell), I work with > numerical optimization (I envy Pythonians for their libraries, although I still > prefer Haskell because what I achieve, at least I get right), I work with Markov > chains (yes, I had to write my own MCMC library in order to run proper Markov > chains), I need to plot my data (there is no superb standard plotting library > available in Haskell). By now, I do maintain library packages providing answers > to some of these problems, but it was (and is) a lot of work. I have to take issue with your statement about random sampling. I think we have a really good story with random numbers now. They are of high quality and fast. R and possibly Python and Julia by comparison still use Mersenne Twister, of lower quality, slower and without a good story for generating independent sequences for parallel computations. I maintain random-fu (sampling from distributions) and using the new random number generator it is now several times (x4?) faster than it was. Conceivably it could be made even faster. Please give details on where you think we can improve and better still contribute your own improvements :-) In terms of MCMC, I think Jared Tobin wrote some libraries but I don’t think they are maintained. I maintain an SMC library but I don’t know how much use it gets. Tom Nielsen, Henrik Nilsson and I wrote Haskell “bindings” for Stan: https://nottingham-repository.worktribe.com/output/1151875/getting-more-out-of-stan-some-ideas-from-the-haskell-bindings. It would be a lot of work to e.g. re-create Stan in Haskell natively. I agree about plotting but inline-r makes it possible to use ggplot in R via Haskell which makes things like drawing maps with reasonable projections relatively straightforward. More generally, I think we have a good set of bindings for the ODE solver library SUNDIALS and also for other numeric libraries (e.g. LAPACK and BLAS). The problem we have is not enough hands working on such things. I now sadly return to programming in Julia. PS - there is probably more I could say on numerical stuff in Haskell but the above already looks like “stream of consciousness”. Dominic Steinitz dominic at steinitz.org http://idontgetoutmuch.org Twitter: @idontgetoutmuch -------------- next part -------------- An HTML attachment was scrubbed... URL: From anton.antich at gmail.com Mon Sep 13 13:47:51 2021 From: anton.antich at gmail.com (Anton Antich) Date: Mon, 13 Sep 2021 15:47:51 +0200 Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman In-Reply-To: <87wnnlixbn.fsf@gmail.com> References: <87wnnlixbn.fsf@gmail.com> Message-ID: <61E4010B-DC94-4F8C-BC74-FD4D5E2353C1@gmail.com> I love Haskell, as probably anybody who has finally understood “how to cook it”. Took me 3 attempts to really get it though - and my experience is quite similar to a lot of developers with imperative background. I’ve worked with large teams of developers both in the enterprise environment as well as in some 20 startups I’ve invested into. I’ve tried to push haskell on all of them, half-seriously, to try to understand why wouldn’t they use it? I would say the most popular reason by far is - very steep learning curve for any imperative programmer. Not the libraries (even if we could use more for some specific domains), not the tooling (even though I can envision an IDE for Haskell that would make development experience such a delight - imagine visualizing monad transformer stacks and function composition with types?!), not that GUI sucks (we really need a good GUI library) - but difficulty learning the concepts to become proficient. Somewhat arrogant approach of the libraries authors to the documentation - the whole “type signature *is* documentation” - doesn’t help either. So, again, I love Haskell, went a difficult road understanding how it should be taught by mastering it myself, which actually lead me to writing a book on teaching Haskell from the first principles, focusing on types, but gently and in pictures so that it’s accessible - https://leanpub.com/magicalhaskell - for which id love feedback by the way :) But we need to teach FP much better in CS schools - there are a zillion courses on Python and how Many on Haskell? We have to write more tutorials and much friendlier documentation. We have to explain real world patterns much better and with more examples - normally all Haskell docs and even examples are way too abstract, which is solid science but doesn’t help for the mass adoption. And then, yes, we need libraries and tooling. Best wishes, - A. > On 12 Sep 2021, at 18:17, Dominik Schrempf wrote: > >  > Henning Thielemann writes: > >>> On Sun, 12 Sep 2021, Dominik Schrempf wrote: >>> >>> I work with Markov chains (yes, I had to write my own MCMC library in order to >>> run proper Markov chains), >> >> I don't know what proper Markov chains are, at least I wrote my own simple lazy >> Markov chain generator years ago that fulfilled my needs: >> https://hackage.haskell.org/package/markov-chain >> >> I have also written a package for Hidden Markov models: >> https://hackage.haskell.org/package/hmm-lapack > > Thank you for mentioning this. I was playing around with 'markov-chain' some > time ago! I was referring for something more generic, for example, where the > transition rate/probability matrices can be directly defined. I am not so > familiar with hidden Markov models. With respect to the term "proper", thanks > for picking that up :); I should have been more specific: I was referring to > Markov chain Monte Carlo samplers. For a reference implementation, please see > the 'mcmc' library in R [1], for a feature-rich one, e.g., 'PyMC3' [2]. > >> >>> I need to plot my data (there is no superb standard plotting library available >>> in Haskell). By now, I do maintain library packages providing answers to some >>> of these problems, but it was (and is) a lot of work. >> >> If you write packages that fulfill the needs of your applications, that's >> certainly better than writing impressive frameworks where no one knows >> whether it is usable, at all. :-) > > You are right, we want to avoid impressive but unusable frameworks. I was > referring to the following question: "For a given goal, which features do I have > to implement myself in order achieve the goal?" With the existing set of Haskell > libraries, I make the following observation too often (or too early in my stack > of requirements): "This feature is not available (or not readily available), I > need to implement it myself." For example, at the moment I am working on a > library for estimating covariance matrices from sample data. This is not at all > my area of expertise. In Python and R, well maintained state-of-the-art methods > are readily available (e.g., shrinkage based estimators such as the Ledoit-Wolf > estimator, or oracle approximating shrinkage, as well as estimators based on > Gaussian graphical models such as the graphical lasso --- actually, there is a > glasso library on Hackage but it seems unmaintained, lacks documentation, and > improvements from newer findings in the last 10 years). > > I hope I made myself clear. I don't want to naysay. I really enjoy Haskell per > se! I am a big fan. > > Dominik > > [1] https://mran.microsoft.com/snapshot/2015-02-27/web/packages/mcmc/index.html > > [2] https://docs.pymc.io/ > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From emilypi at cohomolo.gy Mon Sep 13 19:30:16 2021 From: emilypi at cohomolo.gy (Emily Pillmore) Date: Mon, 13 Sep 2021 19:30:16 +0000 Subject: [Haskell-cafe] [ANN] Core Libraries Committee Elections Message-ID: Dear Haskell Community, The Core Libraries Committee is seeking new members! As detailed in recent updates (see: https://discourse.haskell.org/t/state-of-the-core-libraries-committee-update/2911 ), we put out an internal call to discuss restructuring the CLC to better meet the needs of the community. In particular, we are in the planning stages of writing the new process, and are seeking **2** new members who, as part of their standard CLC duties, get to participate in its construction. ## Who should apply? Anyone who meets the following criteria should apply: 1. Candidates should have enough bandwidth to review merge requests to `base` on a semi-frequent basis (2 to 3 per month), and *sustain* this for their term in a healthy manner. 2. Candidates should be able to contribute opinions and analysis to issues raised by the community as a part of the new Github-based CLC process on a semi-frequent basis (2 to 3 per month). 3. Candidates should be good communicators, and at least be able to articulate to the CLC team when they will be available vs. unavailable. 4. Candidates should be productive, and be able to follow through on merge requests and conversations to their completion in a diligent and timely manner. We encourage any and all who satisfy these requirements to apply. Please note that we are not looking for the biggest galaxy brain in the room - quite the opposite. We are looking for productive, motivated individuals who want to help support the ecosystem that we love. As such, we hope to build a broad sample of the community. This election is particularly special due to the fact that our new members will have the chance to help shape process for new generations of the CLC to come, and can take ownership from the ground up so to speak. This means that we can help shape a process that works better for us as modern Haskell developers, and help the CLC become a better fit for the community's needs. ## How can I apply? To apply for one of these positions, send an email to the CLC email address ( core-libraries-committee at haskell.org ) that consists of the following data: 1. The header "CLC Election September 2021 - " 2. Why you think you're a good fit given the above criteria 3. If applicable, please point us to some code you've written ## When will elections be decided? Please note the following dates: 1. Election submissions open: Sept 13 2. Election submissions close: Sept 20 3. Election outcome announced: Sept 27 Cheers, Emily - on behalf of the CLC -------------- next part -------------- An HTML attachment was scrubbed... URL: From dominik.schrempf at gmail.com Tue Sep 14 08:27:34 2021 From: dominik.schrempf at gmail.com (Dominik Schrempf) Date: Tue, 14 Sep 2021 10:27:34 +0200 Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman In-Reply-To: References: Message-ID: <87v933v8wj.fsf@gmail.com> Dominic Steinitz writes: > On 12 Sep 2021, at 13:00, haskell-cafe-request at haskell.org wrote: > > In particular, I am a mathematician/statistician working in evolutionary > biology. I work with multivariate distributions (hardly any of those are readily > available on Hackage), I work with a lot of random numbers (the support for > random sampling is mediocre, at best; 'splitmix' is standard by now but not > > supported by the most important statistics library of Haskell), I work with > numerical optimization (I envy Pythonians for their libraries, although I still > prefer Haskell because what I achieve, at least I get right), I work with Markov > chains (yes, I had to write my own MCMC library in order to run proper Markov > chains), I need to plot my data (there is no superb standard plotting library > available in Haskell). By now, I do maintain library packages providing answers > to some of these problems, but it was (and is) a lot of work. > > I have to take issue with your statement about random sampling. I think we have a really good story with random numbers now. They are of high quality and fast. R and possibly Python and Julia by comparison still use Mersenne Twister, of lower > quality, slower and without a good story for generating independent sequences for parallel computations. I maintain random-fu (sampling from distributions) and using the new random number generator it is now several times (x4?) faster than it > was. Conceivably it could be made even faster. Thank you for mentioning 'random-fu'. It makes me feel like wanting to change from using 'statistics' to 'random-fu'. I started using 'statistics' because I liked (depended on?) the notion of a 'Distribution' which can be instance of many classes (but I just saw that this is also the case for 'random-fu', maybe I overlooked it). I liked that there is a distinction between discrete and continuous distributions, and that there are more statistical functions available such as quantiles, and so on. The package 'statistics' only supports random number generation using the Mersenne Twister. It also does not support multivariate distributions. Right now, I am considering changing to 'random-fu'. What also kept me from using 'random-fu' is the following sentence in the description of the package: "Quality is prioritized over speed, but performance is an important goal too." This sounds to me like 'random-fu' focuses on the generation of cryptographically secure random numbers which is not what I need. > > Please give details on where you think we can improve and better still contribute your own improvements :-) In my opinion it would be great to: - separate continuous from discrete distributions - have one set of type classes used by 'random-fu' and 'statistics' (and all other packages working with distributions) - implement more and multivariate distributions (I implemented the 'dirichlet' distribution for 'statistics'; it is available on Hackage but it is not completely finished, and I don't consider myself able enough to contribute to core libraries yet; there is also 'random-fu-multivariate' but it only has the multivariate normal distribution) > > In terms of MCMC, I think Jared Tobin wrote some libraries but I don’t think they are maintained. I maintain an SMC library but I don’t know how much use it gets. Tom Nielsen, Henrik Nilsson and I wrote Haskell “bindings” for Stan: > https://nottingham-repository.worktribe.com/output/1151875/getting-more-out-of-stan-some-ideas-from-the-haskell-bindings. It would be a lot of work to e.g. re-create Stan in Haskell natively. I am aware of Jared Tobins packages! They are great entry points but not flexible enough for what I am doing. If you are interested, have a look at the 'mcmc' package, which I am developing. Thank you, I didn't know about the Stan Haskell bindings and will have a look. > > I agree about plotting but inline-r makes it possible to use ggplot in R via Haskell which makes things like drawing maps with reasonable projections relatively straightforward. > > More generally, I think we have a good set of bindings for the ODE solver library SUNDIALS and also for other numeric libraries (e.g. LAPACK and BLAS). The problem we have is not enough hands working on such things. > > I now sadly return to programming in Julia. Thanks for you input! > > PS - there is probably more I could say on numerical stuff in Haskell but the above already looks like “stream of consciousness”. > > Dominic Steinitz > dominic at steinitz.org > http://idontgetoutmuch.org > Twitter: @idontgetoutmuch > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From nikhil at acm.org Tue Sep 14 14:31:42 2021 From: nikhil at acm.org (Rishiyur Nikhil) Date: Tue, 14 Sep 2021 10:31:42 -0400 Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman In-Reply-To: References: Message-ID: This thread seems to be a mixture of (A) the original topic (about broad obstacles to Haskell adoption) and (B) technical details about particular libraries that came up in the conversation that may not be of immediate interest to people following (A). For people discussing (B), kindly change the subject line of your reply to be more specific to (B). Thanks, Nikhil -------------- next part -------------- An HTML attachment was scrubbed... URL: From borgauf at gmail.com Wed Sep 15 03:50:27 2021 From: borgauf at gmail.com (Galaxy Being) Date: Tue, 14 Sep 2021 22:50:27 -0500 Subject: [Haskell-cafe] Mixed Fraction data type Message-ID: I'm looking at Sandy Maguire's _Thinking With Types_ and he's talking about the cardinality of types. He introduces the product type data MixedFraction a = Fraction { mixedBit :: Word8 , numerator :: a , denominator :: a } How is this a type for holding mixed fractions such as 5-1/2? ⨽ Lawrence Bottorff Grand Marais, MN, USA borgauf at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From bob at redivi.com Wed Sep 15 04:13:10 2021 From: bob at redivi.com (Bob Ippolito) Date: Tue, 14 Sep 2021 21:13:10 -0700 Subject: [Haskell-cafe] Mixed Fraction data type In-Reply-To: References: Message-ID: >From context it's only used as a more concrete example of a product type to show how cardinality analysis works. I would infer that the idea is that this type would use mixedBit for the whole number and there would be a constraint that numerator < denominator. Fraction 5 1 2 would be the canonical way to represent 5 1/2 in that scheme. Practically speaking there's no reason to have the mixedBit field because a pair is enough to represent any fraction, but if it was simplified this way then the example would be redundant since there's already an example of a pair type on the same page. On Tue, Sep 14, 2021 at 8:51 PM Galaxy Being wrote: > I'm looking at Sandy Maguire's _Thinking With Types_ and he's talking > about the cardinality of types. He introduces the product type > > data MixedFraction a = Fraction > { mixedBit :: Word8 > , numerator :: a > , denominator :: a > } > > How is this a type for holding mixed fractions such as 5-1/2? > > ⨽ > Lawrence Bottorff > Grand Marais, MN, USA > borgauf at gmail.com > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Wed Sep 15 04:33:23 2021 From: david.feuer at gmail.com (David Feuer) Date: Wed, 15 Sep 2021 00:33:23 -0400 Subject: [Haskell-cafe] Typeable convenience class Message-ID: Occasionally it's useful to get a little information about a type's constructor (especially its name, module, or source package), without needing a Typeable instance for the type itself. I came up with this rather simple way, but I'm wondering if something like this already exists on Hackage. #if __GLASGOW_HASKELL__ < 710 {-# language OverlappingInstances #-} #endif ... import Data.Typeable class OuterTypeable a where -- | Get the 'TypeRep' corresponding to the outermost constructor -- of a type. getConTR :: proxy a -> TypeRep #if __GLASGOW_HASKELL__ >= 708 instance # if __GLASGOW_HASKELL__ >= 710 {-# OVERLAPPING #-} # endif OuterTypeable f => OuterTypeable (f a) where getConTR _ = getConTR (Proxy :: Proxy f) instance Typeable a => OuterTypeable a where getConTR = typeRep #else -- Before GHC 7.8, we didn't have polykinded Typeable, so things were -- rather less nice. instance Typeable a => OuterTypeable a where getConTR _ = typeOf (undefined :: a) instance Typeable1 p => OuterTypeable (p a) where getConTR _ = typeOf1 (undefined :: p a) [...] instance Typeable7 p => OuterTypeable (p a b c d e f g) where getConTR _ = typeOf7 (undefined :: p a b c d e f g) #endif From michael.eugene.turner at gmail.com Wed Sep 15 07:07:38 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Wed, 15 Sep 2021 16:07:38 +0900 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools Message-ID: I haven't been able to view Andrew Boardman's video so far, but I gather from the summary that he feels the solution to the most pressing problem -- growth through fostering newbies -- is simply . . . better tools. I beg to differ, as a newbie who is now struggling with the revival of some Haskell code only with a feeling of claustrophobia. Where is this incredible feeling of freedom I was promised? At the top of the learning curve. And it feels like a Sisyphean slope -- the boulder stops, when I lay off learning, and then slowly starts to roll down under the gravitational force of memory decay. The real problem is that the writing sucks. Not all of it -- and some contributors to the community are stellar writers, even if, in the snarkish commentary they write about Haskell and the community, I don't quite get all the jokes. But speaking as a contributor to the Haskell.org wiki -- to which I contribute at times out of hope that clarifying points I understand will also lead to more clarity for myself -- I have to say it: the writing sucks. Why does it suck? Well, there are several syndromes. One is to think that Haskell is so incredibly good and pure and elementally profound that one must start conceptually from scratch. (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") I've had a book recommended to me whose author had such pretensions to writing in a way that was easily foundational that he actually claimed his book could teach you Haskell even if you have no programming experience at all. Now, in practical marketing terms, that's just silly: such an approach addresses a minuscule fraction of the book's potential audience. If you've heard of Haskell as a programming language, you're probably software-multilingual already. But in practical pedagogical terms, it's also a little ridiculous. Your average reader (already a programmer) would be better served by a comparative approach: Here's how to say something in a couple of other programming languages, here's how to say something roughly equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. Here's how Haskell makes something easier (at least perhaps in being more concise, if the Haskell is more concise) but also conferring useful leverage where Haskell might otherwise seem unnecessarily verbose. The problem of better writing is ultimately social, I believe. I have a friend who's a tenured professor at Columbia University, who has used Haskell in courses, who praises Haskell for how it makes students think a little more clearly about how to structure software. However, his final verdict is this: Functional programming is a cult. Now, he's a unabashedly abrasive type. (Just ask him, he'll tell you.) And that verdict IS a little over the top. But I have to say, my impression of the community is that there are Founder demi-gods praised even though they leave something to be desired in how articulate and clear they are for newbies, even when claiming to be addressing newbies, while the language itself seems to be somewhat an object of worship. How can the writing be better? Well, here's a clue: Simon Peyton-Jones, somewhere in a talk where he was his usual vibrant self (but where the audience was clearly stunned and intimidated into silence even though he'd invited people to interrupt with questions) said that F# had settled on the term "workflow" instead of "monad", and he felt this was wise. Workflow? Workflow!? My still-feeble understanding of monads took a leap forward, because suddenly I had a motivation for them: abstraction of the idea of a workflow. Could it be that something as simple as Maybe was a kind of "degenerate case" of a "workflow abstraction"? I felt massively encouraged that I might finally figure out how great monads were. Which is not to say that I have. Writers: you need to stop speaking your own obscure little dialect of "programmer English". If you're not aware that you are, become more self-aware. If you ARE aware of it, become aware of how snobbish or pointlessly mysterious you sound. And if you do become aware of how you sound, but don't care, ask yourself: if the goal now is to spread Haskell and help it flourish, isn't your attitude more of a hindrance than a help? Tools? That's not the front I'd pick. Because I hit a glitch in getting VScode to work under Windows 10 (yes, cue the snobbery), I backed off to github bash and vim. And you know what? It's fine. Sorry if my knuckles seem to be dragging on the floor, but I'm from the Stone Age of Unix v7 command line and Bill Joy's original vi. I'd like nicer tools. But they aren't likely to help me with Haskell. What's not fine: half the time, I can't figure out the error messages from GHC, and a dismaying portion of the time, I can't figure out the language documentation. And since the concepts are seldom described in concrete enough and time-honored programming language terms (by comparison to other programming languages) they often don't really stick. It's like my Sysiphean boulder has been pre-greased -- if I stop pushing (hard enough with all the abstraction grease on it), it starts to slide even before it rolls, whenever I leave off coding in Haskell for any length of time. Sorry for not writing better email here -- my sentences get rather long and tortuous when I rant. But not sorry for ranting. You say the solution to a tool adoption problem (getting more people to use Haskell) is yet more tools written in Haskell, for your favorite language, Haskell? No. The failure here is a failure to communicate. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry From dominic at steinitz.org Wed Sep 15 09:23:49 2021 From: dominic at steinitz.org (Dominic Steinitz) Date: Wed, 15 Sep 2021 10:23:49 +0100 Subject: [Haskell-cafe] Comment on "The Historical Futurism of Haskell" by Andrew Boardman In-Reply-To: <87v933v8wj.fsf@gmail.com> References: <87v933v8wj.fsf@gmail.com> Message-ID: <93565FF7-55B5-4767-A6A2-D2500CB453EE@steinitz.org> Hi Dominik Thanks very much for your reply - comments inline below :-) Dominic Steinitz dominic at steinitz.org http://idontgetoutmuch.org Twitter: @idontgetoutmuch > On 14 Sep 2021, at 09:27, Dominik Schrempf wrote: > > > Dominic Steinitz > writes: > >> On 12 Sep 2021, at 13:00, haskell-cafe-request at haskell.org wrote: >> >> In particular, I am a mathematician/statistician working in evolutionary >> biology. I work with multivariate distributions (hardly any of those are readily >> available on Hackage), I work with a lot of random numbers (the support for >> random sampling is mediocre, at best; 'splitmix' is standard by now but not >> >> supported by the most important statistics library of Haskell), I work with >> numerical optimization (I envy Pythonians for their libraries, although I still >> prefer Haskell because what I achieve, at least I get right), I work with Markov >> chains (yes, I had to write my own MCMC library in order to run proper Markov >> chains), I need to plot my data (there is no superb standard plotting library >> available in Haskell). By now, I do maintain library packages providing answers >> to some of these problems, but it was (and is) a lot of work. >> >> I have to take issue with your statement about random sampling. I think we have a really good story with random numbers now. They are of high quality and fast. R and possibly Python and Julia by comparison still use Mersenne Twister, of lower >> quality, slower and without a good story for generating independent sequences for parallel computations. I maintain random-fu (sampling from distributions) and using the new random number generator it is now several times (x4?) faster than it >> was. Conceivably it could be made even faster. > > Thank you for mentioning 'random-fu'. It makes me feel like wanting to change > from using 'statistics' to 'random-fu'. I started using 'statistics' because I > liked (depended on?) the notion of a 'Distribution' which can be instance of > many classes (but I just saw that this is also the case for 'random-fu', maybe I > overlooked it). I liked that there is a distinction between discrete and > continuous distributions, and that there are more statistical functions > available such as quantiles, and so on. The package 'statistics' only supports > random number generation using the Mersenne Twister. It also does not support > multivariate distributions. Right now, I am considering changing to 'random-fu'. > > What also kept me from using 'random-fu' is the following sentence in the > description of the package: > > "Quality is prioritized over speed, but performance is an important goal too." > > This sounds to me like 'random-fu' focuses on the generation of > cryptographically secure random numbers which is not what I need. I think the original author meant they were not aiming for C like speed. The library certainly is not intended to generate crypto strength random numbers. Here’s my take on what random-fu did: Provides an interface to "sources of entropy” so you can plug in any RNG and produce random values for various specified types. Provides a domain specific language so that you can manipulate random values using an early precursor of free monads (the prompt monad) Provides a way of sampling from distributions. Provides cumulative distribution functions and probability density functions (where they exist). I think this is a bit of a later addition and I would like it to be comparable to what R provides. The new random interface means that (1) is no longer required. With new random (1.2) you can plug in your favourite RNG without having to add anything to random-fu (this was not the case e.g. for adding MWC previously). In my free time, I have been looking at how to move from the prompt monad to the free monad: https://github.com/lehins/random-fu/pull/1 > >> >> Please give details on where you think we can improve and better still contribute your own improvements :-) > In my opinion it would be great to: > - separate continuous from discrete distributions Certainly possible but I am not sure of the benefits and what would it look like concretely? > - have one set of type classes used by 'random-fu' and 'statistics' (and all > other packages working with distributions) I find this harder to visualise and what its consequences and benefits would be. > - implement more and multivariate distributions (I implemented the 'dirichlet' > distribution for 'statistics'; it is available on Hackage but it is not > completely finished, and I don't consider myself able enough to contribute to > core libraries yet; there is also 'random-fu-multivariate' but it only has the > multivariate normal distribution) Random-fu has a dirichlet sampler (https://hackage.haskell.org/package/random-fu-0.2.7.7/docs/Data-Random-Distribution-Dirichlet.html ) but maybe that is not what you meant? I created random-fu-multivariate with the intention of adding more multivariate distributions when I needed them - I haven’t thus far. It would be great if folks added to it. The reason to separate it from random-fu was that it relies on extra Haskell and external packages (LAPACK for Cholesky). Please do contribute. My approach is to look at what R / Python / Julia have already done and read the old masters such as http://www.eirene.de/Devroye.pdf I no longer feel totally confident that other programming language ecosystems have optimal implementations (vide Mersenne Twister). > >> >> In terms of MCMC, I think Jared Tobin wrote some libraries but I don’t think they are maintained. I maintain an SMC library but I don’t know how much use it gets. Tom Nielsen, Henrik Nilsson and I wrote Haskell “bindings” for Stan: >> https://nottingham-repository.worktribe.com/output/1151875/getting-more-out-of-stan-some-ideas-from-the-haskell-bindings . It would be a lot of work to e.g. re-create Stan in Haskell natively. > > I am aware of Jared Tobins packages! They are great entry points but not > flexible enough for what I am doing. If you are interested, have a look at the > 'mcmc' package, which I am developing. > > Thank you, I didn't know about the Stan Haskell bindings and will have a look. > >> >> I agree about plotting but inline-r makes it possible to use ggplot in R via Haskell which makes things like drawing maps with reasonable projections relatively straightforward. >> >> More generally, I think we have a good set of bindings for the ODE solver library SUNDIALS and also for other numeric libraries (e.g. LAPACK and BLAS). The problem we have is not enough hands working on such things. >> >> I now sadly return to programming in Julia. > > Thanks for you input! > >> >> PS - there is probably more I could say on numerical stuff in Haskell but the above already looks like “stream of consciousness”. >> >> Dominic Steinitz >> dominic at steinitz.org >> http://idontgetoutmuch.org >> Twitter: @idontgetoutmuch >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From minorinoki at gmail.com Wed Sep 15 12:08:45 2021 From: minorinoki at gmail.com (=?UTF-8?B?6I2S55SwIOWun+aouQ==?=) Date: Wed, 15 Sep 2021 21:08:45 +0900 Subject: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows In-Reply-To: References: <8A7B2D58-37D0-4C29-88BF-7580BFF31064@gmail.com> <74A1C636-FBA7-4E24-BD98-3FBF6193D9DE@gmail.com> Message-ID: The problem of asinh should be fixed in the C runtime library, so it should be fixed in mingw, or by using another C library implementation than mingw's. Actually, Microsoft's recent C library (Universal CRT) seems to have better math functions than mingw, so using it might be an option if possible. (cf. https://mail.haskell.org/pipermail/haskell-cafe/2021-April/133931.html https://awson.github.io/ghc-nw/ ) As to why GCC has two different implementations of asinh -- the implementation of math functions that GCC uses for constant folding is MPFR, which is a bit heavy for linking to every program that it compiles. 2021年9月7日(火) 18:01 David James : > > Thanks again. I’ve added a note to the issue, and raised a bug against mingw. (And also updated another related one.) > > > > Is the right solution here to get it fixed in mingw? (And would that then be picked up in some future Haskell release?). > > > > I’m also still a bit confused about ming-w64 and GCC (which are all very new to me). Per Wikipedia “Mingw-w64 includes a port of the GNU Compiler Collection (GCC)”. So why does it have two different implementations of asinh? – one for use by GCC (that gives good results), and one that is called at runtime (that gives bad results)?. > > > > Thanks! David. > > > > From: arata, mizuki > Sent: 04 September 2021 12:41 > To: David James > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows > > > > FloatFnInverses is marked as ‘expect_broken’ on Windows: > > https://gitlab.haskell.org/ghc/ghc/-/blob/922c6bc8dd8d089cfe4b90ec2120cb48959ba2b5/testsuite/tests/numeric/should_run/all.T#L44-45 > > And there’s a relevant issue: https://gitlab.haskell.org/ghc/ghc/-/issues/15670 > > > > Mizuki > > > > 2021/09/04 18:46、David James のメール: > > > > Hi - thank you for this. I was unaware of the “constant folding” in GCC (and I’m surprised it works for functions like asinh), but I can see that it explains the difference in behaviour. > > > > So I think this is a (possibly minor) bug that Haskell inherits from mingw-w64. I guess I should raise a GHC issue – though I’m not sure whether it would be best to try to fix within Haskell or within mingw-w64. > > > > Also, I think the FloatFnInverses.hs test doesn’t should be showing as a fail somewhere in the CI testing. (It doesn’t give the expected output when I run it on Windows). Do you know whether/where I can see that? (I don’t know what CI happens or how to view its output). > > > > Thanks again, > > David. > > > > From: arata, mizuki > Sent: 03 September 2021 13:43 > To: David James > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Trouble with asinh (c calls with Doubles) in Windows > > > > Hi David, > > If I understand correctly, GHC uses mingw-w64’s libc implementation on Windows. > Since mingw-w64’s math functions are not of very good quality, it is likely that asinh returns NaN for a very large input. > > As to why `asinh(1.7976931348623157e308)` in CAsinh.c produces (seemingly-correct) 710.4758, it is probably because the C compiler (GCC) uses a different implementation of asinh when doing constant folding. > As a note, you may get a different (compile-time computed) result for `asinh(x)` if you set a more aggressive optimization flag. > > Mizuki > > > > From dominik.schrempf at gmail.com Wed Sep 15 12:48:20 2021 From: dominik.schrempf at gmail.com (Dominik Schrempf) Date: Wed, 15 Sep 2021 14:48:20 +0200 Subject: [Haskell-cafe] Random number sampling and statistics libraries (was: Comment on "The Historical Futurism of Haskell" by Andrew Boardman) In-Reply-To: <93565FF7-55B5-4767-A6A2-D2500CB453EE@steinitz.org> References: <87v933v8wj.fsf@gmail.com> <93565FF7-55B5-4767-A6A2-D2500CB453EE@steinitz.org> Message-ID: <87a6kernud.fsf@gmail.com> Hi Dominic, neither can I do anything else than thank you for your detailed answer. I also added a few remarks below. Dominic Steinitz writes: > Hi Dominik > > Thanks very much for your reply - comments inline below :-) > > Dominic Steinitz > dominic at steinitz.org > http://idontgetoutmuch.org > Twitter: @idontgetoutmuch > > On 14 Sep 2021, at 09:27, Dominik Schrempf wrote: > > Dominic Steinitz writes: > > On 12 Sep 2021, at 13:00, haskell-cafe-request at haskell.org wrote: > > In particular, I am a mathematician/statistician working in evolutionary > biology. I work with multivariate distributions (hardly any of those are readily > available on Hackage), I work with a lot of random numbers (the support for > random sampling is mediocre, at best; 'splitmix' is standard by now but not > > supported by the most important statistics library of Haskell), I work with > numerical optimization (I envy Pythonians for their libraries, although I still > prefer Haskell because what I achieve, at least I get right), I work with Markov > chains (yes, I had to write my own MCMC library in order to run proper Markov > chains), I need to plot my data (there is no superb standard plotting library > available in Haskell). By now, I do maintain library packages providing answers > to some of these problems, but it was (and is) a lot of work. > > I have to take issue with your statement about random sampling. I think we have a really good story with random numbers now. They are of high quality and fast. R and possibly Python and Julia by comparison still use Mersenne Twister, > of lower > quality, slower and without a good story for generating independent sequences for parallel computations. I maintain random-fu (sampling from distributions) and using the new random number generator it is now several times (x4?) > faster than it > was. Conceivably it could be made even faster. > > Thank you for mentioning 'random-fu'. It makes me feel like wanting to change > from using 'statistics' to 'random-fu'. I started using 'statistics' because I > liked (depended on?) the notion of a 'Distribution' which can be instance of > many classes (but I just saw that this is also the case for 'random-fu', maybe I > overlooked it). I liked that there is a distinction between discrete and > continuous distributions, and that there are more statistical functions > available such as quantiles, and so on. The package 'statistics' only supports > random number generation using the Mersenne Twister. It also does not support > multivariate distributions. Right now, I am considering changing to 'random-fu'. > > What also kept me from using 'random-fu' is the following sentence in the > description of the package: > > "Quality is prioritized over speed, but performance is an important goal too." > > This sounds to me like 'random-fu' focuses on the generation of > cryptographically secure random numbers which is not what I need. > > I think the original author meant they were not aiming for C like speed. The library certainly is not intended to generate crypto strength random numbers. > > Here’s my take on what random-fu did: > > 1 Provides an interface to "sources of entropy” so you can plug in any RNG and produce random values for various specified types. > 2 Provides a domain specific language so that you can manipulate random values using an early precursor of free monads (the prompt monad) > 3 Provides a way of sampling from distributions. > 4 Provides cumulative distribution functions and probability density functions (where they exist). I think this is a bit of a later addition and I would like it to be comparable to what R provides. > > The new random interface means that (1) is no longer required. With new random (1.2) you can plug in your favourite RNG without having to add anything to random-fu (this was not the case e.g. for adding MWC previously). > > In my free time, I have been looking at how to move from the prompt monad to the free monad: https://github.com/lehins/random-fu/pull/1 Debloating the interface would certainly be advantageous. I just read through the documentation of "Data.Random" and was astonished how complicated the types are (but maybe this is necessary, I do not have enough information). It was also hard to find the reverse dependencies: splitmix <- random <- random-fu (splitmix seems to be hidden in 'StdGen', please correct me if this is wrong). > > Please give details on where you think we can improve and better still contribute your own improvements :-) > > In my opinion it would be great to: > - separate continuous from discrete distributions > > Certainly possible but I am not sure of the benefits and what would it look like concretely? I was thinking along the lines of the statistics package, which has a nice distinction: https://hackage.haskell.org/package/statistics-0.15.2.0/docs/Statistics-Distribution.html > > - have one set of type classes used by 'random-fu' and 'statistics' (and all > other packages working with distributions) > > I find this harder to visualise and what its consequences and benefits would be. I think I made an error. I didn't mean the type classes would be shared (those would be different in random-fu and statistics), but the (new)types. For example, the normal distribution 'Normal' could be instance of 'Data.Random.Distribution' of 'random-fu' but also of 'Statistics.Distribution.ContDistribution' of 'statistics'. Like so, 'random-fu' can take care of the sampling, and 'statistics' of the probability density functions etc. But maybe this is too naive of an idea. In practice, however, that's exactly what I (and I guess, others) need. I do not only need random samples, but also the (log) probability density function, etc. With respect to the Dirichlet distribution which you mention below (thanks for pointing this out), this is exactly the problem. The PDF is not available in 'random-fu' (or is it?), and so, another dependency or a personal implementation is required. > > - implement more and multivariate distributions (I implemented the 'dirichlet' > distribution for 'statistics'; it is available on Hackage but it is not > completely finished, and I don't consider myself able enough to contribute to > core libraries yet; there is also 'random-fu-multivariate' but it only has the > multivariate normal distribution) > > Random-fu has a dirichlet sampler (https://hackage.haskell.org/package/random-fu-0.2.7.7/docs/Data-Random-Distribution-Dirichlet.html) but maybe that is not what you meant? > > I created random-fu-multivariate with the intention of adding more multivariate distributions when I needed them - I haven’t thus far. It would be great if folks added to it. The reason to separate it from random-fu was that it relies on extra Haskell > and external packages (LAPACK for Cholesky). > > Please do contribute. My approach is to look at what R / Python / Julia have already done and read the old masters such as http://www.eirene.de/Devroye.pdf I no longer feel totally confident that other programming language ecosystems have > optimal implementations (vide Mersenne Twister). Thanks for your encouragement! Best, Dominik > > In terms of MCMC, I think Jared Tobin wrote some libraries but I don’t think they are maintained. I maintain an SMC library but I don’t know how much use it gets. Tom Nielsen, Henrik Nilsson and I wrote Haskell “bindings” for Stan: > https://nottingham-repository.worktribe.com/output/1151875/getting-more-out-of-stan-some-ideas-from-the-haskell-bindings. It would be a lot of work to e.g. re-create Stan in Haskell natively. > > I am aware of Jared Tobins packages! They are great entry points but not > flexible enough for what I am doing. If you are interested, have a look at the > 'mcmc' package, which I am developing. > > Thank you, I didn't know about the Stan Haskell bindings and will have a look. > > I agree about plotting but inline-r makes it possible to use ggplot in R via Haskell which makes things like drawing maps with reasonable projections relatively straightforward. > > More generally, I think we have a good set of bindings for the ODE solver library SUNDIALS and also for other numeric libraries (e.g. LAPACK and BLAS). The problem we have is not enough hands working on such things. > > I now sadly return to programming in Julia. > > Thanks for you input! > > PS - there is probably more I could say on numerical stuff in Haskell but the above already looks like “stream of consciousness”. > > Dominic Steinitz > dominic at steinitz.org > http://idontgetoutmuch.org > Twitter: @idontgetoutmuch > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From borgauf at gmail.com Wed Sep 15 14:35:35 2021 From: borgauf at gmail.com (Galaxy Being) Date: Wed, 15 Sep 2021 09:35:35 -0500 Subject: [Haskell-cafe] Mixed Fraction data type In-Reply-To: References: Message-ID: Guess I was just wondering what deep lore was behind choosing Word8 for the whole number instead of an Integer. Right, Fraction 5 1 2, but what's up with "mixedBit" and Word8? BTW, how might that constraint numerator < denominator be handled if setting up MIxedFraction for real use? On Tue, Sep 14, 2021 at 11:13 PM Bob Ippolito wrote: > From context it's only used as a more concrete example of a product type > to show how cardinality analysis works. I would infer that the idea is that > this type would use mixedBit for the whole number and there would be a > constraint that numerator < denominator. Fraction 5 1 2 would be the > canonical way to represent 5 1/2 in that scheme. Practically speaking > there's no reason to have the mixedBit field because a pair is enough to > represent any fraction, but if it was simplified this way then the example > would be redundant since there's already an example of a pair type on the > same page. > > > On Tue, Sep 14, 2021 at 8:51 PM Galaxy Being wrote: > >> I'm looking at Sandy Maguire's _Thinking With Types_ and he's talking >> about the cardinality of types. He introduces the product type >> >> data MixedFraction a = Fraction >> { mixedBit :: Word8 >> , numerator :: a >> , denominator :: a >> } >> >> How is this a type for holding mixed fractions such as 5-1/2? >> >> ⨽ >> Lawrence Bottorff >> Grand Marais, MN, USA >> borgauf at gmail.com >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > -- ⨽ Lawrence Bottorff Grand Marais, MN, USA borgauf at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From bob at redivi.com Wed Sep 15 14:42:16 2021 From: bob at redivi.com (Bob Ippolito) Date: Wed, 15 Sep 2021 07:42:16 -0700 Subject: [Haskell-cafe] Mixed Fraction data type In-Reply-To: References: Message-ID: I don't think there's any deep lore, it doesn't really make much sense to specialize the mixedBit but not the numerator and denominator. I think it was just an example to show that the cardinality is 256 * |a| * |a|. With that representation, constraints can only be enforced with a smart constructor. https://wiki.haskell.org/Smart_constructors On Wed, Sep 15, 2021 at 7:35 AM Galaxy Being wrote: > Guess I was just wondering what deep lore was behind choosing Word8 for > the whole number instead of an Integer. Right, Fraction 5 1 2, but what's > up with "mixedBit" and Word8? BTW, how might that constraint numerator < > denominator be handled if setting up MIxedFraction for real use? > > On Tue, Sep 14, 2021 at 11:13 PM Bob Ippolito wrote: > >> From context it's only used as a more concrete example of a product type >> to show how cardinality analysis works. I would infer that the idea is that >> this type would use mixedBit for the whole number and there would be a >> constraint that numerator < denominator. Fraction 5 1 2 would be the >> canonical way to represent 5 1/2 in that scheme. Practically speaking >> there's no reason to have the mixedBit field because a pair is enough to >> represent any fraction, but if it was simplified this way then the example >> would be redundant since there's already an example of a pair type on the >> same page. >> >> >> On Tue, Sep 14, 2021 at 8:51 PM Galaxy Being wrote: >> >>> I'm looking at Sandy Maguire's _Thinking With Types_ and he's talking >>> about the cardinality of types. He introduces the product type >>> >>> data MixedFraction a = Fraction >>> { mixedBit :: Word8 >>> , numerator :: a >>> , denominator :: a >>> } >>> >>> How is this a type for holding mixed fractions such as 5-1/2? >>> >>> ⨽ >>> Lawrence Bottorff >>> Grand Marais, MN, USA >>> borgauf at gmail.com >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> > > -- > ⨽ > Lawrence Bottorff > Grand Marais, MN, USA > borgauf at gmail.com > -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony.d.clayden at gmail.com Thu Sep 16 04:53:55 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Thu, 16 Sep 2021 16:53:55 +1200 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools Message-ID: Hi Michael, oh dear, oh dear, oh dear. The seeds of your confusion are very evident from your message. How to back you out of whatever deep rabbit-hole you've managed to get your head into? > ... Your average reader (already a programmer) would be better served by a comparative approach: Here's how to say something in a couple of other programming languages, here's how to say something roughly equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. No. Just no. Haskell is not "subtly different" to (say) Java in the way that C++ or C# are different. (I'll leave others to judge how subtly different they are.) Haskell is dramatically and fundamentally different. You can't just 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's many tales of woe on StackOverflow. Just No. I really don't know how you could have got any experience with Haskell and say "subtly". I suggest you unlearn everything you think you know about Haskell, and strike out in an entirely different direction. The best approach would be to spend a few days playing with lambda calculus. (That's what I did before tackling Haskell.) > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") Lambda calculus is an excellent place for beginners to start. What could be easier to learn? It's certainly easier than grokking a Turing machine; and much easier than Haskell: less than a handful of primitives yet can compute anything computable. > And since the concepts are seldom described in concrete enough and time-honored programming language terms (by comparison to other programming languages) I'm guessing that the concepts you're talking of simply don't correspond to anything in time-honoured (procedural) programming. Anybody writing about Haskell (including anybody writing the User Guide) assumes a base level of understanding of Haskell. You've clearly veered off the track and haven't yet reached base. Remember the User Guide builds on top of the Language Report. (On the point of 'time-honoured': lambda calculus is almost exactly the same age as Turing machines. The first well-known programming language using lambda-calculus ideas (LISP 1966) is almost exactly the same age as the first OOP language (Simula 1967). Which is the more time-honoured?) You do have a point that the terminology in Haskell is often mysterious > [SPJ said] F# had settled on the term "workflow" instead of "monad", and he felt this was wise. Yes many have yearned for a more warm-and-cuddly term than "monad". But the terminology barrier starts before that. Haskell typeclasses are not 'classes' in any sense recognisable from OOP. There are no objects, no hidden state, no destructive assignment. We might go back to February 1988 when a strawman for what became typeclasses used OVERLOAD/INSTANCE. AntC -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at richarde.dev Thu Sep 16 14:05:19 2021 From: lists at richarde.dev (Richard Eisenberg) Date: Thu, 16 Sep 2021 14:05:19 +0000 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000@us-east-2.amazonses.com> I just want to pipe up and say I'm not comfortable with this response. When I feel this way about writing on a forum, I normally contact the author in private, but I think posting publicly here has its merits. I'm hoping that the long correspondence AntC and I have had -- often with opposing viewpoints but with mutual respect -- with withstand this email. Michael posted here expressing frustration with his experience learning and using Haskell. In my opinion, he has spent too much time reading older papers, written by experts for experts -- which Michael is not. I do not fault Michael for this: these resources are sometimes what appear when searching, and we as a community have done a poor job marshaling our educational resources. (Michael, I just thought of a resource you might find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource attempting to do that marshaling. I am not vouching for it here, per se, but I know others have found it useful.) However, Michael very specifically said that "just learn lambda-calculus" was not helpful for him, and so I think it's unhelpful for someone to respond with "just learn lambda-calculus". There are a number of other statements in the email below which could be seen as belittling -- also not helpful. Instead, I wish that we, as a community, could take posts like Michael's at face value: this is the experience of someone who wants to learn Haskell. While some of the conclusions stated in that post are misunderstandings, it is not the sole fault of the learner for these misunderstandings: instead, we must try to understand what about our community and posted materials induced these misunderstandings, and then seek to improve. Many people in Michael's situation may not have posted at all -- and so this kind of information can be very hard to get. Michael, I have no silver bullet to offer to you to try to help you here. I do tend to agree with AntC that you have developed some misconceptions that are hindering your continued learning. The terminology actively hurts here. (To be fair, the first Haskell standard pre-dates both Java and C++, and so one could argue who got the terms wrong.) For my part, I am trying to help with this situation both by trying to improve error messages, and though my support of the Haskell Foundation's Haskell School initiative (https://github.com/haskellfoundation/HaskellSchool). These will take time to grow, but my hope is that a future person like you will have an easier route in. In the meantime, I implore us to take all expressed experiences as exactly that: the experience of the person writing. And if they say they don't want X, please let's not feed them X. :) Richard > On Sep 16, 2021, at 12:53 AM, Anthony Clayden wrote: > > Hi Michael, oh dear, oh dear, oh dear. > > The seeds of your confusion are very evident from your message. How to back you out of whatever deep rabbit-hole you've managed to get your head into? > > > ... Your average reader (already a programmer) would be better served by a comparative approach: Here's how to say something in a couple of other programming languages, here's how to say something roughly equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > No. Just no. Haskell is not "subtly different" to (say) Java in the way that C++ or C# are different. (I'll leave others to judge how subtly different they are.) > > Haskell is dramatically and fundamentally different. You can't just 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's many tales of woe on StackOverflow. Just No. > > I really don't know how you could have got any experience with Haskell and say "subtly". > > I suggest you unlearn everything you think you know about Haskell, and strike out in an entirely different direction. The best approach would be to spend a few days playing with lambda calculus. (That's what I did before tackling Haskell.) > > > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") > > Lambda calculus is an excellent place for beginners to start. What could be easier to learn? It's certainly easier than grokking a Turing machine; and much easier than Haskell: less than a handful of primitives yet can compute anything computable. > > > And since the concepts are seldom described in concrete enough and time-honored programming language terms (by comparison to other programming languages) > > I'm guessing that the concepts you're talking of simply don't correspond to anything in time-honoured (procedural) programming. Anybody writing about Haskell (including anybody writing the User Guide) assumes a base level of understanding of Haskell. You've clearly veered off the track and haven't yet reached base. Remember the User Guide builds on top of the Language Report. > > (On the point of 'time-honoured': lambda calculus is almost exactly the same age as Turing machines. The first well-known programming language using lambda-calculus ideas (LISP 1966) is almost exactly the same age as the first OOP language (Simula 1967). Which is the more time-honoured?) > > You do have a point that the terminology in Haskell is often mysterious > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", and he felt this was wise. > > Yes many have yearned for a more warm-and-cuddly term than "monad". But the terminology barrier starts before that. > > Haskell typeclasses are not 'classes' in any sense recognisable from OOP. There are no objects, no hidden state, no destructive assignment. We might go back to February 1988 when a strawman for what became typeclasses used OVERLOAD/INSTANCE. > > AntC > > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jeffbrown.the at gmail.com Thu Sep 16 14:34:09 2021 From: jeffbrown.the at gmail.com (Jeffrey Brown) Date: Thu, 16 Sep 2021 09:34:09 -0500 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000@us-east-2.amazonses.com> References: <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000@us-east-2.amazonses.com> Message-ID: I strongly believe the best study strategy is to be unfaithful to any source or subtopic. When I want to learn something, I study whatever aspect of it holds my interest, for only slightly longer than it continues to do so. If I continue to want to learn a topic, but lose interest in a particular source or subtopic, it's important to stop that particular avenue. Otherwise I'll lose motivation for the topic as a whole. The result is that, while I never learn (say) a language completely, I generally learn enough to do whatever I was trying to do. (Sometimes I learn enough to decide it's too hard -- and for cases in which that's bound to happen, the quicker the better.) Almost nobody learns any language completely anyway, and most of those who do could have used their time better. Sacrifice is a superpower. On Thu, Sep 16, 2021 at 9:09 AM Richard Eisenberg wrote: > I just want to pipe up and say I'm not comfortable with this response. > When I feel this way about writing on a forum, I normally contact the > author in private, but I think posting publicly here has its merits. I'm > hoping that the long correspondence AntC and I have had -- often with > opposing viewpoints but with mutual respect -- with withstand this email. > > Michael posted here expressing frustration with his experience learning > and using Haskell. In my opinion, he has spent too much time reading older > papers, written by experts for experts -- which Michael is not. I do not > fault Michael for this: these resources are sometimes what appear when > searching, and we as a community have done a poor job marshaling our > educational resources. (Michael, I just thought of a resource you might > find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource > attempting to do that marshaling. I am not vouching for it here, per se, > but I know others have found it useful.) > > However, Michael very specifically said that "just learn lambda-calculus" > was not helpful for him, and so I think it's unhelpful for someone to > respond with "just learn lambda-calculus". There are a number of other > statements in the email below which could be seen as belittling -- also not > helpful. > > Instead, I wish that we, as a community, could take posts like Michael's > at face value: this is the experience of someone who wants to learn > Haskell. While some of the conclusions stated in that post are > misunderstandings, it is not the sole fault of the learner for these > misunderstandings: instead, we must try to understand what about our > community and posted materials induced these misunderstandings, and then > seek to improve. Many people in Michael's situation may not have posted at > all -- and so this kind of information can be very hard to get. > > Michael, I have no silver bullet to offer to you to try to help you here. > I do tend to agree with AntC that you have developed some misconceptions > that are hindering your continued learning. The terminology actively hurts > here. (To be fair, the first Haskell standard pre-dates both Java and C++, > and so one could argue who got the terms wrong.) For my part, I am trying > to help with this situation both by trying to improve error messages, and > though my support of the Haskell Foundation's Haskell School initiative ( > https://github.com/haskellfoundation/HaskellSchool). These will take time > to grow, but my hope is that a future person like you will have an easier > route in. > > In the meantime, I implore us to take all expressed experiences as exactly > that: the experience of the person writing. And if they say they don't want > X, please let's not feed them X. :) > > Richard > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden > wrote: > > Hi Michael, oh dear, oh dear, oh dear. > > The seeds of your confusion are very evident from your message. How to > back you out of whatever deep rabbit-hole you've managed to get your head > into? > > > ... Your average reader (already a programmer) would be better served > by a comparative approach: Here's how to say something in a couple of > other programming languages, here's how to say something roughly > equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > No. Just no. Haskell is not "subtly different" to (say) Java in the way > that C++ or C# are different. (I'll leave others to judge how subtly > different they are.) > > Haskell is dramatically and fundamentally different. You can't just > 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's > many tales of woe on StackOverflow. Just No. > > I really don't know how you could have got any experience with Haskell and > say "subtly". > > I suggest you unlearn everything you think you know about Haskell, and > strike out in an entirely different direction. The best approach would be > to spend a few days playing with lambda calculus. (That's what I did before > tackling Haskell.) > > > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") > > > Lambda calculus is an excellent place for beginners to start. What could > be easier to learn? It's certainly easier than grokking a Turing machine; > and much easier than Haskell: less than a handful of primitives yet can > compute anything computable. > > > And since the concepts are seldom described in concrete enough and > time-honored programming language terms (by comparison to other > programming languages) > > I'm guessing that the concepts you're talking of simply don't correspond > to anything in time-honoured (procedural) programming. Anybody writing > about Haskell (including anybody writing the User Guide) assumes a base > level of understanding of Haskell. You've clearly veered off the track and > haven't yet reached base. Remember the User Guide builds on top of the > Language Report. > > (On the point of 'time-honoured': lambda calculus is almost exactly the > same age as Turing machines. The first well-known programming language > using lambda-calculus ideas (LISP 1966) is almost exactly the same age as > the first OOP language (Simula 1967). Which is the more time-honoured?) > > You do have a point that the terminology in Haskell is often mysterious > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", and > he felt this was wise. > > Yes many have yearned for a more warm-and-cuddly term than "monad". But > the terminology barrier starts before that. > > Haskell typeclasses are not 'classes' in any sense recognisable from OOP. > There are no objects, no hidden state, no destructive assignment. We might > go back to February 1988 when a strawman for what became typeclasses used > OVERLOAD/INSTANCE. > > AntC > > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- Jeff Brown | Jeffrey Benjamin Brown LinkedIn | Github | Twitter | Facebook | very old Website -------------- next part -------------- An HTML attachment was scrubbed... URL: From guthrie at miu.edu Thu Sep 16 15:28:16 2021 From: guthrie at miu.edu (Gregory Guthrie) Date: Thu, 16 Sep 2021 15:28:16 +0000 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000@us-east-2.amazonses.com> References: <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000@us-east-2.amazonses.com> Message-ID: Educational research and learning theory shows that learning anything new is more effective and longer retained when it is connected to and builds on prior knowledge. People may understand anything new if presented as a completely new set of ideas or principles, but that knowledge is not persistent or long remembered. I personally find Haskell a good example of this. When teaching it one can show incrementally how it is the same in many ways as procedural programming languages. Then how it improves on them with first-class functions, currying, immutability, type abstractions, etc. These are all important ideas that they will also see in other IP languages, just much cleaner and more integrated in Haskell(!). Basic Haskell programs with these features can then be used as a bisis for both appreciating the language features and design and FP in general, and as a stepping stone to more advanced usages. Then introducing Functors, Monads, .... Are again an easy and well motivated step for improving on their existing IP experience, and show both nice abstractions and ideas, and a nice implementation and results. All of this connects to and builds on what they already know. Moving into all of the fancier type system features and pragmas, one enters into a realm where Haskell programs are no longer simple enough to easily read as they incorporate several levels of new abstractions and syntax. But at least students have a good basis for further exploration, and an appreciation of FP and Haskell. :-) From: Haskell-Cafe On Behalf Of Richard Eisenberg Sent: Thursday, September 16, 2021 10:05 AM To: Anthony Clayden Cc: haskell-cafe at haskell.org Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools I just want to pipe up and say I'm not comfortable with this response. When I feel this way about writing on a forum, I normally contact the author in private, but I think posting publicly here has its merits. I'm hoping that the long correspondence AntC and I have had -- often with opposing viewpoints but with mutual respect -- with withstand this email. Michael posted here expressing frustration with his experience learning and using Haskell. In my opinion, he has spent too much time reading older papers, written by experts for experts -- which Michael is not. I do not fault Michael for this: these resources are sometimes what appear when searching, and we as a community have done a poor job marshaling our educational resources. (Michael, I just thought of a resource you might find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource attempting to do that marshaling. I am not vouching for it here, per se, but I know others have found it useful.) However, Michael very specifically said that "just learn lambda-calculus" was not helpful for him, and so I think it's unhelpful for someone to respond with "just learn lambda-calculus". There are a number of other statements in the email below which could be seen as belittling -- also not helpful. Instead, I wish that we, as a community, could take posts like Michael's at face value: this is the experience of someone who wants to learn Haskell. While some of the conclusions stated in that post are misunderstandings, it is not the sole fault of the learner for these misunderstandings: instead, we must try to understand what about our community and posted materials induced these misunderstandings, and then seek to improve. Many people in Michael's situation may not have posted at all -- and so this kind of information can be very hard to get. Michael, I have no silver bullet to offer to you to try to help you here. I do tend to agree with AntC that you have developed some misconceptions that are hindering your continued learning. The terminology actively hurts here. (To be fair, the first Haskell standard pre-dates both Java and C++, and so one could argue who got the terms wrong.) For my part, I am trying to help with this situation both by trying to improve error messages, and though my support of the Haskell Foundation's Haskell School initiative (https://github.com/haskellfoundation/HaskellSchool). These will take time to grow, but my hope is that a future person like you will have an easier route in. In the meantime, I implore us to take all expressed experiences as exactly that: the experience of the person writing. And if they say they don't want X, please let's not feed them X. :) Richard On Sep 16, 2021, at 12:53 AM, Anthony Clayden > wrote: Hi Michael, oh dear, oh dear, oh dear. The seeds of your confusion are very evident from your message. How to back you out of whatever deep rabbit-hole you've managed to get your head into? > ... Your average reader (already a programmer) would be better served by a comparative approach: Here's how to say something in a couple of other programming languages, here's how to say something roughly equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. No. Just no. Haskell is not "subtly different" to (say) Java in the way that C++ or C# are different. (I'll leave others to judge how subtly different they are.) Haskell is dramatically and fundamentally different. You can't just 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's many tales of woe on StackOverflow. Just No. I really don't know how you could have got any experience with Haskell and say "subtly". I suggest you unlearn everything you think you know about Haskell, and strike out in an entirely different direction. The best approach would be to spend a few days playing with lambda calculus. (That's what I did before tackling Haskell.) > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") Lambda calculus is an excellent place for beginners to start. What could be easier to learn? It's certainly easier than grokking a Turing machine; and much easier than Haskell: less than a handful of primitives yet can compute anything computable. > And since the concepts are seldom described in concrete enough and time-honored programming language terms (by comparison to other programming languages) I'm guessing that the concepts you're talking of simply don't correspond to anything in time-honoured (procedural) programming. Anybody writing about Haskell (including anybody writing the User Guide) assumes a base level of understanding of Haskell. You've clearly veered off the track and haven't yet reached base. Remember the User Guide builds on top of the Language Report. (On the point of 'time-honoured': lambda calculus is almost exactly the same age as Turing machines. The first well-known programming language using lambda-calculus ideas (LISP 1966) is almost exactly the same age as the first OOP language (Simula 1967). Which is the more time-honoured?) You do have a point that the terminology in Haskell is often mysterious > [SPJ said] F# had settled on the term "workflow" instead of "monad", and he felt this was wise. Yes many have yearned for a more warm-and-cuddly term than "monad". But the terminology barrier starts before that. Haskell typeclasses are not 'classes' in any sense recognisable from OOP. There are no objects, no hidden state, no destructive assignment. We might go back to February 1988 when a strawman for what became typeclasses used OVERLOAD/INSTANCE. AntC _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From carter.schonwald at gmail.com Thu Sep 16 18:21:58 2021 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Thu, 16 Sep 2021 14:21:58 -0400 Subject: [Haskell-cafe] Bundle patterns with type aliases In-Reply-To: References: <0EC9C321-12FF-405B-B9BC-10E8DE9D165E@gmail.com> Message-ID: These are great ideas! Could you please create a ghc tracker ticket with a tiny examples or two? There may be specific technical reasons we might not be able to do so for type synonyms in ghc, but I don’t see any obvious barriers in the case of David’s excellent idea, I’ve def seen lots of great code out there where you’d really want either associated pattern synonyms or to bundle pattern synonyms with the exported public interface for a type class. I’m sure there’s some devil in the details but these sound lovely. Step -1 is making up 1-2 toy examples and explaining what and why you want it on a ghc ticket! On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > I would like that, along with the ability to bundle patterns with classes. > > On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > >> Is there currently a way to 'bundle' a pattern with a type alias? And if >> not, could that capability be added to the PatternSynonyms GHC extension? >> (Is this the right place to ask, or should I be asking a GHC list?) >> >> --Keith >> Sent from my phone with K-9 Mail. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Sep 16 19:08:45 2021 From: david.feuer at gmail.com (David Feuer) Date: Thu, 16 Sep 2021 15:08:45 -0400 Subject: [Haskell-cafe] Bundle patterns with type aliases In-Reply-To: References: <0EC9C321-12FF-405B-B9BC-10E8DE9D165E@gmail.com> Message-ID: Here's an example: pattern State :: (s -> (a, s)) -> State s a pattern State f <- (coerce . runStateT -> f) where State = state This would be very nice to bundle with the State type synonym. On Thu, Sep 16, 2021, 2:22 PM Carter Schonwald wrote: > These are great ideas! Could you please create a ghc tracker ticket with a > tiny examples or two? > > There may be specific technical reasons we might not be able to do so for > type synonyms in ghc, but I don’t see any obvious barriers in the case of > David’s excellent idea, I’ve def seen lots of great code out there where > you’d really want either associated pattern synonyms or to bundle pattern > synonyms with the exported public interface for a type class. > > I’m sure there’s some devil in the details but these sound lovely. Step > -1 is making up 1-2 toy examples and explaining what and why you want it on > a ghc ticket! > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > >> I would like that, along with the ability to bundle patterns with classes. >> >> On Wed, Sep 8, 2021, 1:13 PM Keith wrote: >> >>> Is there currently a way to 'bundle' a pattern with a type alias? And if >>> not, could that capability be added to the PatternSynonyms GHC extension? >>> (Is this the right place to ask, or should I be asking a GHC list?) >>> >>> --Keith >>> Sent from my phone with K-9 Mail. >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Thu Sep 16 19:12:57 2021 From: david.feuer at gmail.com (David Feuer) Date: Thu, 16 Sep 2021 15:12:57 -0400 Subject: [Haskell-cafe] Bundle patterns with type aliases In-Reply-To: References: <0EC9C321-12FF-405B-B9BC-10E8DE9D165E@gmail.com> Message-ID: Here's a class example: class (MFoldable t, Monoid t) => Sequence t where singleton :: Elem t -> t .... One might wish to write pattern synonyms for viewing the ends of a sequence, like the ones in Data.Sequence, and bundle them with this class. On Thu, Sep 16, 2021, 2:22 PM Carter Schonwald wrote: > These are great ideas! Could you please create a ghc tracker ticket with a > tiny examples or two? > > There may be specific technical reasons we might not be able to do so for > type synonyms in ghc, but I don’t see any obvious barriers in the case of > David’s excellent idea, I’ve def seen lots of great code out there where > you’d really want either associated pattern synonyms or to bundle pattern > synonyms with the exported public interface for a type class. > > I’m sure there’s some devil in the details but these sound lovely. Step > -1 is making up 1-2 toy examples and explaining what and why you want it on > a ghc ticket! > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > >> I would like that, along with the ability to bundle patterns with classes. >> >> On Wed, Sep 8, 2021, 1:13 PM Keith wrote: >> >>> Is there currently a way to 'bundle' a pattern with a type alias? And if >>> not, could that capability be added to the PatternSynonyms GHC extension? >>> (Is this the right place to ask, or should I be asking a GHC list?) >>> >>> --Keith >>> Sent from my phone with K-9 Mail. >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Thu Sep 16 20:52:22 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Thu, 16 Sep 2021 16:52:22 -0400 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > The real problem is that the writing sucks. Not all of it -- and some > contributors to the community are stellar writers, even if, in the > snarkish commentary they write about Haskell and the community, I > don't quite get all the jokes. But speaking as a contributor to the > Haskell.org wiki -- to which I contribute at times out of hope that > clarifying points I understand will also lead to more clarity for > myself -- I have to say it: the writing sucks. Can you be a bit more specific about which sort of writing you find sufficiently unsatisfactory to say "the writing sucks"? * Books about Haskell - Introductory (e.g. http://learnyouahaskell.com/) - Comprehensive (e.g. the classic Real World Haskell) - Topic focused (e.g. the IMHO rather excellent Parallel and Concurrent Haskell) - Theory focused (e.g. https://bartoszmilewski.com/category/category-theory/) - ... * The library reference documentation? * The GHC User's Guide? * The Haskell report? * Blog posts? * The Haskell Wiki? * r/haskell? * Haskell mailing lists? ... * All of the above??? I am also curious whether I'm part of the solution or part of the precipitate. I've recently contributed new documentation for Data.Foldable and Data.Traversable: https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 are these a step in the right direction, or examples of more writing that sucks? These are reference documentation, not beginner tutorials, so a more detailed write up of the concepts, pitfalls, ... things to keep in mind when using library, ... More of that sort of thing would help me to more quickly learn to use some of the libraries that lack this sort of overview prose, but perhaps what you're looking for is something else? -- Viktor. From david.feuer at gmail.com Thu Sep 16 20:57:28 2021 From: david.feuer at gmail.com (David Feuer) Date: Thu, 16 Sep 2021 16:57:28 -0400 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: I am not a fan of how the new Traversable documentation buries the actual laws. On Thu, Sep 16, 2021, 4:55 PM Viktor Dukhovni wrote: > On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > > > The real problem is that the writing sucks. Not all of it -- and some > > contributors to the community are stellar writers, even if, in the > > snarkish commentary they write about Haskell and the community, I > > don't quite get all the jokes. But speaking as a contributor to the > > Haskell.org wiki -- to which I contribute at times out of hope that > > clarifying points I understand will also lead to more clarity for > > myself -- I have to say it: the writing sucks. > > Can you be a bit more specific about which sort of writing you find > sufficiently unsatisfactory to say "the writing sucks"? > > * Books about Haskell > - Introductory (e.g. http://learnyouahaskell.com/) > - Comprehensive (e.g. the classic Real World Haskell) > - Topic focused (e.g. the IMHO rather excellent Parallel and > Concurrent Haskell) > - Theory focused (e.g. > https://bartoszmilewski.com/category/category-theory/) > - ... > * The library reference documentation? > * The GHC User's Guide? > * The Haskell report? > * Blog posts? > * The Haskell Wiki? > * r/haskell? > * Haskell mailing lists? > ... > * All of the above??? > > I am also curious whether I'm part of the solution or part of the > precipitate. I've recently contributed new documentation for > Data.Foldable and Data.Traversable: > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > are these a step in the right direction, or examples of more writing > that sucks? These are reference documentation, not beginner tutorials, > so a more detailed write up of the concepts, pitfalls, ... things to > keep in mind when using library, ... > > More of that sort of thing would help me to more quickly learn to use > some of the libraries that lack this sort of overview prose, but perhaps > what you're looking for is something else? > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Thu Sep 16 22:43:31 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Thu, 16 Sep 2021 18:43:31 -0400 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: On Thu, Sep 16, 2021 at 04:57:28PM -0400, David Feuer wrote: > I am not a fan of how the new Traversable documentation buries the > actual laws. The laws are one click away from the table of contents, and IMHO not particularly illuminating other than for advanced readers. For example, in Data.Foldable they are: foldr f z t = appEndo (foldMap (Endo . f) t ) z foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z fold = foldMap id length = getSum . foldMap (Sum . const 1) is someone new to Data.Foldable really going to learn something from these before they've deeply understood the background concepts? My take is that the laws should almost always be "buried" (one click away) at the end of the module documentation. Those who care and need them can find them, but I think they just intimidate the less experienced readers. Putting the laws first likely only discourages beginners. -- Viktor. From david.feuer at gmail.com Thu Sep 16 22:51:42 2021 From: david.feuer at gmail.com (David Feuer) Date: Thu, 16 Sep 2021 18:51:42 -0400 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: The last time I went to look at the laws it took me a couple minutes to find them. I use them to write instances. Pretty important, IMO. On Thu, Sep 16, 2021, 6:46 PM Viktor Dukhovni wrote: > On Thu, Sep 16, 2021 at 04:57:28PM -0400, David Feuer wrote: > > > I am not a fan of how the new Traversable documentation buries the > > actual laws. > > The laws are one click away from the table of contents, and IMHO not > particularly illuminating other than for advanced readers. > > For example, in Data.Foldable they are: > > foldr f z t = appEndo (foldMap (Endo . f) t ) z > foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z > fold = foldMap id > length = getSum . foldMap (Sum . const 1) > > is someone new to Data.Foldable really going to learn something from > these before they've deeply understood the background concepts? > > My take is that the laws should almost always be "buried" (one click > away) at the end of the module documentation. Those who care and need > them can find them, but I think they just intimidate the less > experienced readers. Putting the laws first likely only discourages > beginners. > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony.d.clayden at gmail.com Thu Sep 16 23:32:04 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Fri, 17 Sep 2021 11:32:04 +1200 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000@us-east-2.amazonses.com> References: <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000@us-east-2.amazonses.com> Message-ID: Thank you Richard, I'm quite comfortable with discussing in public whether my response was appropriate. Michael might as well observe early that there's a broad range of views as to how best to learn Haskell. (And every reason that what works for some doesn't work for others.) I was sharing my experience. I was also drawing on observations of q's on StackOverflow, for which there's an alarming number who think Haskell is just C/C++ spelled funny. (Take the very first [Haskell] q right now.) Learning by 'mentally executing' programs is a workable approach -- but not if your mental model of execution is a Turing machine. And I was observing Michael's actual q on the Beginners list. It's clear to me: * He's trying to translate Haskell to C/C++. * He thinks Lambda calculus is 'advanced'/complicated/beyond a beginner. * He hasn't tried Lambda calculus/he didn't say it "wasn't helpful for him". * He thinks that already knowing a swag of procedural/OOP languages will help with learning Haskell. I'd say all of those are unhelpful blocks to learning. Perhaps in my personal 'learning journey' it helped that I was profoundly dissatisfied with procedural languages (of which I'd worked in over a dozen); and that I fell across Backus' 'Can Programming be liberated ...?', then Lambda calculus, before I landed on an actual implementation of those ideas in Haskell. And for sure, my learning approach left me with some misconceptions, that Richard and others have patiently untangled. AntC On Fri, 17 Sept 2021 at 02:05, Richard Eisenberg wrote: > I just want to pipe up and say I'm not comfortable with this response. > When I feel this way about writing on a forum, I normally contact the > author in private, but I think posting publicly here has its merits. I'm > hoping that the long correspondence AntC and I have had -- often with > opposing viewpoints but with mutual respect -- with withstand this email. > > Michael posted here expressing frustration with his experience learning > and using Haskell. In my opinion, he has spent too much time reading older > papers, written by experts for experts -- which Michael is not. I do not > fault Michael for this: these resources are sometimes what appear when > searching, and we as a community have done a poor job marshaling our > educational resources. (Michael, I just thought of a resource you might > find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource > attempting to do that marshaling. I am not vouching for it here, per se, > but I know others have found it useful.) > > However, Michael very specifically said that "just learn lambda-calculus" > was not helpful for him, and so I think it's unhelpful for someone to > respond with "just learn lambda-calculus". There are a number of other > statements in the email below which could be seen as belittling -- also not > helpful. > > ... > > In the meantime, I implore us to take all expressed experiences as exactly > that: the experience of the person writing. And if they say they don't want > X, please let's not feed them X. :) > > Richard > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden > wrote: > > Hi Michael, oh dear, oh dear, oh dear. > > The seeds of your confusion are very evident from your message. How to > back you out of whatever deep rabbit-hole you've managed to get your head > into? > > > ... Your average reader (already a programmer) would be better served > by a comparative approach: Here's how to say something in a couple of > other programming languages, here's how to say something roughly > equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > No. Just no. Haskell is not "subtly different" to (say) Java in the way > that C++ or C# are different. (I'll leave others to judge how subtly > different they are.) > > Haskell is dramatically and fundamentally different. You can't just > 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's > many tales of woe on StackOverflow. Just No. > > I really don't know how you could have got any experience with Haskell and > say "subtly". > > I suggest you unlearn everything you think you know about Haskell, and > strike out in an entirely different direction. The best approach would be > to spend a few days playing with lambda calculus. (That's what I did before > tackling Haskell.) > ... > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Thu Sep 16 23:43:07 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Thu, 16 Sep 2021 19:43:07 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? Message-ID: On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > The last time I went to look at the laws it took me a couple minutes to > find them. I use them to write instances. Pretty important, IMO. I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances. If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module. Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so). Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum... -- Viktor. From anthony.d.clayden at gmail.com Fri Sep 17 00:37:17 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Fri, 17 Sep 2021 12:37:17 +1200 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? Message-ID: Hi Viktor, really this is a quite different q than the thread talking about a learner's experience. You're writing deeply-technical detail not at all aimed at beginners. There's a very broad range of reasons and prior knowledge for readers of Library docos. But I disagree with this: > The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances. I'll want to write an instance of Foldable as soon as I've declared my datatype, won't I? Or do you expect me to be folding only over Lists? Speaking for myself, if I want to understand a function, I look first at its type then its source definition. The Laws for the particular Foldable example I don't understand at all. I'd say: hide those Laws as far away as possible. In fact, since the blasted FTP re-organisation of that library, I've more or less given up. Too hard/too abstract/too much Category Theory. What's an `Endo`? Thank you for your efforts to document. I expect there's someone you're helping. Not me. I don't think it's that the style "sucks". This style and content is enough for me: https://www.haskell.org/hugs/pages/libraries/base/Data-Foldable.html > Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum... I've gone well beyond the point of being intimidated by Category Theorists. I find they're doing a splendid job of putting people off getting to love Haskell as I used to. If you want to tell me off for speaking out of turn, go ahead. (But this forum is the cafe, perhaps this particular discussion should be on glasgow-haskell-users?) AntC On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: >* The last time I went to look at the laws it took me a couple minutes to *>* find them. I use them to write instances. Pretty important, IMO. * I agree the laws are important to document, I just don't think they belong at the top of the module. The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances. If more modules adopt something like the style of the new Data.Foldable, experienced users will know to look for the laws at the end, if not still present at the top of the module. Of course perhaps the community would prefer the original Laws first format, I'm fine with that emerging as the consensus. Perhaps worthy of a separate thread (made it so). Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum... -- -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Fri Sep 17 01:10:58 2021 From: cdsmith at gmail.com (Chris Smith) Date: Thu, 16 Sep 2021 21:10:58 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: For what it's worth, I agree with you both that it's important to document the laws, and that it's not the most friendly way to begin the documentation for a reader who is unfamiliar with the concept. It's not clear to me whether the documentation ought to be optimized for readers who are or aren't familiar with the concept, but I lean to the latter, which means putting the type class laws at the end (but still easily accessible) makes sense to me. On Thu, Sep 16, 2021 at 7:47 PM Viktor Dukhovni wrote: > On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > > > The last time I went to look at the laws it took me a couple minutes to > > find them. I use them to write instances. Pretty important, IMO. > > I agree the laws are important to document, I just don't think they > belong at the top of the module. The beginner to intermediate users > will be using the library and existing instances for some time before > they start to write their own instances. > > If more modules adopt something like the style of the new Data.Foldable, > experienced users will know to look for the laws at the end, if not > still present at the top of the module. > > Of course perhaps the community would prefer the original Laws first > format, I'm fine with that emerging as the consensus. Perhaps worthy > of a separate thread (made it so). > > Of course the conjectured users who might most benefit from not being > intimidated by being exposed to laws before they're ready to understand > them might not be present on this forum... > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Fri Sep 17 01:14:19 2021 From: david.feuer at gmail.com (David Feuer) Date: Thu, 16 Sep 2021 21:14:19 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: I'm not talking about whether they're first or last. They're currently not part of the class documentation *at all*. They're only in the Data.Traversable documentation. On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni wrote: > On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > > > The last time I went to look at the laws it took me a couple minutes to > > find them. I use them to write instances. Pretty important, IMO. > > I agree the laws are important to document, I just don't think they > belong at the top of the module. The beginner to intermediate users > will be using the library and existing instances for some time before > they start to write their own instances. > > If more modules adopt something like the style of the new Data.Foldable, > experienced users will know to look for the laws at the end, if not > still present at the top of the module. > > Of course perhaps the community would prefer the original Laws first > format, I'm fine with that emerging as the consensus. Perhaps worthy > of a separate thread (made it so). > > Of course the conjectured users who might most benefit from not being > intimidated by being exposed to laws before they're ready to understand > them might not be present on this forum... > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Fri Sep 17 01:25:17 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Thu, 16 Sep 2021 21:25:17 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: On Thu, Sep 16, 2021 at 09:14:19PM -0400, David Feuer wrote: > I'm not talking about whether they're first or last. They're currently not > part of the class documentation *at all*. They're only in the > Data.Traversable documentation. I see, I think you're noting that when re-exported from Prelude, the class definitions of Foldable and Traversable that appear in the Prelude module: https://hackage.haskell.org/package/base-4.15.0.0/docs/Prelude.html#g:11 no longer include the laws, you have to look at the underlying module to find them. If that's the issue, I should note that the re-exported class definitions do have overview hyperlinks: A more detailed description can be found in the overview section of [Data.Foldable](https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Foldable.html#overview) A more detailed description can be found in the overview section of [Data.Traversable](https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Traversable.html#overview) Would your issue be addressed if links to the laws were similarly linked from the class definitions? -- Viktor. From anthony.d.clayden at gmail.com Fri Sep 17 01:26:48 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Fri, 17 Sep 2021 13:26:48 +1200 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? Message-ID: Hi David, The Foldable Laws are here https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:21 In the Data-Foldable doco. (There's a menu entry on the sidebar, or text search.) The Data-Traversable doco has only the Traversable Laws. > I'm not talking about whether they're first or last. They're currently not part of the class documentation *at all*. They're only in the Data.Traversable documentation. -------------- next part -------------- An HTML attachment was scrubbed... URL: From cdsmith at gmail.com Fri Sep 17 01:32:29 2021 From: cdsmith at gmail.com (Chris Smith) Date: Thu, 16 Sep 2021 21:32:29 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: Ah, I misunderstood you as well. I agree that the laws should be included in the type class documentation. In fact, most of the documentation from the link should probably be moved into the documentation for the class, rather than a stand-alone section. On Thu, Sep 16, 2021 at 9:15 PM David Feuer wrote: > I'm not talking about whether they're first or last. They're currently not > part of the class documentation *at all*. They're only in the > Data.Traversable documentation. > > On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni > wrote: > >> On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: >> >> > The last time I went to look at the laws it took me a couple minutes to >> > find them. I use them to write instances. Pretty important, IMO. >> >> I agree the laws are important to document, I just don't think they >> belong at the top of the module. The beginner to intermediate users >> will be using the library and existing instances for some time before >> they start to write their own instances. >> >> If more modules adopt something like the style of the new Data.Foldable, >> experienced users will know to look for the laws at the end, if not >> still present at the top of the module. >> >> Of course perhaps the community would prefer the original Laws first >> format, I'm fine with that emerging as the consensus. Perhaps worthy >> of a separate thread (made it so). >> >> Of course the conjectured users who might most benefit from not being >> intimidated by being exposed to laws before they're ready to understand >> them might not be present on this forum... >> >> -- >> Viktor. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Fri Sep 17 01:33:02 2021 From: david.feuer at gmail.com (David Feuer) Date: Thu, 16 Sep 2021 21:33:02 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: The laws of any sensible class are an essential and integral part of it. Without them, you just have ad hoc overloading. They shouldn't be relegated to the canonical exporting module. On Thu, Sep 16, 2021, 9:27 PM Viktor Dukhovni wrote: > On Thu, Sep 16, 2021 at 09:14:19PM -0400, David Feuer wrote: > > > I'm not talking about whether they're first or last. They're currently > not > > part of the class documentation *at all*. They're only in the > > Data.Traversable documentation. > > I see, I think you're noting that when re-exported from Prelude, the > class definitions of Foldable and Traversable that appear in the > Prelude module: > > > https://hackage.haskell.org/package/base-4.15.0.0/docs/Prelude.html#g:11 > > no longer include the laws, you have to look at the underlying module > to find them. If that's the issue, I should note that the re-exported > class definitions do have overview hyperlinks: > > A more detailed description can be found in the overview section of > [Data.Foldable]( > https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Foldable.html#overview > ) > > A more detailed description can be found in the overview section of > [Data.Traversable]( > https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Traversable.html#overview > ) > > Would your issue be addressed if links to the laws were similarly linked > from the class definitions? > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Fri Sep 17 01:56:37 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Thu, 16 Sep 2021 21:56:37 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: > On 16 Sep 2021, at 9:33 pm, David Feuer wrote: > > The laws of any sensible class are an essential and integral part of it. Without them, you just have ad hoc overloading. They shouldn't be relegated to the canonical exporting module. Surely a one click link from the Prelude re-export is no worse than a 1-click link in the module table of contents? I am rather reluctant beat new readers over the head with laws that often are much too abstract to add clarity. -- Viktor. From sjcjoosten+haskell at gmail.com Fri Sep 17 02:13:27 2021 From: sjcjoosten+haskell at gmail.com (Sebastiaan Joosten) Date: Thu, 16 Sep 2021 22:13:27 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: I personally like it if the documentation of re-exported classes just contain a summary, much like Data.Foldable does. The prelude documentation is quite long already. I would not object to making the links stand out a bit more though: a title 'More detailed descriptions' with a bulleted summary to 'laws' might do that. On where the laws need to be: I think for foldable the right decision is made, there may be exceptions but I typically like to hear about the ideas behind things before I dive into the algebraic characterization. Also, many thanks to the write-up of Foldable. Best, Sebastiaan On Thu, Sep 16, 2021 at 9:36 PM Chris Smith wrote: > Ah, I misunderstood you as well. I agree that the laws should be included > in the type class documentation. In fact, most of the documentation from > the link should probably be moved into the documentation for the class, > rather than a stand-alone section. > > On Thu, Sep 16, 2021 at 9:15 PM David Feuer wrote: > >> I'm not talking about whether they're first or last. They're currently >> not part of the class documentation *at all*. They're only in the >> Data.Traversable documentation. >> >> On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni >> wrote: >> >>> On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: >>> >>> > The last time I went to look at the laws it took me a couple minutes to >>> > find them. I use them to write instances. Pretty important, IMO. >>> >>> I agree the laws are important to document, I just don't think they >>> belong at the top of the module. The beginner to intermediate users >>> will be using the library and existing instances for some time before >>> they start to write their own instances. >>> >>> If more modules adopt something like the style of the new Data.Foldable, >>> experienced users will know to look for the laws at the end, if not >>> still present at the top of the module. >>> >>> Of course perhaps the community would prefer the original Laws first >>> format, I'm fine with that emerging as the consensus. Perhaps worthy >>> of a separate thread (made it so). >>> >>> Of course the conjectured users who might most benefit from not being >>> intimidated by being exposed to laws before they're ready to understand >>> them might not be present on this forum... >>> >>> -- >>> Viktor. >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael.eugene.turner at gmail.com Fri Sep 17 02:27:12 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Fri, 17 Sep 2021 11:27:12 +0900 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: On Fri, Sep 17, 2021 at 5:52 AM Viktor Dukhovni wrote: > > On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > > > The real problem is that the writing sucks. [snip] Vikor: > Can you be a bit more specific about which sort of writing you find > sufficiently unsatisfactory to say "the writing sucks"? It's an axiom of sales: quality is what the customer says it is. You'll evaluate writing differently depending on what sort of audience you're in. I'm in this audience: -- I have a lot of programming experience with a variety of languages. I have limited patience with writing that feels like it's talking down to me. -- I have limited patience for a language whose main appeal seems to be to a niche audience of programmers who want to learn a language in part because they've been told it's a challenge -- I'm not seeking status among other programmers. ("Ooh, he knows Haskell. You have to be really smart to write Haskell.") -- I prefer a presentation that's clear and concise, with a significant reliance on diagrams that show conceptual relations. A picture of how something works is worth a thousand words that tell me how great something was, or how great it's going to be once I'm proficient. > > * Books about Haskell > - Introductory (e.g. http://learnyouahaskell.com/) I started here. I was initially drawn in by the welcoming chattiness. It got old, fast. Fonzie? Really? How many young programmers today even know the TV series Happy Days? Waste of page-space. (But see above -- that's MY reaction. Audiences will differ.) > - Comprehensive (e.g. the classic Real World Haskell) I hadn't looked at this before. So I looked today. Uh-oh: the introductory part reminds me of that old joke about the IBM salesman, back in the mainframe days, when getting a computer up and running the customer's application could take months, from hardware order to production data processing: The salesman sits on the edge of the bed on his honeymoon night, telling his bride out great it's going to be. The first bit of code shows how you'd write a very short function (courtesy of "take", not of any inherent feature of Haskell's programming model) to get the k least elements in a list. A claim is made: it's faster because of laziness. Um, really? Sorting is O(n log n) upper bound no matter what. There's a vaguely game-theoretic proof of this I found delightful back in college, and it came to mind when I read that. How would you arrange numbers in a list so that, no matter what sort algorithm you used, there would be no way in general to get the k smallest elements without a full sort? Well, maybe the authors mean "faster on average, counting using the number of comparisons"? Oh, but wait: isn't there some overhead for implementing laziness? Hm, why aren't they saying something here? My eyes glaze over all the IBM salesman honeymoon bridal suite talk, so I go to chapter one. I skip through all the stuff I already know, and at the end of the chapter, there's bit of code: count the number of lines in input. After months of looking at Haskell code (but a few weeks of not looking at it) I can't quite get it, the way I'd almost instantly get it if it was written in a more conventional programming language. It's just an exercise in putting some code in a file and running it. Supposedly it will build confidence. It has the opposite effect on me. But maybe it's explicated in the next chapter? I turn to chapter two, hoping that the line-counter would be explicated. Oh no: long IBM honeymoon-night salesman talk about Why Types Are Good. Oh, fuck you! I already know why types are good! I even know what's bad about the otherwise-good type systems of several programming languages! WHY ARE YOU WASTING MY TIME?! > - Topic focused (e.g. the IMHO rather excellent Parallel and > Concurrent Haskell) It may be excellent if you're already up to speed on Haskell. I'm a newbie drowning in writing that's not for me. > - Theory focused (e.g. > https://bartoszmilewski.com/category/category-theory/) I bailed halfway through a video from Philip Wadler, a talk about Categories for the Working Hacker (or something) because he still hadn't said anything about how knowing category theory was useful to, uh, you know, a working hacker? I ran across a blog that said: forget category theory. It won't help you. At least not starting out. > * The library reference documentation? Pretty impenetrable for a newbie, though that's hardly unusual for a newbie to any language, with reference docs. > * The GHC User's Guide? Been a while since I looked at it, but not much easier, as I remember. > * The Haskell report? Haven't read it. > * Blog posts? So far, only helpful when they are honest and tell me that I'm having trouble for some very good reasons. I feel less alone. I feel less stupid. > * The Haskell Wiki? Very sloppy, much neglected. I put in some improvements to articles, but a certain syndrome is very much in evidence: it seems mostly written by Haskell experts who can't seem to get back into a newbie mindset (and who maybe never had a mindset like mine), and who often jump from IBM honeymoon salesman talk straight into unnecessarily complex examples. > * r/haskell? Sometimes helpful. > * Haskell mailing lists? When you're being told curtly, "Learn lambda calculus", or someone can't answer your question about something but instead of saying "I don't know where you'd find that", gives you an answer to a question you didn't ask, you're not on a truly beginner-friendly newbies list. Other mailing lists take up topics that feel way over my head at this point. > * All of the above??? So far, pretty much. > I am also curious whether I'm part of the solution or part of the > precipitate. I've recently contributed new documentation for > Data.Foldable and Data.Traversable: > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 OK: "Merging the contribution of the current element with an accumulator value from a partial result is performed by an operator function, either explicitly provided by the caller as in foldr, implicit count as in length, or partly implicit as in foldMap (where each element is mapped into a Monoid, and the monoid's mappend operator performs the merge)." Let me tell you how I tried to read that lo-o-ong sentence. "Merging the contribution of the current element--" Um, you didn't introduce "current element", so "the current element" is confusing. It feels like you're starting in the middle. And wait, is the current element being merged, or is some kind of contribution /from/ the current element being merged? I guess since Haskell is lazy, it could be the latter . . . "--with an accumulator value--" Coming from Erlang, I just call them "accumulators". So is an accumulator value different from an accumulator or . . . what? "--from a partial result--" So, it's a partial result in the form of the accumulator? Or "the contribution of the current element"? I kinda-sorta feels like it must be the accumulator, so, plunging onward . . . "--is performed by an operator function" Uh-oh: passive voice sentence construction. And "operator function" is . . . well, all operators are functions in Haskell, so it's performed by an operator, but-- I could go on for a while, but let it suffice to say, long before I'm halfway through this sentence, the cognitive load is starting to crush me. How many times will I have to read it to understand it? Well, I probably won't understand it with multiple readings. Because there I see "monoid" toward the end (no hyperlink), and again, that feeling: Haskell may be very powerful indeed, but a lot of the writing makes me want to kill somebody. (Don't worry. I don't kill people.) Now, remember what I said about target audiences? I can imagine a reader who would actually admire that sentence. But that reader is someone who has used foldr and foldr a lot, who has a pretty adequate mental model already, and thinks: "Good. It summarizes all my knowledge, while refreshing me on a point that hasn't mattered much in my coding so far." The sentence may contain a few unnecessary words, but for such a reader, these are like drops of water rolling off a duck's back. It might read more smoothly with a few added words, but this reader is mentally inserting such smoothing linkages in his internal conceptual schema, probably without even subvocalizing those words. Still, there might be a way to break it up and with not many added words, satisfy more readers. Do you want to do that? Do you need to do that? Let me tell you something, either way: it'll probably be harder for you than writing the sentence you wrote. This is an interesting point illustrated in a different field, by Paul Krugman, a few years after he started writing about economics for layman-reader outlets like Salon: It was actually harder for him to write the same number of words for a layman, on a given topic, than it was for him to write a journal article to pass peer review. He had to think: "What might my readers NOT quite understand yet? How can I get them there quickly?" As an economist, he could think in graphs and equations. And he could easily say things like "there could be labor-activism-related variations in how downward-sticky wages become in a liquidity trap." If he said that to your average economist, he could count on being understood. It was actually harder for him to write something more generally accessible, like, "When consumers have snapped their purses shut in a recession and during the slow recovery, most bosses will prefer to lay workers off to cut costs, rather than cut wages to keep workers on payroll. However, others may not. It could depend on how much that boss fears that the workers would go out on strike in response to a pay cut." It was harder for him than for me (I'm not an economist) because first he had to realize: if I say it in the way that's most obvious to me, most people won't get it. > are these a step in the right direction, or examples of more writing > that sucks? These are reference documentation, not beginner tutorials, > so a more detailed write up of the concepts, pitfalls, ... things to > keep in mind when using library, ... As I say, for a certain kind of reader, that sentence that I only stumble around in may be fine for your audience. But Haskell has apparently plateaued, after surviving a phase where, as Simon Peyton-Jones points out, almost all new languages die. So it's a question of what you want to be a part of: a relatively insular community? Or a drive to expand the community, by making learning easier? > More of that sort of thing would help me to more quickly learn to use > some of the libraries that lack this sort of overview prose, but perhaps > what you're looking for is something else? I've written at very low levels -- e.g., very tight assembly code to fit into a 512-byte disk boot block on up to very high levels -- attempts at cognitive-linguistic modeling of spreading activation in conceptual networks, in Erlang. My big problem has been finding a treatment of Haskell that roots its model of computation in something more computationally concrete than, say, lambda calculus or category theory. Like I could find for Lisp. Like I could find for Prolog. Like I could find for Erlang. I once tried to get Erlang up on a platform with an old C compiler, and got a little obsessive about it: there was a nasty stack crash before I even got to the Erlang shell prompt, and I basically had to resort to laborious breakpoint debugging to find the problematic line of code. On the way down to that line, I passed data structures and C code that had me thinking, "So that's how they do that. Well, but, it was already pretty obvious. It had to be something like that. But guys: clean up your code, OK?" I have yet to gain any such feeling for Haskell. I once thought I could-- I found a very small 'compiler' for Haskell on github, written in C, that actually worked for a lot of things. (It could swallow Prelude easily.) It was maybe 2000 lines of code. I was encouraged that it generated some kind of VM assembly code. Alas, the VM code emitted turned out to be for some graph-combinator thingie I didn't understand. And I laid the code-study project aside. I thought, certainly, somebody somewhere has drawn a not-too-abstract data structure diagram that shows how thunks relate to data, and how type variables are represented, and how they directly or indirectly link to thunks. With that, I could think about the Haskell execution model with my eyes wandering around the diagram: this happens here, the next thing happens over there, opportunities for parallelism happen on this branch, dispatching of tasks happens down inside this thing, and it all comes back here. And that's why my output looks the way it does. Mystery solved! Now, if somebody harumphs and remonstrates, "That's not how you should try to understand Haskell!" I'm just going to reply, "Maybe it's not how YOU came to YOUR understanding. But look: I'm not you, OK? I'm me. I need to understand how a language works from the nuts and bolts on up. I won't feel confident enough in it otherwise." But I'd only say it that way if I was in a mood to be relatively polite. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry From michael.eugene.turner at gmail.com Fri Sep 17 03:05:09 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Fri, 17 Sep 2021 12:05:09 +0900 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: And I forgot to add: selling power is important, but clarity is too. Selling ergonomics is important, but clarity is too. I once learned a very, very powerful language: APL. Now, to be sure, there was a market obstacle -- it had a very extended character set. But IBM probably thought, "A very powerful language will sell! And that means we'll sell a lot more of the specialized IBM Selectric type-balls! This could be our most profitable programming language ever, especially considering that type-balls wear out eventually and have to be replaced! What's not to like?" I suppose you could say APL was ergonomic, because you spent a lot of your keyboard time just looking for the right keytop symbol, and it slowed you way down. The thing is, most code that actually gets used, and even makes money, is read more than it's written. Software expense is mostly in the maintenance life-cycle, and I think that's still true, even in these days of Agile and CI -- it's just that the effort of the former "maintenance phase" bleeds more into the early phases. I'd love to be so fluent in Haskell that I can appreciate its superior ergonomics, and I speak as a former RSI casualty. But frustration over feeling powerless every time GHC barfs out another error message you don't understand only leads to muscle tension which can inflame chronic RSI, and Haskell is pretty frustrating, starting out. Of course, I'm sure people will tell me to just relax and take my time. But I have a lot of other things to do. I've noticed an interesting metric for Haskell: github activity is more sharply distributed over weekend days than just about any other language in the top 40. Is it basically an intellectual hobby language, outside of academia? I'm evaluating Haskell for a project, one for which I'd like to report some serious progress by the time a certain conference rolls around in March. Months ago, I started with some confidence that I'd have settled the question. Maybe I'd even have a demo all written in Haskell by March, if Haskell seemed right. I'm far less confident now. I'd been warned that the learning curve is steep and long. If my complaints about documentation sound anguished, it's for a reason: a lot of the problems of getting traction on the slope trace back (for me, at least) to writing by people so steeped in Haskell that they no longer remember how they themselves absorbed it, the better to explain it. And, as Simon Peyton-Jones says in one talk, in the early years, the language designers had the incredible luxury of academia -- as he admits, they could spend literally years being confused about the right path forward, at various points, and it didn't matter much for their careers or their goals. That's years of steeping too. And it shows. I don't have years. I have months. And lots of other things I have to get done. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry On Fri, Sep 17, 2021 at 11:27 AM Michael Turner wrote: > > On Fri, Sep 17, 2021 at 5:52 AM Viktor Dukhovni wrote: > > > > On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > > > > > The real problem is that the writing sucks. [snip] > > Vikor: > > Can you be a bit more specific about which sort of writing you find > > sufficiently unsatisfactory to say "the writing sucks"? > > It's an axiom of sales: quality is what the customer says it is. > You'll evaluate writing differently depending on what sort of audience > you're in. > > I'm in this audience: > > -- I have a lot of programming experience with a variety of languages. > I have limited patience with writing that feels like it's talking down > to me. > > -- I have limited patience for a language whose main appeal seems to > be to a niche audience of programmers who want to learn a language in > part because they've been told it's a challenge -- I'm not seeking > status among other programmers. ("Ooh, he knows Haskell. You have to > be really smart to write Haskell.") > > -- I prefer a presentation that's clear and concise, with a > significant reliance on diagrams that show conceptual relations. A > picture of how something works is worth a thousand words that tell me > how great something was, or how great it's going to be once I'm > proficient. > > > > > * Books about Haskell > > - Introductory (e.g. http://learnyouahaskell.com/) > > I started here. I was initially drawn in by the welcoming chattiness. > It got old, fast. Fonzie? Really? How many young programmers today > even know the TV series Happy Days? Waste of page-space. (But see > above -- that's MY reaction. Audiences will differ.) > > > - Comprehensive (e.g. the classic Real World Haskell) > > I hadn't looked at this before. So I looked today. > > Uh-oh: the introductory part reminds me of that old joke about the IBM > salesman, back in the mainframe days, when getting a computer up and > running the customer's application could take months, from hardware > order to production data processing: The salesman sits on the edge of > the bed on his honeymoon night, telling his bride out great it's going > to be. > > The first bit of code shows how you'd write a very short function > (courtesy of "take", not of any inherent feature of Haskell's > programming model) to get the k least elements in a list. A claim is > made: it's faster because of laziness. > > Um, really? Sorting is O(n log n) upper bound no matter what. There's > a vaguely game-theoretic proof of this I found delightful back in > college, and it came to mind when I read that. How would you arrange > numbers in a list so that, no matter what sort algorithm you used, > there would be no way in general to get the k smallest elements > without a full sort? Well, maybe the authors mean "faster on average, > counting using the number of comparisons"? Oh, but wait: isn't there > some overhead for implementing laziness? Hm, why aren't they saying > something here? > > My eyes glaze over all the IBM salesman honeymoon bridal suite talk, > so I go to chapter one. I skip through all the stuff I already know, > and at the end of the chapter, there's bit of code: count the number > of lines in input. After months of looking at Haskell code (but a few > weeks of not looking at it) I can't quite get it, the way I'd almost > instantly get it if it was written in a more conventional programming > language. It's just an exercise in putting some code in a file and > running it. Supposedly it will build confidence. It has the opposite > effect on me. But maybe it's explicated in the next chapter? > > I turn to chapter two, hoping that the line-counter would be > explicated. Oh no: long IBM honeymoon-night salesman talk about Why > Types Are Good. Oh, fuck you! I already know why types are good! I > even know what's bad about the otherwise-good type systems of several > programming languages! WHY ARE YOU WASTING MY TIME?! > > > - Topic focused (e.g. the IMHO rather excellent Parallel and > > Concurrent Haskell) > > It may be excellent if you're already up to speed on Haskell. I'm a > newbie drowning in writing that's not for me. > > > - Theory focused (e.g. > > https://bartoszmilewski.com/category/category-theory/) > > I bailed halfway through a video from Philip Wadler, a talk about > Categories for the Working Hacker (or something) because he still > hadn't said anything about how knowing category theory was useful to, > uh, you know, a working hacker? I ran across a blog that said: forget > category theory. It won't help you. At least not starting out. > > > * The library reference documentation? > > Pretty impenetrable for a newbie, though that's hardly unusual for a > newbie to any language, with reference docs. > > > * The GHC User's Guide? > > Been a while since I looked at it, but not much easier, as I remember. > > > * The Haskell report? > > Haven't read it. > > > * Blog posts? > > So far, only helpful when they are honest and tell me that I'm having > trouble for some very good reasons. I feel less alone. I feel less > stupid. > > > * The Haskell Wiki? > > Very sloppy, much neglected. I put in some improvements to articles, > but a certain syndrome is very much in evidence: it seems mostly > written by Haskell experts who can't seem to get back into a newbie > mindset (and who maybe never had a mindset like mine), and who often > jump from IBM honeymoon salesman talk straight into unnecessarily > complex examples. > > > * r/haskell? > > Sometimes helpful. > > > * Haskell mailing lists? > > When you're being told curtly, "Learn lambda calculus", or someone > can't answer your question about something but instead of saying "I > don't know where you'd find that", gives you an answer to a question > you didn't ask, you're not on a truly beginner-friendly newbies list. > Other mailing lists take up topics that feel way over my head at this > point. > > > * All of the above??? > > So far, pretty much. > > > I am also curious whether I'm part of the solution or part of the > > precipitate. I've recently contributed new documentation for > > Data.Foldable and Data.Traversable: > > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > OK: > > "Merging the contribution of the current element with an accumulator > value from a partial result is performed by an operator function, > either explicitly provided by the caller as in foldr, implicit count > as in length, or partly implicit as in foldMap (where each element is > mapped into a Monoid, and the monoid's mappend operator performs the > merge)." > > Let me tell you how I tried to read that lo-o-ong sentence. > > "Merging the contribution of the current element--" > > Um, you didn't introduce "current element", so "the current element" > is confusing. It feels like you're starting in the middle. And wait, > is the current element being merged, or is some kind of contribution > /from/ the current element being merged? I guess since Haskell is > lazy, it could be the latter . . . > > "--with an accumulator value--" > > Coming from Erlang, I just call them "accumulators". So is an > accumulator value different from an accumulator or . . . what? > > "--from a partial result--" > > So, it's a partial result in the form of the accumulator? Or "the > contribution of the current element"? I kinda-sorta feels like it must > be the accumulator, so, plunging onward . . . > > "--is performed by an operator function" > > Uh-oh: passive voice sentence construction. And "operator function" is > . . . well, all operators are functions in Haskell, so it's performed > by an operator, but-- > > I could go on for a while, but let it suffice to say, long before I'm > halfway through this sentence, the cognitive load is starting to crush > me. How many times will I have to read it to understand it? Well, I > probably won't understand it with multiple readings. Because there I > see "monoid" toward the end (no hyperlink), and again, that feeling: > Haskell may be very powerful indeed, but a lot of the writing makes me > want to kill somebody. (Don't worry. I don't kill people.) > > Now, remember what I said about target audiences? I can imagine a > reader who would actually admire that sentence. But that reader is > someone who has used foldr and foldr a lot, who has a pretty adequate > mental model already, and thinks: "Good. It summarizes all my > knowledge, while refreshing me on a point that hasn't mattered much in > my coding so far." The sentence may contain a few unnecessary words, > but for such a reader, these are like drops of water rolling off a > duck's back. It might read more smoothly with a few added words, but > this reader is mentally inserting such smoothing linkages in his > internal conceptual schema, probably without even subvocalizing those > words. > > Still, there might be a way to break it up and with not many added > words, satisfy more readers. Do you want to do that? Do you need to do > that? Let me tell you something, either way: it'll probably be harder > for you than writing the sentence you wrote. > > This is an interesting point illustrated in a different field, by Paul > Krugman, a few years after he started writing about economics for > layman-reader outlets like Salon: It was actually harder for him to > write the same number of words for a layman, on a given topic, than it > was for him to write a journal article to pass peer review. He had to > think: "What might my readers NOT quite understand yet? How can I get > them there quickly?" > > As an economist, he could think in graphs and equations. And he could > easily say things like "there could be labor-activism-related > variations in how downward-sticky wages become in a liquidity trap." > If he said that to your average economist, he could count on being > understood. It was actually harder for him to write something more > generally accessible, like, "When consumers have snapped their purses > shut in a recession and during the slow recovery, most bosses will > prefer to lay workers off to cut costs, rather than cut wages to keep > workers on payroll. However, others may not. It could depend on how > much that boss fears that the workers would go out on strike in > response to a pay cut." It was harder for him than for me (I'm not an > economist) because first he had to realize: if I say it in the way > that's most obvious to me, most people won't get it. > > > are these a step in the right direction, or examples of more writing > > that sucks? These are reference documentation, not beginner tutorials, > > so a more detailed write up of the concepts, pitfalls, ... things to > > keep in mind when using library, ... > > As I say, for a certain kind of reader, that sentence that I only > stumble around in may be fine for your audience. But Haskell has > apparently plateaued, after surviving a phase where, as Simon > Peyton-Jones points out, almost all new languages die. So it's a > question of what you want to be a part of: a relatively insular > community? Or a drive to expand the community, by making learning > easier? > > > More of that sort of thing would help me to more quickly learn to use > > some of the libraries that lack this sort of overview prose, but perhaps > > what you're looking for is something else? > > I've written at very low levels -- e.g., very tight assembly code to > fit into a 512-byte disk boot block on up to very high levels -- > attempts at cognitive-linguistic modeling of spreading activation in > conceptual networks, in Erlang. My big problem has been finding a > treatment of Haskell that roots its model of computation in something > more computationally concrete than, say, lambda calculus or category > theory. Like I could find for Lisp. Like I could find for Prolog. Like > I could find for Erlang. > > I once tried to get Erlang up on a platform with an old C compiler, > and got a little obsessive about it: there was a nasty stack crash > before I even got to the Erlang shell prompt, and I basically had to > resort to laborious breakpoint debugging to find the problematic line > of code. On the way down to that line, I passed data structures and C > code that had me thinking, "So that's how they do that. Well, but, it > was already pretty obvious. It had to be something like that. But > guys: clean up your code, OK?" > > I have yet to gain any such feeling for Haskell. I once thought I > could-- I found a very small 'compiler' for Haskell on github, written > in C, that actually worked for a lot of things. (It could swallow > Prelude easily.) It was maybe 2000 lines of code. I was encouraged > that it generated some kind of VM assembly code. Alas, the VM code > emitted turned out to be for some graph-combinator thingie I didn't > understand. And I laid the code-study project aside. I thought, > certainly, somebody somewhere has drawn a not-too-abstract data > structure diagram that shows how thunks relate to data, and how type > variables are represented, and how they directly or indirectly link to > thunks. With that, I could think about the Haskell execution model > with my eyes wandering around the diagram: this happens here, the next > thing happens over there, opportunities for parallelism happen on this > branch, dispatching of tasks happens down inside this thing, and it > all comes back here. And that's why my output looks the way it does. > Mystery solved! > > Now, if somebody harumphs and remonstrates, "That's not how you should > try to understand Haskell!" I'm just going to reply, "Maybe it's not > how YOU came to YOUR understanding. But look: I'm not you, OK? I'm me. > I need to understand how a language works from the nuts and bolts on > up. I won't feel confident enough in it otherwise." > > But I'd only say it that way if I was in a mood to be relatively polite. > > Regards, > Michael Turner > Executive Director > Project Persephone > 1-25-33 Takadanobaba > Shinjuku-ku Tokyo 169-0075 > Mobile: +81 (90) 5203-8682 > turner at projectpersephone.org > > Understand - http://www.projectpersephone.org/ > Join - http://www.facebook.com/groups/ProjectPersephone/ > Donate - http://www.patreon.com/ProjectPersephone > Volunteer - https://github.com/ProjectPersephone > > "Love does not consist in gazing at each other, but in looking outward > together in the same direction." -- Antoine de Saint-Exupéry From michael.eugene.turner at gmail.com Fri Sep 17 03:53:13 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Fri, 17 Sep 2021 12:53:13 +0900 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 17 In-Reply-To: References: Message-ID: Wow, someone on this thread said of me, from what I wrote on the beginner's list, "He's trying to translate Haskell to C/C++." No. I started here: https://www.stwing.upenn.edu/~wlovas/hudak/aug.pdf I'd like to use this parsing technique for natural language. I had no intention of translating Haskell to C/C++ unless it turned out to matter for performance. What I didn't realize starting out in trying to understand that code is that it's horribly written code, and underdocumented. 'g' as a function name, a name not clearly related to any meaning? Oh, and how about this type signature: app :: (TTree -> TTree -> Tree) -> TTree -> TTree -> [TTree] I actually reached a point where I thought, "I'm never gonna understand this code," because of that line. Somehow, after weeks of scrolling past it, grimacing, then looking at it again, I figure out a clarification. -- Order (Before/After) type Order = Typed_Tree -> Typed_Tree -> Tree and then I get app :: Order -> Typed_Tree -- the TT to be applied -> Typed_Tree -- TT applied to -> [Typed_Tree] -- result list Is that "translating it to C++"? Or is it "translating it to something you can at least mentally translate into plain English"? (Current frustration: can't seem to find a clean way to extract "Before" and "After" type constructors from Order, as strings to print in trace messages. Several "solutions" found, all either not working in my version of GHC, or not even compilable.) I finally realized: that paper where I started learning Haskell may be a gem as a paper in English, but the code is basically dashed off, by people so steeped in Haskell that it was all obvious to them. And it uses a representation of a left upper-triangular array (in a list-of-lists approach that probably sprays garbage left and right in the course of Haskell evaluations of "transpose", "reverse", etc.) which only makes the code harder to understand. And I haven't convinced myself that it wouldn't just spray smaller numbers of larger pieces of garbage anyway, if I rewrote it to clean out all the list-hacking cruft. Maybe it's OK. Maybe the GHC optimizer really is that good. But before I refactor it to Vector, first I have to make sure I really understand what this code is doing, so that the unit tests I'm adding don't just fail mysteriously. And I'm not there yet. When you read a "diagnosis" of me as someone whose mind is resistant to the Haskell execution model, please ignore it. I'm not resisting it. I'm trying to internalize it. Unfortunately, I haven't found a treatment that ties the execution model to where the rubber hits the road: real computers, like you buy at a store, which are derided by this commenter as "Turing machines." Sorry, guy, but you wrote your reply on a Turing machine. Turing machines got it to my inbox. As Simon Peyton-Jones said, in a talk about how to handle effects, you can't really verify that your program is executing correctly by noticing that the box it's running on gets warmer. I'm quite fine with purity, at least where it can reduce debugging time. I've learned a couple of other functional languages, if you'll condescendingly permit that, say, Lisp and Erlang are "functional." In college, I got fascinated by the idea of a Lisp interpreter with lazy evaluation, and read some papers on the subject, and I even believe laziness could prove useful for the project I'm on. I'm all for static typing. I'm all for how lazy evaluation and purity and functional programming in general can facilitate exploitation of multi-core parallelism. What I want is a clear, concise description of the execution model, to tie it all finally back down to those horrible grubby Turing machines that people buy in stores. Like the one on my desk, right now. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry On Fri, Sep 17, 2021 at 11:18 AM wrote: > > Send Haskell-Cafe mailing list submissions to > haskell-cafe at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > or, via email, send a message with subject or body 'help' to > haskell-cafe-request at haskell.org > > You can reach the person managing the list at > haskell-cafe-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Haskell-Cafe digest..." > > > Today's Topics: > > 1. Re: Haskell's "historical futurism" needs better writing, not > better tools (Viktor Dukhovni) > 2. Re: Haskell's "historical futurism" needs better writing, not > better tools (David Feuer) > 3. Re: Haskell's "historical futurism" needs better writing, not > better tools (Viktor Dukhovni) > 4. Re: Haskell's "historical futurism" needs better writing, not > better tools (David Feuer) > 5. Re: Haskell's "historical futurism" needs better writing, not > better tools (Anthony Clayden) > 6. Haskell reference documentation, laws first or laws last? > (Viktor Dukhovni) > 7. Re: Haskell reference documentation, laws first or laws last? > (Anthony Clayden) > 8. Re: Haskell reference documentation, laws first or laws last? > (Chris Smith) > 9. Re: Haskell reference documentation, laws first or laws last? > (David Feuer) > 10. Re: Haskell reference documentation, laws first or laws last? > (Viktor Dukhovni) > 11. Re: Haskell reference documentation, laws first or laws last? > (Anthony Clayden) > 12. Re: Haskell reference documentation, laws first or laws last? > (Chris Smith) > 13. Re: Haskell reference documentation, laws first or laws last? > (David Feuer) > 14. Re: Haskell reference documentation, laws first or laws last? > (Viktor Dukhovni) > 15. Re: Haskell reference documentation, laws first or laws last? > (Sebastiaan Joosten) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Thu, 16 Sep 2021 16:52:22 -0400 > From: Viktor Dukhovni > To: haskell-cafe at haskell.org > Cc: Michael Turner > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > Content-Type: text/plain; charset=us-ascii > > On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > > > The real problem is that the writing sucks. Not all of it -- and some > > contributors to the community are stellar writers, even if, in the > > snarkish commentary they write about Haskell and the community, I > > don't quite get all the jokes. But speaking as a contributor to the > > Haskell.org wiki -- to which I contribute at times out of hope that > > clarifying points I understand will also lead to more clarity for > > myself -- I have to say it: the writing sucks. > > Can you be a bit more specific about which sort of writing you find > sufficiently unsatisfactory to say "the writing sucks"? > > * Books about Haskell > - Introductory (e.g. http://learnyouahaskell.com/) > - Comprehensive (e.g. the classic Real World Haskell) > - Topic focused (e.g. the IMHO rather excellent Parallel and > Concurrent Haskell) > - Theory focused (e.g. > https://bartoszmilewski.com/category/category-theory/) > - ... > * The library reference documentation? > * The GHC User's Guide? > * The Haskell report? > * Blog posts? > * The Haskell Wiki? > * r/haskell? > * Haskell mailing lists? > ... > * All of the above??? > > I am also curious whether I'm part of the solution or part of the > precipitate. I've recently contributed new documentation for > Data.Foldable and Data.Traversable: > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > are these a step in the right direction, or examples of more writing > that sucks? These are reference documentation, not beginner tutorials, > so a more detailed write up of the concepts, pitfalls, ... things to > keep in mind when using library, ... > > More of that sort of thing would help me to more quickly learn to use > some of the libraries that lack this sort of overview prose, but perhaps > what you're looking for is something else? > > -- > Viktor. > > > ------------------------------ > > Message: 2 > Date: Thu, 16 Sep 2021 16:57:28 -0400 > From: David Feuer > To: "haskell-cafe at haskell.org" > Cc: Michael Turner > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > I am not a fan of how the new Traversable documentation buries the actual > laws. > > On Thu, Sep 16, 2021, 4:55 PM Viktor Dukhovni > wrote: > > > On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > > > > > The real problem is that the writing sucks. Not all of it -- and some > > > contributors to the community are stellar writers, even if, in the > > > snarkish commentary they write about Haskell and the community, I > > > don't quite get all the jokes. But speaking as a contributor to the > > > Haskell.org wiki -- to which I contribute at times out of hope that > > > clarifying points I understand will also lead to more clarity for > > > myself -- I have to say it: the writing sucks. > > > > Can you be a bit more specific about which sort of writing you find > > sufficiently unsatisfactory to say "the writing sucks"? > > > > * Books about Haskell > > - Introductory (e.g. http://learnyouahaskell.com/) > > - Comprehensive (e.g. the classic Real World Haskell) > > - Topic focused (e.g. the IMHO rather excellent Parallel and > > Concurrent Haskell) > > - Theory focused (e.g. > > https://bartoszmilewski.com/category/category-theory/) > > - ... > > * The library reference documentation? > > * The GHC User's Guide? > > * The Haskell report? > > * Blog posts? > > * The Haskell Wiki? > > * r/haskell? > > * Haskell mailing lists? > > ... > > * All of the above??? > > > > I am also curious whether I'm part of the solution or part of the > > precipitate. I've recently contributed new documentation for > > Data.Foldable and Data.Traversable: > > > > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > > > are these a step in the right direction, or examples of more writing > > that sucks? These are reference documentation, not beginner tutorials, > > so a more detailed write up of the concepts, pitfalls, ... things to > > keep in mind when using library, ... > > > > More of that sort of thing would help me to more quickly learn to use > > some of the libraries that lack this sort of overview prose, but perhaps > > what you're looking for is something else? > > > > -- > > Viktor. > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 3 > Date: Thu, 16 Sep 2021 18:43:31 -0400 > From: Viktor Dukhovni > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > Content-Type: text/plain; charset=us-ascii > > On Thu, Sep 16, 2021 at 04:57:28PM -0400, David Feuer wrote: > > > I am not a fan of how the new Traversable documentation buries the > > actual laws. > > The laws are one click away from the table of contents, and IMHO not > particularly illuminating other than for advanced readers. > > For example, in Data.Foldable they are: > > foldr f z t = appEndo (foldMap (Endo . f) t ) z > foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z > fold = foldMap id > length = getSum . foldMap (Sum . const 1) > > is someone new to Data.Foldable really going to learn something from > these before they've deeply understood the background concepts? > > My take is that the laws should almost always be "buried" (one click > away) at the end of the module documentation. Those who care and need > them can find them, but I think they just intimidate the less > experienced readers. Putting the laws first likely only discourages > beginners. > > -- > Viktor. > > > ------------------------------ > > Message: 4 > Date: Thu, 16 Sep 2021 18:51:42 -0400 > From: David Feuer > To: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > The last time I went to look at the laws it took me a couple minutes to > find them. I use them to write instances. Pretty important, IMO. > > On Thu, Sep 16, 2021, 6:46 PM Viktor Dukhovni > wrote: > > > On Thu, Sep 16, 2021 at 04:57:28PM -0400, David Feuer wrote: > > > > > I am not a fan of how the new Traversable documentation buries the > > > actual laws. > > > > The laws are one click away from the table of contents, and IMHO not > > particularly illuminating other than for advanced readers. > > > > For example, in Data.Foldable they are: > > > > foldr f z t = appEndo (foldMap (Endo . f) t ) z > > foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z > > fold = foldMap id > > length = getSum . foldMap (Sum . const 1) > > > > is someone new to Data.Foldable really going to learn something from > > these before they've deeply understood the background concepts? > > > > My take is that the laws should almost always be "buried" (one click > > away) at the end of the module documentation. Those who care and need > > them can find them, but I think they just intimidate the less > > experienced readers. Putting the laws first likely only discourages > > beginners. > > > > -- > > Viktor. > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 5 > Date: Fri, 17 Sep 2021 11:32:04 +1200 > From: Anthony Clayden > To: Haskell Cafe > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Thank you Richard, I'm quite comfortable with discussing in public whether > my response was appropriate. > > Michael might as well observe early that there's a broad range of views as > to how best to learn Haskell. (And every reason that what works for some > doesn't work for others.) I was sharing my experience. I was also drawing > on observations of q's on StackOverflow, for which there's an > alarming number who think Haskell is just C/C++ spelled funny. (Take the > very first [Haskell] q right now.) > > Learning by 'mentally executing' programs is a workable approach -- but not > if your mental model of execution is a Turing machine. > > And I was observing Michael's actual q on the Beginners list. It's clear to > me: > > * He's trying to translate Haskell to C/C++. > * He thinks Lambda calculus is 'advanced'/complicated/beyond a beginner. > * He hasn't tried Lambda calculus/he didn't say it "wasn't helpful for him". > * He thinks that already knowing a swag of procedural/OOP languages will > help with learning Haskell. > > I'd say all of those are unhelpful blocks to learning. > > Perhaps in my personal 'learning journey' it helped that I was profoundly > dissatisfied with procedural languages (of which I'd worked in over a > dozen); and that I fell across Backus' 'Can Programming be liberated ...?', > then Lambda calculus, before I landed on an actual implementation of those > ideas in Haskell. > > And for sure, my learning approach left me with some misconceptions, that > Richard and others have patiently untangled. > > AntC > > On Fri, 17 Sept 2021 at 02:05, Richard Eisenberg wrote: > > > I just want to pipe up and say I'm not comfortable with this response. > > When I feel this way about writing on a forum, I normally contact the > > author in private, but I think posting publicly here has its merits. I'm > > hoping that the long correspondence AntC and I have had -- often with > > opposing viewpoints but with mutual respect -- with withstand this email. > > > > Michael posted here expressing frustration with his experience learning > > and using Haskell. In my opinion, he has spent too much time reading older > > papers, written by experts for experts -- which Michael is not. I do not > > fault Michael for this: these resources are sometimes what appear when > > searching, and we as a community have done a poor job marshaling our > > educational resources. (Michael, I just thought of a resource you might > > find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource > > attempting to do that marshaling. I am not vouching for it here, per se, > > but I know others have found it useful.) > > > > However, Michael very specifically said that "just learn lambda-calculus" > > was not helpful for him, and so I think it's unhelpful for someone to > > respond with "just learn lambda-calculus". There are a number of other > > statements in the email below which could be seen as belittling -- also not > > helpful. > > > > ... > > > > In the meantime, I implore us to take all expressed experiences as exactly > > that: the experience of the person writing. And if they say they don't want > > X, please let's not feed them X. :) > > > > Richard > > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden > > wrote: > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > The seeds of your confusion are very evident from your message. How to > > back you out of whatever deep rabbit-hole you've managed to get your head > > into? > > > > > ... Your average reader (already a programmer) would be better served > > by a comparative approach: Here's how to say something in a couple of > > other programming languages, here's how to say something roughly > > equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way > > that C++ or C# are different. (I'll leave others to judge how subtly > > different they are.) > > > > Haskell is dramatically and fundamentally different. You can't just > > 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's > > many tales of woe on StackOverflow. Just No. > > > > I really don't know how you could have got any experience with Haskell and > > say "subtly". > > > > I suggest you unlearn everything you think you know about Haskell, and > > strike out in an entirely different direction. The best approach would be > > to spend a few days playing with lambda calculus. (That's what I did before > > tackling Haskell.) > > ... > > > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 6 > Date: Thu, 16 Sep 2021 19:43:07 -0400 > From: Viktor Dukhovni > To: haskell-cafe at haskell.org > Subject: [Haskell-cafe] Haskell reference documentation, laws first or > laws last? > Message-ID: > Content-Type: text/plain; charset=us-ascii > > On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > > > The last time I went to look at the laws it took me a couple minutes to > > find them. I use them to write instances. Pretty important, IMO. > > I agree the laws are important to document, I just don't think they > belong at the top of the module. The beginner to intermediate users > will be using the library and existing instances for some time before > they start to write their own instances. > > If more modules adopt something like the style of the new Data.Foldable, > experienced users will know to look for the laws at the end, if not > still present at the top of the module. > > Of course perhaps the community would prefer the original Laws first > format, I'm fine with that emerging as the consensus. Perhaps worthy > of a separate thread (made it so). > > Of course the conjectured users who might most benefit from not being > intimidated by being exposed to laws before they're ready to understand > them might not be present on this forum... > > -- > Viktor. > > > ------------------------------ > > Message: 7 > Date: Fri, 17 Sep 2021 12:37:17 +1200 > From: Anthony Clayden > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Hi Viktor, really this is a quite different q than the thread talking > about a learner's experience. > > You're writing deeply-technical detail not at all aimed at beginners. > There's a very broad range of reasons and prior knowledge for readers > of Library docos. > > But I disagree with this: > > > The beginner to intermediate users will be using the library and existing instances for some time before they start to write their own instances. > > I'll want to write an instance of Foldable as soon as I've declared my > datatype, won't I? Or do you expect me to be folding only over Lists? > > Speaking for myself, if I want to understand a function, I look first > at its type then its source definition. > > The Laws for the particular Foldable example I don't understand at > all. I'd say: hide those Laws as far away as possible. > > In fact, since the blasted FTP re-organisation of that library, I've > more or less given up. Too hard/too abstract/too much Category Theory. > What's an `Endo`? > > Thank you for your efforts to document. I expect there's someone > you're helping. Not me. I don't think it's that the style "sucks". > > This style and content is enough for me: > https://www.haskell.org/hugs/pages/libraries/base/Data-Foldable.html > > > > Of course the conjectured users who might most benefit from not being intimidated by being exposed to laws before they're ready to understand them might not be present on this forum... > > > I've gone well beyond the point of being intimidated by Category > Theorists. I find they're doing a splendid job of putting people off > getting to love Haskell as I used to. If you want to tell me off for > speaking out of turn, go ahead. (But this forum is the cafe, perhaps > this particular discussion should be on glasgow-haskell-users?) > > > AntC > > > On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > >* The last time I went to look at the laws it took me a couple minutes to > *>* find them. I use them to write instances. Pretty important, IMO. > * > I agree the laws are important to document, I just don't think they > belong at the top of the module. The beginner to intermediate users > will be using the library and existing instances for some time before > they start to write their own instances. > > If more modules adopt something like the style of the new Data.Foldable, > experienced users will know to look for the laws at the end, if not > still present at the top of the module. > > Of course perhaps the community would prefer the original Laws first > format, I'm fine with that emerging as the consensus. Perhaps worthy > of a separate thread (made it so). > > Of course the conjectured users who might most benefit from not being > intimidated by being exposed to laws before they're ready to understand > them might not be present on this forum... > > -- > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 8 > Date: Thu, 16 Sep 2021 21:10:58 -0400 > From: Chris Smith > To: haskell-cafe > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > For what it's worth, I agree with you both that it's important to document > the laws, and that it's not the most friendly way to begin the > documentation for a reader who is unfamiliar with the concept. It's not > clear to me whether the documentation ought to be optimized for readers who > are or aren't familiar with the concept, but I lean to the latter, which > means putting the type class laws at the end (but still easily accessible) > makes sense to me. > > On Thu, Sep 16, 2021 at 7:47 PM Viktor Dukhovni > wrote: > > > On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > > > > > The last time I went to look at the laws it took me a couple minutes to > > > find them. I use them to write instances. Pretty important, IMO. > > > > I agree the laws are important to document, I just don't think they > > belong at the top of the module. The beginner to intermediate users > > will be using the library and existing instances for some time before > > they start to write their own instances. > > > > If more modules adopt something like the style of the new Data.Foldable, > > experienced users will know to look for the laws at the end, if not > > still present at the top of the module. > > > > Of course perhaps the community would prefer the original Laws first > > format, I'm fine with that emerging as the consensus. Perhaps worthy > > of a separate thread (made it so). > > > > Of course the conjectured users who might most benefit from not being > > intimidated by being exposed to laws before they're ready to understand > > them might not be present on this forum... > > > > -- > > Viktor. > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 9 > Date: Thu, 16 Sep 2021 21:14:19 -0400 > From: David Feuer > To: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > I'm not talking about whether they're first or last. They're currently not > part of the class documentation *at all*. They're only in the > Data.Traversable documentation. > > On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni > wrote: > > > On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > > > > > The last time I went to look at the laws it took me a couple minutes to > > > find them. I use them to write instances. Pretty important, IMO. > > > > I agree the laws are important to document, I just don't think they > > belong at the top of the module. The beginner to intermediate users > > will be using the library and existing instances for some time before > > they start to write their own instances. > > > > If more modules adopt something like the style of the new Data.Foldable, > > experienced users will know to look for the laws at the end, if not > > still present at the top of the module. > > > > Of course perhaps the community would prefer the original Laws first > > format, I'm fine with that emerging as the consensus. Perhaps worthy > > of a separate thread (made it so). > > > > Of course the conjectured users who might most benefit from not being > > intimidated by being exposed to laws before they're ready to understand > > them might not be present on this forum... > > > > -- > > Viktor. > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 10 > Date: Thu, 16 Sep 2021 21:25:17 -0400 > From: Viktor Dukhovni > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > Content-Type: text/plain; charset=us-ascii > > On Thu, Sep 16, 2021 at 09:14:19PM -0400, David Feuer wrote: > > > I'm not talking about whether they're first or last. They're currently not > > part of the class documentation *at all*. They're only in the > > Data.Traversable documentation. > > I see, I think you're noting that when re-exported from Prelude, the > class definitions of Foldable and Traversable that appear in the > Prelude module: > > https://hackage.haskell.org/package/base-4.15.0.0/docs/Prelude.html#g:11 > > no longer include the laws, you have to look at the underlying module > to find them. If that's the issue, I should note that the re-exported > class definitions do have overview hyperlinks: > > A more detailed description can be found in the overview section of > [Data.Foldable](https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Foldable.html#overview) > > A more detailed description can be found in the overview section of > [Data.Traversable](https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Traversable.html#overview) > > Would your issue be addressed if links to the laws were similarly linked > from the class definitions? > > -- > Viktor. > > > ------------------------------ > > Message: 11 > Date: Fri, 17 Sep 2021 13:26:48 +1200 > From: Anthony Clayden > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Hi David, > > The Foldable Laws are here > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:21 > > In the Data-Foldable doco. (There's a menu entry on the sidebar, or > text search.) > > The Data-Traversable doco has only the Traversable Laws. > > > I'm not talking about whether they're first or last. They're currently not part of the class documentation *at all*. They're only in the Data.Traversable documentation. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 12 > Date: Thu, 16 Sep 2021 21:32:29 -0400 > From: Chris Smith > To: David Feuer > Cc: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Ah, I misunderstood you as well. I agree that the laws should be included > in the type class documentation. In fact, most of the documentation from > the link should probably be moved into the documentation for the class, > rather than a stand-alone section. > > On Thu, Sep 16, 2021 at 9:15 PM David Feuer wrote: > > > I'm not talking about whether they're first or last. They're currently not > > part of the class documentation *at all*. They're only in the > > Data.Traversable documentation. > > > > On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni > > wrote: > > > >> On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > >> > >> > The last time I went to look at the laws it took me a couple minutes to > >> > find them. I use them to write instances. Pretty important, IMO. > >> > >> I agree the laws are important to document, I just don't think they > >> belong at the top of the module. The beginner to intermediate users > >> will be using the library and existing instances for some time before > >> they start to write their own instances. > >> > >> If more modules adopt something like the style of the new Data.Foldable, > >> experienced users will know to look for the laws at the end, if not > >> still present at the top of the module. > >> > >> Of course perhaps the community would prefer the original Laws first > >> format, I'm fine with that emerging as the consensus. Perhaps worthy > >> of a separate thread (made it so). > >> > >> Of course the conjectured users who might most benefit from not being > >> intimidated by being exposed to laws before they're ready to understand > >> them might not be present on this forum... > >> > >> -- > >> Viktor. > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 13 > Date: Thu, 16 Sep 2021 21:33:02 -0400 > From: David Feuer > To: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > The laws of any sensible class are an essential and integral part of it. > Without them, you just have ad hoc overloading. They shouldn't be relegated > to the canonical exporting module. > > On Thu, Sep 16, 2021, 9:27 PM Viktor Dukhovni > wrote: > > > On Thu, Sep 16, 2021 at 09:14:19PM -0400, David Feuer wrote: > > > > > I'm not talking about whether they're first or last. They're currently > > not > > > part of the class documentation *at all*. They're only in the > > > Data.Traversable documentation. > > > > I see, I think you're noting that when re-exported from Prelude, the > > class definitions of Foldable and Traversable that appear in the > > Prelude module: > > > > > > https://hackage.haskell.org/package/base-4.15.0.0/docs/Prelude.html#g:11 > > > > no longer include the laws, you have to look at the underlying module > > to find them. If that's the issue, I should note that the re-exported > > class definitions do have overview hyperlinks: > > > > A more detailed description can be found in the overview section of > > [Data.Foldable]( > > https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Foldable.html#overview > > ) > > > > A more detailed description can be found in the overview section of > > [Data.Traversable]( > > https://hackage.haskell.org/package/base-4.15.0.0/docs/Data-Traversable.html#overview > > ) > > > > Would your issue be addressed if links to the laws were similarly linked > > from the class definitions? > > > > -- > > Viktor. > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 14 > Date: Thu, 16 Sep 2021 21:56:37 -0400 > From: Viktor Dukhovni > To: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > Content-Type: text/plain; charset=us-ascii > > > On 16 Sep 2021, at 9:33 pm, David Feuer wrote: > > > > The laws of any sensible class are an essential and integral part of it. Without them, you just have ad hoc overloading. They shouldn't be relegated to the canonical exporting module. > > Surely a one click link from the Prelude re-export is no worse than a 1-click link > in the module table of contents? > > I am rather reluctant beat new readers over the head with laws that often are much > too abstract to add clarity. > > -- > Viktor. > > > > ------------------------------ > > Message: 15 > Date: Thu, 16 Sep 2021 22:13:27 -0400 > From: Sebastiaan Joosten > To: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > I personally like it if the documentation of re-exported classes just > contain a summary, much like Data.Foldable does. The prelude documentation > is quite long already. I would not object to making the links stand out a > bit more though: a title 'More detailed descriptions' with a bulleted > summary to 'laws' might do that. > On where the laws need to be: I think for foldable the right decision is > made, there may be exceptions but I typically like to hear about the ideas > behind things before I dive into the algebraic characterization. > > Also, many thanks to the write-up of Foldable. > > Best, > Sebastiaan > > On Thu, Sep 16, 2021 at 9:36 PM Chris Smith wrote: > > > Ah, I misunderstood you as well. I agree that the laws should be included > > in the type class documentation. In fact, most of the documentation from > > the link should probably be moved into the documentation for the class, > > rather than a stand-alone section. > > > > On Thu, Sep 16, 2021 at 9:15 PM David Feuer wrote: > > > >> I'm not talking about whether they're first or last. They're currently > >> not part of the class documentation *at all*. They're only in the > >> Data.Traversable documentation. > >> > >> On Thu, Sep 16, 2021, 7:45 PM Viktor Dukhovni > >> wrote: > >> > >>> On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > >>> > >>> > The last time I went to look at the laws it took me a couple minutes to > >>> > find them. I use them to write instances. Pretty important, IMO. > >>> > >>> I agree the laws are important to document, I just don't think they > >>> belong at the top of the module. The beginner to intermediate users > >>> will be using the library and existing instances for some time before > >>> they start to write their own instances. > >>> > >>> If more modules adopt something like the style of the new Data.Foldable, > >>> experienced users will know to look for the laws at the end, if not > >>> still present at the top of the module. > >>> > >>> Of course perhaps the community would prefer the original Laws first > >>> format, I'm fine with that emerging as the consensus. Perhaps worthy > >>> of a separate thread (made it so). > >>> > >>> Of course the conjectured users who might most benefit from not being > >>> intimidated by being exposed to laws before they're ready to understand > >>> them might not be present on this forum... > >>> > >>> -- > >>> Viktor. > >>> _______________________________________________ > >>> Haskell-Cafe mailing list > >>> To (un)subscribe, modify options or view archives go to: > >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >>> Only members subscribed via the mailman list are allowed to post. > >> > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > ------------------------------ > > End of Haskell-Cafe Digest, Vol 217, Issue 17 > ********************************************* From ietf-dane at dukhovni.org Fri Sep 17 04:24:12 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Fri, 17 Sep 2021 00:24:12 -0400 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: On Fri, Sep 17, 2021 at 11:27:12AM +0900, Michael Turner wrote: > > I am also curious whether I'm part of the solution or part of the > > precipitate. I've recently contributed new documentation for > > Data.Foldable and Data.Traversable: > > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > OK: > > "Merging the contribution of the current element with an accumulator > value from a partial result is performed by an operator function, > either explicitly provided by the caller as in foldr, implicit count > as in length, or partly implicit as in foldMap (where each element is > mapped into a Monoid, and the monoid's mappend operator performs the > merge)." > > Let me tell you how I tried to read that lo-o-ong sentence. If I may trouble you just a bit longer, I'd like to ask whether the problem is the phrasing, or the selection of subject matter. If the latter, then any defects in the phrasing are perhaps moot. Supposing I rephrase the same thing as: The contribution of each element to the final result is combined with an accumulator via an /operator/ function. The operator may be explicitly provided by the caller as in `foldr` or may be implicit as in `length`. In the case of `foldMap`, the caller provides a function mapping each element into a suitable 'Monoid', which makes it possible to merge the per-element contributions via that monoid's `mappend` function. Does that help? At all? Enough? The word "Monoid" hyperlinks to the documentation of that class, and I thought it fair to reference Monoids in the reference documentation for a module that defines `foldMap`. If the above is helpful, I am not too proud to rewrite any paragraphs that are poorly phrased, if there is some merit in the subject matter. I don't think the module overview can be a beginner tutorial, that's more the domain of books, ... I think that the descriptive prose in the reference docs that follows the function synopses just need to cover any concepts and API behaviours that don't immediately follow from those synopses. A rough guide for me were Unix manpages, where e.g. setsockopt(2) is not a networking tutorial, and yet still has a bunch of useful prose, and not just function signatures. -- Viktor. From michael.eugene.turner at gmail.com Fri Sep 17 04:43:01 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Fri, 17 Sep 2021 13:43:01 +0900 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: References: Message-ID: "The seeds of your confusion are very evident from your message". The seeds of your unsubstantiated assumptions about me are very evident from yours. "You can't just 'translate' an algorithm from OOP to Haskell" Wow, I'm either "trying to translate Haskell to C++" (someone else, above) or trying to translate C++ to Haskell. I'm actually doing neither. I started by trying to understand this: https://www.stwing.upenn.edu/~wlovas/hudak/aug.pdf (And no, just because Haskell is great for writing little special-purpose programming languages does not automatically mean it's up to snuff for handling natural language.) I'd originally hoped to fully understand the rather short program in that paper (full code, in two versions, elsewhere on Paul Jones aca dite) by getting it to run again, then commenting the code as I began to understand it. And then, on to more important issues for a fuller Haskell implementation, issues described here https://www.aclweb.org/anthology/C94-2137.pdf and here http://www.lacus.org/volumes/23/22.sypniewski.pdf Both of which are references I dug up and supplied here https://en.wikipedia.org/wiki/Applicative_universal_grammar as I took the Wikipedia article from stub status to something less stubby -- it actually started in this state: https://en.wikipedia.org/w/index.php?title=Applicative_universal_grammar&diff=prev&oldid=1020447173 The ASCII-art diagrams you see there are output from code that I've gotten working again. I learned about lazy evaluation in college, when I got interested in how Lisp might implement it. I'm very familiar with the arguments for purity, especially from learning Erlang some years ago (during which I wrote my share of accumulator-based tail-recursive functions.) I prefer static typing but hated the way C++ templates extended the concept, mostly because the syntax error messages were so bad for so long. My career includes a time in the late 80s when the kind of computing power we have in our phones now with multicore processors filled a box of hardware too heavy to lift. This was at a startup where the founder was substantially inspired by this stream-oriented single-assignment language: https://en.wikipedia.org/wiki/SISAL I started programming at 15. It's been a very rare year, even after leaving the software profession, when I didn't write at least some code, learning new things in the process. Which means I've been looking at programming languages and how to implement things at the most appropriate level of abstraction possible for just a few months shy of fifty years. The arguments here are following a familiar pattern, one I see in discussions of everything from programming to government policy. (1) I disagree with someone (2) This person instantly assumes I must be ignorant of what they know (3) They start Mansplaining It All To Me. This is particularly irksome when the person is actually considerably more ignorant of the subject than I am. I'm still ignorant of most of Haskell, to be sure. However, I'm not ignorant when it comes to writing. (Published articles on request.) A great deal of what's written about Haskell, usually with very good intentions, has proved useless to me. Have I had a stroke that leaves me apparently unharmed, but actually no longer able to absorb a different programming language? Was I always just too dumb to learn Haskell? Somehow, I think it's more related to the writing. To some extent the community seems to recognize there's a problem -- e.g., the Monad Tutorial Explosion. I finally got (most of?) what monads really mean for practical programming when none other than Simon Peyton-Jones said F# called a very similar construct "workflow," a word he likes. Wow, plain English instead of a mathematical abstraction that, in the math introductions, looks weirdly clunky to me, if anything, but, in any case, very hard to relate to writing better code. Lambda calculus? I have vague memories of Eugene Lawler https://en.wikipedia.org/wiki/Eugene_Lawler covering it when I took computing theory from him. And again, when I was grading computing theory homework for this required course for graduate students (for their prelim exams) for Richard Lipton https://en.wikipedia.org/wiki/Richard_Lipton in the fall term of 1980 at U.C. Berkeley. It's not that I'm too stupid to learn lambda calculus. It's that I seriously doubt that refreshing my memory on the details is going to add significantly more to my grasp of functional programming in Haskell. I disagree with some people here. They jump to the conclusion that I'm some ignorant moron. They also keep trying to sell Haskell as something dramatically, fundamentally -- nay transcendentally! -- different from anything I've ever known. Are you doing that? Stop. Just stop. Haskell's big problem right now is adoption. And I'm telling you why adoption has been hard for me. You lecture back, telling me things I already know, making sweeping assumptions about me. When you do that, you're not part of the solution to Haskell's biggest problem right now. You're part of the problem. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry On Fri, Sep 17, 2021 at 4:19 AM wrote: > > Send Haskell-Cafe mailing list submissions to > haskell-cafe at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > or, via email, send a message with subject or body 'help' to > haskell-cafe-request at haskell.org > > You can reach the person managing the list at > haskell-cafe-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Haskell-Cafe digest..." > > > Today's Topics: > > 1. Re: Haskell's "historical futurism" needs better writing, not > better tools (Richard Eisenberg) > 2. Re: Haskell's "historical futurism" needs better writing, not > better tools (Jeffrey Brown) > 3. Re: Haskell's "historical futurism" needs better writing, not > better tools (Gregory Guthrie) > 4. Re: Bundle patterns with type aliases (Carter Schonwald) > 5. Re: Bundle patterns with type aliases (David Feuer) > 6. Re: Bundle patterns with type aliases (David Feuer) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Thu, 16 Sep 2021 14:05:19 +0000 > From: Richard Eisenberg > To: Anthony Clayden > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000 at us-east-2.amazonses.com> > > Content-Type: text/plain; charset="utf-8" > > I just want to pipe up and say I'm not comfortable with this response. When I feel this way about writing on a forum, I normally contact the author in private, but I think posting publicly here has its merits. I'm hoping that the long correspondence AntC and I have had -- often with opposing viewpoints but with mutual respect -- with withstand this email. > > Michael posted here expressing frustration with his experience learning and using Haskell. In my opinion, he has spent too much time reading older papers, written by experts for experts -- which Michael is not. I do not fault Michael for this: these resources are sometimes what appear when searching, and we as a community have done a poor job marshaling our educational resources. (Michael, I just thought of a resource you might find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource attempting to do that marshaling. I am not vouching for it here, per se, but I know others have found it useful.) > > However, Michael very specifically said that "just learn lambda-calculus" was not helpful for him, and so I think it's unhelpful for someone to respond with "just learn lambda-calculus". There are a number of other statements in the email below which could be seen as belittling -- also not helpful. > > Instead, I wish that we, as a community, could take posts like Michael's at face value: this is the experience of someone who wants to learn Haskell. While some of the conclusions stated in that post are misunderstandings, it is not the sole fault of the learner for these misunderstandings: instead, we must try to understand what about our community and posted materials induced these misunderstandings, and then seek to improve. Many people in Michael's situation may not have posted at all -- and so this kind of information can be very hard to get. > > Michael, I have no silver bullet to offer to you to try to help you here. I do tend to agree with AntC that you have developed some misconceptions that are hindering your continued learning. The terminology actively hurts here. (To be fair, the first Haskell standard pre-dates both Java and C++, and so one could argue who got the terms wrong.) For my part, I am trying to help with this situation both by trying to improve error messages, and though my support of the Haskell Foundation's Haskell School initiative (https://github.com/haskellfoundation/HaskellSchool). These will take time to grow, but my hope is that a future person like you will have an easier route in. > > In the meantime, I implore us to take all expressed experiences as exactly that: the experience of the person writing. And if they say they don't want X, please let's not feed them X. :) > > Richard > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden wrote: > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > The seeds of your confusion are very evident from your message. How to back you out of whatever deep rabbit-hole you've managed to get your head into? > > > > > ... Your average reader (already a programmer) would be better served by a comparative approach: Here's how to say something in a couple of other programming languages, here's how to say something roughly equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way that C++ or C# are different. (I'll leave others to judge how subtly different they are.) > > > > Haskell is dramatically and fundamentally different. You can't just 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's many tales of woe on StackOverflow. Just No. > > > > I really don't know how you could have got any experience with Haskell and say "subtly". > > > > I suggest you unlearn everything you think you know about Haskell, and strike out in an entirely different direction. The best approach would be to spend a few days playing with lambda calculus. (That's what I did before tackling Haskell.) > > > > > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") > > > > Lambda calculus is an excellent place for beginners to start. What could be easier to learn? It's certainly easier than grokking a Turing machine; and much easier than Haskell: less than a handful of primitives yet can compute anything computable. > > > > > And since the concepts are seldom described in concrete enough and time-honored programming language terms (by comparison to other programming languages) > > > > I'm guessing that the concepts you're talking of simply don't correspond to anything in time-honoured (procedural) programming. Anybody writing about Haskell (including anybody writing the User Guide) assumes a base level of understanding of Haskell. You've clearly veered off the track and haven't yet reached base. Remember the User Guide builds on top of the Language Report. > > > > (On the point of 'time-honoured': lambda calculus is almost exactly the same age as Turing machines. The first well-known programming language using lambda-calculus ideas (LISP 1966) is almost exactly the same age as the first OOP language (Simula 1967). Which is the more time-honoured?) > > > > You do have a point that the terminology in Haskell is often mysterious > > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", and he felt this was wise. > > > > Yes many have yearned for a more warm-and-cuddly term than "monad". But the terminology barrier starts before that. > > > > Haskell typeclasses are not 'classes' in any sense recognisable from OOP. There are no objects, no hidden state, no destructive assignment. We might go back to February 1988 when a strawman for what became typeclasses used OVERLOAD/INSTANCE. > > > > AntC > > > > > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 2 > Date: Thu, 16 Sep 2021 09:34:09 -0500 > From: Jeffrey Brown > To: Richard Eisenberg > Cc: haskell-cafe , Anthony Clayden > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > I strongly believe the best study strategy is to be unfaithful to any > source or subtopic. When I want to learn something, I study whatever aspect > of it holds my interest, for only slightly longer than it continues to do > so. If I continue to want to learn a topic, but lose interest in a > particular source or subtopic, it's important to stop that particular > avenue. Otherwise I'll lose motivation for the topic as a whole. > > The result is that, while I never learn (say) a language completely, I > generally learn enough to do whatever I was trying to do. (Sometimes I > learn enough to decide it's too hard -- and for cases in which that's bound > to happen, the quicker the better.) > > Almost nobody learns any language completely anyway, and most of those > who do could have used their time better. Sacrifice is a superpower. > > On Thu, Sep 16, 2021 at 9:09 AM Richard Eisenberg > wrote: > > > I just want to pipe up and say I'm not comfortable with this response. > > When I feel this way about writing on a forum, I normally contact the > > author in private, but I think posting publicly here has its merits. I'm > > hoping that the long correspondence AntC and I have had -- often with > > opposing viewpoints but with mutual respect -- with withstand this email. > > > > Michael posted here expressing frustration with his experience learning > > and using Haskell. In my opinion, he has spent too much time reading older > > papers, written by experts for experts -- which Michael is not. I do not > > fault Michael for this: these resources are sometimes what appear when > > searching, and we as a community have done a poor job marshaling our > > educational resources. (Michael, I just thought of a resource you might > > find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource > > attempting to do that marshaling. I am not vouching for it here, per se, > > but I know others have found it useful.) > > > > However, Michael very specifically said that "just learn lambda-calculus" > > was not helpful for him, and so I think it's unhelpful for someone to > > respond with "just learn lambda-calculus". There are a number of other > > statements in the email below which could be seen as belittling -- also not > > helpful. > > > > Instead, I wish that we, as a community, could take posts like Michael's > > at face value: this is the experience of someone who wants to learn > > Haskell. While some of the conclusions stated in that post are > > misunderstandings, it is not the sole fault of the learner for these > > misunderstandings: instead, we must try to understand what about our > > community and posted materials induced these misunderstandings, and then > > seek to improve. Many people in Michael's situation may not have posted at > > all -- and so this kind of information can be very hard to get. > > > > Michael, I have no silver bullet to offer to you to try to help you here. > > I do tend to agree with AntC that you have developed some misconceptions > > that are hindering your continued learning. The terminology actively hurts > > here. (To be fair, the first Haskell standard pre-dates both Java and C++, > > and so one could argue who got the terms wrong.) For my part, I am trying > > to help with this situation both by trying to improve error messages, and > > though my support of the Haskell Foundation's Haskell School initiative ( > > https://github.com/haskellfoundation/HaskellSchool). These will take time > > to grow, but my hope is that a future person like you will have an easier > > route in. > > > > In the meantime, I implore us to take all expressed experiences as exactly > > that: the experience of the person writing. And if they say they don't want > > X, please let's not feed them X. :) > > > > Richard > > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden > > wrote: > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > The seeds of your confusion are very evident from your message. How to > > back you out of whatever deep rabbit-hole you've managed to get your head > > into? > > > > > ... Your average reader (already a programmer) would be better served > > by a comparative approach: Here's how to say something in a couple of > > other programming languages, here's how to say something roughly > > equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way > > that C++ or C# are different. (I'll leave others to judge how subtly > > different they are.) > > > > Haskell is dramatically and fundamentally different. You can't just > > 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's > > many tales of woe on StackOverflow. Just No. > > > > I really don't know how you could have got any experience with Haskell and > > say "subtly". > > > > I suggest you unlearn everything you think you know about Haskell, and > > strike out in an entirely different direction. The best approach would be > > to spend a few days playing with lambda calculus. (That's what I did before > > tackling Haskell.) > > > > > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") > > > > > > Lambda calculus is an excellent place for beginners to start. What could > > be easier to learn? It's certainly easier than grokking a Turing machine; > > and much easier than Haskell: less than a handful of primitives yet can > > compute anything computable. > > > > > And since the concepts are seldom described in concrete enough and > > time-honored programming language terms (by comparison to other > > programming languages) > > > > I'm guessing that the concepts you're talking of simply don't correspond > > to anything in time-honoured (procedural) programming. Anybody writing > > about Haskell (including anybody writing the User Guide) assumes a base > > level of understanding of Haskell. You've clearly veered off the track and > > haven't yet reached base. Remember the User Guide builds on top of the > > Language Report. > > > > (On the point of 'time-honoured': lambda calculus is almost exactly the > > same age as Turing machines. The first well-known programming language > > using lambda-calculus ideas (LISP 1966) is almost exactly the same age as > > the first OOP language (Simula 1967). Which is the more time-honoured?) > > > > You do have a point that the terminology in Haskell is often mysterious > > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", and > > he felt this was wise. > > > > Yes many have yearned for a more warm-and-cuddly term than "monad". But > > the terminology barrier starts before that. > > > > Haskell typeclasses are not 'classes' in any sense recognisable from OOP. > > There are no objects, no hidden state, no destructive assignment. We might > > go back to February 1988 when a strawman for what became typeclasses used > > OVERLOAD/INSTANCE. > > > > AntC > > > > > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > -- > Jeff Brown | Jeffrey Benjamin Brown > LinkedIn | Github > | Twitter > | Facebook > | very old Website > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 3 > Date: Thu, 16 Sep 2021 15:28:16 +0000 > From: Gregory Guthrie > To: Richard Eisenberg , Anthony Clayden > > Cc: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > > > Content-Type: text/plain; charset="utf-8" > > Educational research and learning theory shows that learning anything new is more effective and longer retained when it is connected to and builds on prior knowledge. > > People may understand anything new if presented as a completely new set of ideas or principles, but that knowledge is not persistent or long remembered. > > I personally find Haskell a good example of this. When teaching it one can show incrementally how it is the same in many ways as procedural programming languages. Then how it improves on them with first-class functions, currying, immutability, type abstractions, etc. These are all important ideas that they will also see in other IP languages, just much cleaner and more integrated in Haskell(!). > > Basic Haskell programs with these features can then be used as a bisis for both appreciating the language features and design and FP in general, and as a stepping stone to more advanced usages. > > Then introducing Functors, Monads, .... Are again an easy and well motivated step for improving on their existing IP experience, and show both nice abstractions and ideas, and a nice implementation and results. > > All of this connects to and builds on what they already know. > > Moving into all of the fancier type system features and pragmas, one enters into a realm where Haskell programs are no longer simple enough to easily read as they incorporate several levels of new abstractions and syntax. > > But at least students have a good basis for further exploration, and an appreciation of FP and Haskell. :-) > > > > From: Haskell-Cafe On Behalf Of Richard Eisenberg > Sent: Thursday, September 16, 2021 10:05 AM > To: Anthony Clayden > Cc: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools > > I just want to pipe up and say I'm not comfortable with this response. When I feel this way about writing on a forum, I normally contact the author in private, but I think posting publicly here has its merits. I'm hoping that the long correspondence AntC and I have had -- often with opposing viewpoints but with mutual respect -- with withstand this email. > > Michael posted here expressing frustration with his experience learning and using Haskell. In my opinion, he has spent too much time reading older papers, written by experts for experts -- which Michael is not. I do not fault Michael for this: these resources are sometimes what appear when searching, and we as a community have done a poor job marshaling our educational resources. (Michael, I just thought of a resource you might find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource attempting to do that marshaling. I am not vouching for it here, per se, but I know others have found it useful.) > > However, Michael very specifically said that "just learn lambda-calculus" was not helpful for him, and so I think it's unhelpful for someone to respond with "just learn lambda-calculus". There are a number of other statements in the email below which could be seen as belittling -- also not helpful. > > Instead, I wish that we, as a community, could take posts like Michael's at face value: this is the experience of someone who wants to learn Haskell. While some of the conclusions stated in that post are misunderstandings, it is not the sole fault of the learner for these misunderstandings: instead, we must try to understand what about our community and posted materials induced these misunderstandings, and then seek to improve. Many people in Michael's situation may not have posted at all -- and so this kind of information can be very hard to get. > > Michael, I have no silver bullet to offer to you to try to help you here. I do tend to agree with AntC that you have developed some misconceptions that are hindering your continued learning. The terminology actively hurts here. (To be fair, the first Haskell standard pre-dates both Java and C++, and so one could argue who got the terms wrong.) For my part, I am trying to help with this situation both by trying to improve error messages, and though my support of the Haskell Foundation's Haskell School initiative (https://github.com/haskellfoundation/HaskellSchool). These will take time to grow, but my hope is that a future person like you will have an easier route in. > > In the meantime, I implore us to take all expressed experiences as exactly that: the experience of the person writing. And if they say they don't want X, please let's not feed them X. :) > > Richard > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden > wrote: > > Hi Michael, oh dear, oh dear, oh dear. > > The seeds of your confusion are very evident from your message. How to back you out of whatever deep rabbit-hole you've managed to get your head into? > > > ... Your average reader (already a programmer) would be better served by a comparative approach: Here's how to say something in a couple of other programming languages, here's how to say something roughly equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way that C++ or C# are different. (I'll leave others to judge how subtly different they are.) > > > Haskell is dramatically and fundamentally different. You can't just 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's many tales of woe on StackOverflow. Just No. > > > I really don't know how you could have got any experience with Haskell and say "subtly". > > > I suggest you unlearn everything you think you know about Haskell, and strike out in an entirely different direction. The best approach would be to spend a few days playing with lambda calculus. (That's what I did before tackling Haskell.) > > > > > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") > > > Lambda calculus is an excellent place for beginners to start. What could be easier to learn? It's certainly easier than grokking a Turing machine; and much easier than Haskell: less than a handful of primitives yet can compute anything computable. > > > > And since the concepts are seldom described in concrete enough and time-honored programming language terms (by comparison to other programming languages) > > > I'm guessing that the concepts you're talking of simply don't correspond to anything in time-honoured (procedural) programming. Anybody writing about Haskell (including anybody writing the User Guide) assumes a base level of understanding of Haskell. You've clearly veered off the track and haven't yet reached base. Remember the User Guide builds on top of the Language Report. > > > (On the point of 'time-honoured': lambda calculus is almost exactly the same age as Turing machines. The first well-known programming language using lambda-calculus ideas (LISP 1966) is almost exactly the same age as the first OOP language (Simula 1967). Which is the more time-honoured?) > > > You do have a point that the terminology in Haskell is often mysterious > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", and he felt this was wise. > > > Yes many have yearned for a more warm-and-cuddly term than "monad". But the terminology barrier starts before that. > > > Haskell typeclasses are not 'classes' in any sense recognisable from OOP. There are no objects, no hidden state, no destructive assignment. We might go back to February 1988 when a strawman for what became typeclasses used OVERLOAD/INSTANCE. > > > AntC > > > > > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 4 > Date: Thu, 16 Sep 2021 14:21:58 -0400 > From: Carter Schonwald > To: David Feuer , GHC Users List > , ghc-devs > Cc: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > These are great ideas! Could you please create a ghc tracker ticket with a > tiny examples or two? > > There may be specific technical reasons we might not be able to do so for > type synonyms in ghc, but I don’t see any obvious barriers in the case of > David’s excellent idea, I’ve def seen lots of great code out there where > you’d really want either associated pattern synonyms or to bundle pattern > synonyms with the exported public interface for a type class. > > I’m sure there’s some devil in the details but these sound lovely. Step -1 > is making up 1-2 toy examples and explaining what and why you want it on a > ghc ticket! > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > > > I would like that, along with the ability to bundle patterns with classes. > > > > On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > > > >> Is there currently a way to 'bundle' a pattern with a type alias? And if > >> not, could that capability be added to the PatternSynonyms GHC extension? > >> (Is this the right place to ask, or should I be asking a GHC list?) > >> > >> --Keith > >> Sent from my phone with K-9 Mail. > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 5 > Date: Thu, 16 Sep 2021 15:08:45 -0400 > From: David Feuer > To: Carter Schonwald > Cc: "haskell-cafe at haskell.org" , GHC Users > List , ghc-devs > > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Here's an example: > > pattern State :: (s -> (a, s)) -> State s a > pattern State f <- (coerce . runStateT -> f) where > State = state > > This would be very nice to bundle with the State type synonym. > > On Thu, Sep 16, 2021, 2:22 PM Carter Schonwald > wrote: > > > These are great ideas! Could you please create a ghc tracker ticket with a > > tiny examples or two? > > > > There may be specific technical reasons we might not be able to do so for > > type synonyms in ghc, but I don’t see any obvious barriers in the case of > > David’s excellent idea, I’ve def seen lots of great code out there where > > you’d really want either associated pattern synonyms or to bundle pattern > > synonyms with the exported public interface for a type class. > > > > I’m sure there’s some devil in the details but these sound lovely. Step > > -1 is making up 1-2 toy examples and explaining what and why you want it on > > a ghc ticket! > > > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > > > >> I would like that, along with the ability to bundle patterns with classes. > >> > >> On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > >> > >>> Is there currently a way to 'bundle' a pattern with a type alias? And if > >>> not, could that capability be added to the PatternSynonyms GHC extension? > >>> (Is this the right place to ask, or should I be asking a GHC list?) > >>> > >>> --Keith > >>> Sent from my phone with K-9 Mail. > >>> _______________________________________________ > >>> Haskell-Cafe mailing list > >>> To (un)subscribe, modify options or view archives go to: > >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >>> Only members subscribed via the mailman list are allowed to post. > >> > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > > > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 6 > Date: Thu, 16 Sep 2021 15:12:57 -0400 > From: David Feuer > To: Carter Schonwald > Cc: "haskell-cafe at haskell.org" , GHC Users > List , ghc-devs > > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > Here's a class example: > > class (MFoldable t, Monoid t) => Sequence t where > singleton :: Elem t -> t > .... > > One might wish to write pattern synonyms for viewing the ends of a > sequence, like the ones in Data.Sequence, and bundle them with this class. > > On Thu, Sep 16, 2021, 2:22 PM Carter Schonwald > wrote: > > > These are great ideas! Could you please create a ghc tracker ticket with a > > tiny examples or two? > > > > There may be specific technical reasons we might not be able to do so for > > type synonyms in ghc, but I don’t see any obvious barriers in the case of > > David’s excellent idea, I’ve def seen lots of great code out there where > > you’d really want either associated pattern synonyms or to bundle pattern > > synonyms with the exported public interface for a type class. > > > > I’m sure there’s some devil in the details but these sound lovely. Step > > -1 is making up 1-2 toy examples and explaining what and why you want it on > > a ghc ticket! > > > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > > > >> I would like that, along with the ability to bundle patterns with classes. > >> > >> On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > >> > >>> Is there currently a way to 'bundle' a pattern with a type alias? And if > >>> not, could that capability be added to the PatternSynonyms GHC extension? > >>> (Is this the right place to ask, or should I be asking a GHC list?) > >>> > >>> --Keith > >>> Sent from my phone with K-9 Mail. > >>> _______________________________________________ > >>> Haskell-Cafe mailing list > >>> To (un)subscribe, modify options or view archives go to: > >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >>> Only members subscribed via the mailman list are allowed to post. > >> > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > > > > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > ------------------------------ > > End of Haskell-Cafe Digest, Vol 217, Issue 16 > ********************************************* From michael.eugene.turner at gmail.com Fri Sep 17 05:15:28 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Fri, 17 Sep 2021 14:15:28 +0900 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: I might have missed your link to "Monoid" because my attention fell on "monoid mappend". Sorry for that. "The contribution of each element to the final result is combined with an accumulator via an /operator/ function. The operator may be explicitly provided by the caller as in `foldr` or may be implicit as in `length`. In the case of `foldMap`, the caller provides a function mapping each element into a suitable 'Monoid', which makes it possible to merge the per-element contributions via that monoid's `mappend` function." This is a little better, but I'd write it this way, I think. "Folds take operators as arguments. In some cases, it's implicit, as in the function "length". These operators are applied to elements when lazy evaluation requires it, with a fold 'accumulator' as one of the operands. 'foldMap' uses a function (implicit? explicit?) that maps elements into . . . ." And this is where I bog down, because I don't know what makes a monoid 'suitable' or even really what a monoid is -- it's been a long time (25 years or so) since my last abstract algebra course. I don't doubt that you're doing something good here. It's just that I'm frustrated about what's in the way of benefitting from it. I gather that there's something about the algebraic properties of folds that makes some code easier to write and understand, once you have the underlying concepts fully understood. My biggest problem is probably out of scope for what you're working on: I need motivating examples. I've used folds in other programming languages. But how they can be algebraically leveraged is still beyond me. I still remember installing a Haskell command-line parser for my project code and marveling that "semigroup" was one of its dependencies. My main concern is whether I can use Haskell for a natural-language processing project. Here, I started on a long Haskell primer for linguists, in case I leave any useful code behind that linguists might need to maintain. But also, I sometimes find that understanding comes from writing. Did I write it clearly? If not, is it because I don't really understand it? If I don't, writing tells me where I need to dig deeper. "Haskell in Plain English: A Primer for the Lexical Semanticist" https://docs.google.com/document/d/1GIDWMbFBAaOZc-jxOu1Majt6UNzCpg4vxMGeydb421M/edit In that piece (no, don't read it if you're not interested in linguistics), I remark that the algebraic facet of Haskell practice may not be very useful for natural language parsing and understanding. The truth is: I'd prefer to be proven wrong about that. This area is so hard, we need all the good tools we can get. IF abstract algebra could be useful for this application, I want it. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry On Fri, Sep 17, 2021 at 1:24 PM Viktor Dukhovni wrote: > > On Fri, Sep 17, 2021 at 11:27:12AM +0900, Michael Turner wrote: > > > > I am also curious whether I'm part of the solution or part of the > > > precipitate. I've recently contributed new documentation for > > > Data.Foldable and Data.Traversable: > > > > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > > > OK: > > > > "Merging the contribution of the current element with an accumulator > > value from a partial result is performed by an operator function, > > either explicitly provided by the caller as in foldr, implicit count > > as in length, or partly implicit as in foldMap (where each element is > > mapped into a Monoid, and the monoid's mappend operator performs the > > merge)." > > > > Let me tell you how I tried to read that lo-o-ong sentence. > > If I may trouble you just a bit longer, I'd like to ask whether the > problem is the phrasing, or the selection of subject matter. If the > latter, then any defects in the phrasing are perhaps moot. > > Supposing I rephrase the same thing as: > > The contribution of each element to the final result is combined with an > accumulator via an /operator/ function. The operator may be explicitly > provided by the caller as in `foldr` or may be implicit as in `length`. In > the case of `foldMap`, the caller provides a function mapping each element > into a suitable 'Monoid', which makes it possible to merge the per-element > contributions via that monoid's `mappend` function. > > Does that help? At all? Enough? The word "Monoid" hyperlinks to the > documentation of that class, and I thought it fair to reference Monoids > in the reference documentation for a module that defines `foldMap`. > > If the above is helpful, I am not too proud to rewrite any paragraphs > that are poorly phrased, if there is some merit in the subject matter. > > I don't think the module overview can be a beginner tutorial, that's > more the domain of books, ... I think that the descriptive prose in the reference > docs that follows the function synopses just need to cover any concepts > and API behaviours that don't immediately follow from those synopses. > > A rough guide for me were Unix manpages, where e.g. setsockopt(2) is not > a networking tutorial, and yet still has a bunch of useful prose, and not > just function signatures. > > -- > Viktor. From ietf-dane at dukhovni.org Fri Sep 17 05:57:58 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Fri, 17 Sep 2021 01:57:58 -0400 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: On Fri, Sep 17, 2021 at 02:15:28PM +0900, Michael Turner wrote: > "The contribution of each element to the final result is combined with an > accumulator via an /operator/ function. The operator may be explicitly > provided by the caller as in `foldr` or may be implicit as in `length`. In > the case of `foldMap`, the caller provides a function mapping each element > into a suitable 'Monoid', which makes it possible to merge the per-element > contributions via that monoid's `mappend` function." > > This is a little better, I'll open an MR for that then, it is likely to be seen as an overall improvement by others too I think. This is perhaps another opportunity for any other wordsmithing suggestions that anyone wants to make while the patient is on the operating table... > but I'd write it this way, I think. > > "Folds take operators as arguments. In some cases, it's implicit, as > in the function "length". OK, but perhaps s/it's/the operator is/ > These operators are applied to elements when > lazy evaluation requires it, Laziness has little to do with this. Whether the result of the fold contains lazy thunks or is strict, the conceptual value is still a result of applying the operator to the next element and the accumulated intermediate result built from the initial value and any previous elements whose contributions have already been folded into the accumulator (whether lazily or strictly). > with a fold 'accumulator' as one of the > operands. 'foldMap' uses a function (implicit? explicit?) that maps > elements into . . . ." The `foldMap` method takes an explicit `a -> m` function that maps each element into a Monoid (a structure with an associative binary operation and an element for this binary operation). Combining elements in monoid is often called "concatenation", and thus `foldMap f` just applies (f :: a -> m) for each element `a` and then concatenates all the `m` values using the Monoid's binary operator (mappend or infix <>). I was indeed assuming that the reader has already seen Monoids, or, if not, that the reader would just move on and read the parts that don't require knowledge of Monoids. Since such a reader wouldn't be using foldMap until Monoids "click". > And this is where I bog down, because I don't know what makes a monoid > 'suitable' or even really what a monoid is -- it's been a long time > (25 years or so) since my last abstract algebra course. Well it is "suitable" when the fold you want to perform is in fact concatenation of monoid elements computed from the elements of the foldable structure. > I don't doubt that you're doing something good here. It's just that > I'm frustrated about what's in the way of benefitting from it. I > gather that there's something about the algebraic properties of folds > that makes some code easier to write and understand, once you have the > underlying concepts fully understood. Yes, that's the idea. Folds are either strict reductions (iterative strict computation of an accumulator value), or essentially coroutines (corecursion) that lazily yield a stream of values (a lazy list or similar). Folds can be left-associative or right associative, and the typically the left-associative ones are best used strictly, and the right-associative ones are best used corecursively, but as with many rules there are exceptions, and the pages of prose try to lay the groundwork for reasoning about how to use the library properly. > My biggest problem is probably out of scope for what you're working > on: I need motivating examples. I've used folds in other programming > languages. Laziness makes it it possible to use folds as coroutines that lazily yield a sequence of values. This is not possible in strict languages, where you'd need explicit support for coroutines (generators) via something like a "yield" primitive. Haskell's lazy lists, used exactly once are coroutines when the elements are computed as needed. When the fold operator is building a recursively defined structure with a lazy tail, you use `foldr` corecursively to yield the head and then when demanded the tail. When the operator is strict ((+), (*), ...) you'd use `foldl'`. > My main concern is whether I can use Haskell for a natural-language > processing project. Can't help you there, I do DNS, TLS, cryptography, ... don't know anything about NLP. > In that piece (no, don't read it if you're not interested in > linguistics), I remark that the algebraic facet of Haskell practice > may not be very useful for natural language parsing and understanding. > The truth is: I'd prefer to be proven wrong about that. This area is > so hard, we need all the good tools we can get. IF abstract algebra > could be useful for this application, I want it. Haskell is quite well suited to writing parsers, DSLs, compilers, largely painless multi-threaded concurrency (which is my primary use-case), nice database APIs (e.g. Hasql), nice Web APIs (e.g. Servant and Wai)... Perhaps also NLP, but I woudn't know about that. My impression was that NLP is substantially neural-net based these days... -- Viktor. From dominik.schrempf at gmail.com Fri Sep 17 05:56:51 2021 From: dominik.schrempf at gmail.com (Dominik Schrempf) Date: Fri, 17 Sep 2021 07:56:51 +0200 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: <87wnnfoi7b.fsf@gmail.com> I really enjoyed reading through the documentation Viktor has contributed, thank you! No doubt, as Michael writes, things can be improved, but in my opinion it is much better than before. Actually, I was astonished to see such a nice overview on Hackage! And this directly relates to the core of the problem Michael is addressing: I am used to having "adequate" documentation on Hackage, and these paragraphs stood out. Viktor Dukhovni writes: > On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > >> The real problem is that the writing sucks. Not all of it -- and some >> contributors to the community are stellar writers, even if, in the >> snarkish commentary they write about Haskell and the community, I >> don't quite get all the jokes. But speaking as a contributor to the >> Haskell.org wiki -- to which I contribute at times out of hope that >> clarifying points I understand will also lead to more clarity for >> myself -- I have to say it: the writing sucks. > > Can you be a bit more specific about which sort of writing you find > sufficiently unsatisfactory to say "the writing sucks"? > > * Books about Haskell > - Introductory (e.g. http://learnyouahaskell.com/) > - Comprehensive (e.g. the classic Real World Haskell) > - Topic focused (e.g. the IMHO rather excellent Parallel and > Concurrent Haskell) > - Theory focused (e.g. > https://bartoszmilewski.com/category/category-theory/) > - ... > * The library reference documentation? > * The GHC User's Guide? > * The Haskell report? > * Blog posts? > * The Haskell Wiki? > * r/haskell? > * Haskell mailing lists? > ... > * All of the above??? > > I am also curious whether I'm part of the solution or part of the > precipitate. I've recently contributed new documentation for > Data.Foldable and Data.Traversable: > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > are these a step in the right direction, or examples of more writing > that sucks? These are reference documentation, not beginner tutorials, > so a more detailed write up of the concepts, pitfalls, ... things to > keep in mind when using library, ... > > More of that sort of thing would help me to more quickly learn to use > some of the libraries that lack this sort of overview prose, but perhaps > what you're looking for is something else? From anthony.d.clayden at gmail.com Fri Sep 17 07:01:46 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Fri, 17 Sep 2021 19:01:46 +1200 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 Message-ID: >> "The seeds of your confusion are very evident from your message". > The seeds of your unsubstantiated assumptions about me are very evident from yours. OK Michael, I can see I'm not helping. I'll stop. On NLP (a topic on which I have some expertise), I'll save you time in your search: Haskell is not suitable. Use a NLP tool. Programming languages and their semantics are so unlike natural languages as to be useless. I found your "primer for the lexical semanticist" to be full of strained and unhelpful analogies. I was surprised it omitted mention of Montague Grammar -- which draws from Lambda calculus/Combinators, and would be the obvious go-to _if_ Haskell were to be applicable. On unsubstantiated assumptions: > I started programming at 15. Me too. (Dartmouth BASIC on a teletype over a dial-up line to a timeshare service.) > It's been a very rare year, even after leaving the software profession, when I didn't write at least some code, learning new things in the process. Me ditto. > Which means I've been looking at programming languages and how to implement things at the most appropriate level of abstraction possible for just a few months shy of fifty years. For me, a few months over fifty years. (BTW nothing you've said persuades me away from recommending the best way to learn Haskell is via Lambda-calculus.) AntC -------------- next part -------------- An HTML attachment was scrubbed... URL: From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Fri Sep 17 07:19:27 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 17 Sep 2021 08:19:27 +0100 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: <20210917071927.GD21030@cloudinit-builder> On Fri, Sep 17, 2021 at 01:57:58AM -0400, Viktor Dukhovni wrote: > Laziness makes it it possible to use folds as coroutines that lazily > yield a sequence of values. This is not possible in strict languages, > where you'd need explicit support for coroutines (generators) via > something like a "yield" primitive. Wouldn't an explicit thunk datatype (that takes a lambda as a "constructor") be sufficient? I can't see why going all the way to coroutines would be required. Tom From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Fri Sep 17 07:50:50 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 17 Sep 2021 08:50:50 +0100 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: References: Message-ID: <20210917075050.GE21030@cloudinit-builder> On Fri, Sep 17, 2021 at 01:43:01PM +0900, Michael Turner wrote: > I finally got (most of?) what monads really mean for practical > programming when none other than Simon Peyton-Jones said F# called a > very similar construct "workflow," a word he likes. Was it literally just a single sentence introducing a new word for a concept that made you "get it"? Could you elaborate? This is really quite remarkable. Tom From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Fri Sep 17 07:58:47 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 17 Sep 2021 08:58:47 +0100 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: Message-ID: <20210917075847.GF21030@cloudinit-builder> Michael, I have an offer for you (in fact two): 1. I will collaborate with you to produce the guide to Haskell's evaluation that *you* would want to read. 2. I will collaborate with you to write the NLP tool that you want to write in Haskell. I can't do these without collaborating with someone like you. I simply don't know what someone else wants to read. Like you I find exhortions to "learn lambda calculus" and explanations that "Haskell is lazy which means it doesn't evaluate expressions until needed" to be thoroughly unhelpful. I understand the evaluation of Haskell (rather, GHC) through analogies to C and Python (in part). Please let me know what you think about my offers. Tom On Fri, Sep 17, 2021 at 12:05:09PM +0900, Michael Turner wrote: > And I forgot to add: selling power is important, but clarity is too. > Selling ergonomics is important, but clarity is too. > > I once learned a very, very powerful language: APL. Now, to be sure, > there was a market obstacle -- it had a very extended character set. > But IBM probably thought, "A very powerful language will sell! And > that means we'll sell a lot more of the specialized IBM Selectric > type-balls! This could be our most profitable programming language > ever, especially considering that type-balls wear out eventually and > have to be replaced! What's not to like?" I suppose you could say APL > was ergonomic, because you spent a lot of your keyboard time just > looking for the right keytop symbol, and it slowed you way down. > > The thing is, most code that actually gets used, and even makes money, > is read more than it's written. Software expense is mostly in the > maintenance life-cycle, and I think that's still true, even in these > days of Agile and CI -- it's just that the effort of the former > "maintenance phase" bleeds more into the early phases. I'd love to be > so fluent in Haskell that I can appreciate its superior ergonomics, > and I speak as a former RSI casualty. But frustration over feeling > powerless every time GHC barfs out another error message you don't > understand only leads to muscle tension which can inflame chronic RSI, > and Haskell is pretty frustrating, starting out. Of course, I'm sure > people will tell me to just relax and take my time. But I have a lot > of other things to do. > > I've noticed an interesting metric for Haskell: github activity is > more sharply distributed over weekend days than just about any other > language in the top 40. Is it basically an intellectual hobby > language, outside of academia? I'm evaluating Haskell for a project, > one for which I'd like to report some serious progress by the time a > certain conference rolls around in March. Months ago, I started with > some confidence that I'd have settled the question. Maybe I'd even > have a demo all written in Haskell by March, if Haskell seemed right. > I'm far less confident now. > > I'd been warned that the learning curve is steep and long. If my > complaints about documentation sound anguished, it's for a reason: a > lot of the problems of getting traction on the slope trace back (for > me, at least) to writing by people so steeped in Haskell that they no > longer remember how they themselves absorbed it, the better to explain > it. And, as Simon Peyton-Jones says in one talk, in the early years, > the language designers had the incredible luxury of academia -- as he > admits, they could spend literally years being confused about the > right path forward, at various points, and it didn't matter much for > their careers or their goals. That's years of steeping too. And it > shows. I don't have years. I have months. And lots of other things I > have to get done. > > On Fri, Sep 17, 2021 at 11:27 AM Michael Turner > wrote: > > > > On Fri, Sep 17, 2021 at 5:52 AM Viktor Dukhovni wrote: > > > > > > On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > > > > > > > The real problem is that the writing sucks. [snip] > > > > Vikor: > > > Can you be a bit more specific about which sort of writing you find > > > sufficiently unsatisfactory to say "the writing sucks"? > > > > It's an axiom of sales: quality is what the customer says it is. > > You'll evaluate writing differently depending on what sort of audience > > you're in. > > > > I'm in this audience: > > > > -- I have a lot of programming experience with a variety of languages. > > I have limited patience with writing that feels like it's talking down > > to me. > > > > -- I have limited patience for a language whose main appeal seems to > > be to a niche audience of programmers who want to learn a language in > > part because they've been told it's a challenge -- I'm not seeking > > status among other programmers. ("Ooh, he knows Haskell. You have to > > be really smart to write Haskell.") > > > > -- I prefer a presentation that's clear and concise, with a > > significant reliance on diagrams that show conceptual relations. A > > picture of how something works is worth a thousand words that tell me > > how great something was, or how great it's going to be once I'm > > proficient. > > > > > > > > * Books about Haskell > > > - Introductory (e.g. http://learnyouahaskell.com/) > > > > I started here. I was initially drawn in by the welcoming chattiness. > > It got old, fast. Fonzie? Really? How many young programmers today > > even know the TV series Happy Days? Waste of page-space. (But see > > above -- that's MY reaction. Audiences will differ.) > > > > > - Comprehensive (e.g. the classic Real World Haskell) > > > > I hadn't looked at this before. So I looked today. > > > > Uh-oh: the introductory part reminds me of that old joke about the IBM > > salesman, back in the mainframe days, when getting a computer up and > > running the customer's application could take months, from hardware > > order to production data processing: The salesman sits on the edge of > > the bed on his honeymoon night, telling his bride out great it's going > > to be. > > > > The first bit of code shows how you'd write a very short function > > (courtesy of "take", not of any inherent feature of Haskell's > > programming model) to get the k least elements in a list. A claim is > > made: it's faster because of laziness. > > > > Um, really? Sorting is O(n log n) upper bound no matter what. There's > > a vaguely game-theoretic proof of this I found delightful back in > > college, and it came to mind when I read that. How would you arrange > > numbers in a list so that, no matter what sort algorithm you used, > > there would be no way in general to get the k smallest elements > > without a full sort? Well, maybe the authors mean "faster on average, > > counting using the number of comparisons"? Oh, but wait: isn't there > > some overhead for implementing laziness? Hm, why aren't they saying > > something here? > > > > My eyes glaze over all the IBM salesman honeymoon bridal suite talk, > > so I go to chapter one. I skip through all the stuff I already know, > > and at the end of the chapter, there's bit of code: count the number > > of lines in input. After months of looking at Haskell code (but a few > > weeks of not looking at it) I can't quite get it, the way I'd almost > > instantly get it if it was written in a more conventional programming > > language. It's just an exercise in putting some code in a file and > > running it. Supposedly it will build confidence. It has the opposite > > effect on me. But maybe it's explicated in the next chapter? > > > > I turn to chapter two, hoping that the line-counter would be > > explicated. Oh no: long IBM honeymoon-night salesman talk about Why > > Types Are Good. Oh, fuck you! I already know why types are good! I > > even know what's bad about the otherwise-good type systems of several > > programming languages! WHY ARE YOU WASTING MY TIME?! > > > > > - Topic focused (e.g. the IMHO rather excellent Parallel and > > > Concurrent Haskell) > > > > It may be excellent if you're already up to speed on Haskell. I'm a > > newbie drowning in writing that's not for me. > > > > > - Theory focused (e.g. > > > https://bartoszmilewski.com/category/category-theory/) > > > > I bailed halfway through a video from Philip Wadler, a talk about > > Categories for the Working Hacker (or something) because he still > > hadn't said anything about how knowing category theory was useful to, > > uh, you know, a working hacker? I ran across a blog that said: forget > > category theory. It won't help you. At least not starting out. > > > > > * The library reference documentation? > > > > Pretty impenetrable for a newbie, though that's hardly unusual for a > > newbie to any language, with reference docs. > > > > > * The GHC User's Guide? > > > > Been a while since I looked at it, but not much easier, as I remember. > > > > > * The Haskell report? > > > > Haven't read it. > > > > > * Blog posts? > > > > So far, only helpful when they are honest and tell me that I'm having > > trouble for some very good reasons. I feel less alone. I feel less > > stupid. > > > > > * The Haskell Wiki? > > > > Very sloppy, much neglected. I put in some improvements to articles, > > but a certain syndrome is very much in evidence: it seems mostly > > written by Haskell experts who can't seem to get back into a newbie > > mindset (and who maybe never had a mindset like mine), and who often > > jump from IBM honeymoon salesman talk straight into unnecessarily > > complex examples. > > > > > * r/haskell? > > > > Sometimes helpful. > > > > > * Haskell mailing lists? > > > > When you're being told curtly, "Learn lambda calculus", or someone > > can't answer your question about something but instead of saying "I > > don't know where you'd find that", gives you an answer to a question > > you didn't ask, you're not on a truly beginner-friendly newbies list. > > Other mailing lists take up topics that feel way over my head at this > > point. > > > > > * All of the above??? > > > > So far, pretty much. > > > > > I am also curious whether I'm part of the solution or part of the > > > precipitate. I've recently contributed new documentation for > > > Data.Foldable and Data.Traversable: > > > > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > > > OK: > > > > "Merging the contribution of the current element with an accumulator > > value from a partial result is performed by an operator function, > > either explicitly provided by the caller as in foldr, implicit count > > as in length, or partly implicit as in foldMap (where each element is > > mapped into a Monoid, and the monoid's mappend operator performs the > > merge)." > > > > Let me tell you how I tried to read that lo-o-ong sentence. > > > > "Merging the contribution of the current element--" > > > > Um, you didn't introduce "current element", so "the current element" > > is confusing. It feels like you're starting in the middle. And wait, > > is the current element being merged, or is some kind of contribution > > /from/ the current element being merged? I guess since Haskell is > > lazy, it could be the latter . . . > > > > "--with an accumulator value--" > > > > Coming from Erlang, I just call them "accumulators". So is an > > accumulator value different from an accumulator or . . . what? > > > > "--from a partial result--" > > > > So, it's a partial result in the form of the accumulator? Or "the > > contribution of the current element"? I kinda-sorta feels like it must > > be the accumulator, so, plunging onward . . . > > > > "--is performed by an operator function" > > > > Uh-oh: passive voice sentence construction. And "operator function" is > > . . . well, all operators are functions in Haskell, so it's performed > > by an operator, but-- > > > > I could go on for a while, but let it suffice to say, long before I'm > > halfway through this sentence, the cognitive load is starting to crush > > me. How many times will I have to read it to understand it? Well, I > > probably won't understand it with multiple readings. Because there I > > see "monoid" toward the end (no hyperlink), and again, that feeling: > > Haskell may be very powerful indeed, but a lot of the writing makes me > > want to kill somebody. (Don't worry. I don't kill people.) > > > > Now, remember what I said about target audiences? I can imagine a > > reader who would actually admire that sentence. But that reader is > > someone who has used foldr and foldr a lot, who has a pretty adequate > > mental model already, and thinks: "Good. It summarizes all my > > knowledge, while refreshing me on a point that hasn't mattered much in > > my coding so far." The sentence may contain a few unnecessary words, > > but for such a reader, these are like drops of water rolling off a > > duck's back. It might read more smoothly with a few added words, but > > this reader is mentally inserting such smoothing linkages in his > > internal conceptual schema, probably without even subvocalizing those > > words. > > > > Still, there might be a way to break it up and with not many added > > words, satisfy more readers. Do you want to do that? Do you need to do > > that? Let me tell you something, either way: it'll probably be harder > > for you than writing the sentence you wrote. > > > > This is an interesting point illustrated in a different field, by Paul > > Krugman, a few years after he started writing about economics for > > layman-reader outlets like Salon: It was actually harder for him to > > write the same number of words for a layman, on a given topic, than it > > was for him to write a journal article to pass peer review. He had to > > think: "What might my readers NOT quite understand yet? How can I get > > them there quickly?" > > > > As an economist, he could think in graphs and equations. And he could > > easily say things like "there could be labor-activism-related > > variations in how downward-sticky wages become in a liquidity trap." > > If he said that to your average economist, he could count on being > > understood. It was actually harder for him to write something more > > generally accessible, like, "When consumers have snapped their purses > > shut in a recession and during the slow recovery, most bosses will > > prefer to lay workers off to cut costs, rather than cut wages to keep > > workers on payroll. However, others may not. It could depend on how > > much that boss fears that the workers would go out on strike in > > response to a pay cut." It was harder for him than for me (I'm not an > > economist) because first he had to realize: if I say it in the way > > that's most obvious to me, most people won't get it. > > > > > are these a step in the right direction, or examples of more writing > > > that sucks? These are reference documentation, not beginner tutorials, > > > so a more detailed write up of the concepts, pitfalls, ... things to > > > keep in mind when using library, ... > > > > As I say, for a certain kind of reader, that sentence that I only > > stumble around in may be fine for your audience. But Haskell has > > apparently plateaued, after surviving a phase where, as Simon > > Peyton-Jones points out, almost all new languages die. So it's a > > question of what you want to be a part of: a relatively insular > > community? Or a drive to expand the community, by making learning > > easier? > > > > > More of that sort of thing would help me to more quickly learn to use > > > some of the libraries that lack this sort of overview prose, but perhaps > > > what you're looking for is something else? > > > > I've written at very low levels -- e.g., very tight assembly code to > > fit into a 512-byte disk boot block on up to very high levels -- > > attempts at cognitive-linguistic modeling of spreading activation in > > conceptual networks, in Erlang. My big problem has been finding a > > treatment of Haskell that roots its model of computation in something > > more computationally concrete than, say, lambda calculus or category > > theory. Like I could find for Lisp. Like I could find for Prolog. Like > > I could find for Erlang. > > > > I once tried to get Erlang up on a platform with an old C compiler, > > and got a little obsessive about it: there was a nasty stack crash > > before I even got to the Erlang shell prompt, and I basically had to > > resort to laborious breakpoint debugging to find the problematic line > > of code. On the way down to that line, I passed data structures and C > > code that had me thinking, "So that's how they do that. Well, but, it > > was already pretty obvious. It had to be something like that. But > > guys: clean up your code, OK?" > > > > I have yet to gain any such feeling for Haskell. I once thought I > > could-- I found a very small 'compiler' for Haskell on github, written > > in C, that actually worked for a lot of things. (It could swallow > > Prelude easily.) It was maybe 2000 lines of code. I was encouraged > > that it generated some kind of VM assembly code. Alas, the VM code > > emitted turned out to be for some graph-combinator thingie I didn't > > understand. And I laid the code-study project aside. I thought, > > certainly, somebody somewhere has drawn a not-too-abstract data > > structure diagram that shows how thunks relate to data, and how type > > variables are represented, and how they directly or indirectly link to > > thunks. With that, I could think about the Haskell execution model > > with my eyes wandering around the diagram: this happens here, the next > > thing happens over there, opportunities for parallelism happen on this > > branch, dispatching of tasks happens down inside this thing, and it > > all comes back here. And that's why my output looks the way it does. > > Mystery solved! > > > > Now, if somebody harumphs and remonstrates, "That's not how you should > > try to understand Haskell!" I'm just going to reply, "Maybe it's not > > how YOU came to YOUR understanding. But look: I'm not you, OK? I'm me. > > I need to understand how a language works from the nuts and bolts on > > up. I won't feel confident enough in it otherwise." > > > > But I'd only say it that way if I was in a mood to be relatively polite. From kindaro at gmail.com Fri Sep 17 08:30:37 2021 From: kindaro at gmail.com (Ignat Insarov) Date: Fri, 17 Sep 2021 13:30:37 +0500 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: Hello Viktor. Thank you for your continuous effort. I have been writing Haskell for years now and even getting paid for it. I care nothing for the laws — I rarely apply equational reasoning. I am a visual person, to me intuitive grasp is the tool of choice. I also know a few newcomers to Haskell and I am certain they make zero use of the laws. My thus informed view is that laws are fine in the end and useless at the start. On Fri, 17 Sept 2021 at 04:48, Viktor Dukhovni wrote: > > On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > > > The last time I went to look at the laws it took me a couple minutes to > > find them. I use them to write instances. Pretty important, IMO. > > I agree the laws are important to document, I just don't think they > belong at the top of the module. The beginner to intermediate users > will be using the library and existing instances for some time before > they start to write their own instances. > > If more modules adopt something like the style of the new Data.Foldable, > experienced users will know to look for the laws at the end, if not > still present at the top of the module. > > Of course perhaps the community would prefer the original Laws first > format, I'm fine with that emerging as the consensus. Perhaps worthy > of a separate thread (made it so). > > Of course the conjectured users who might most benefit from not being > intimidated by being exposed to laws before they're ready to understand > them might not be present on this forum... > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From simon at joyful.com Fri Sep 17 09:16:16 2021 From: simon at joyful.com (Simon Michael) Date: Thu, 16 Sep 2021 23:16:16 -1000 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools Message-ID: Hi Michael, I thoroughly enjoyed and appreciate this thread. You're right, our writing and communication often and in many places does fall short of what's needed (sucks). I think your core point, that writing and communicating better could achieve more than tool-building, is very good. I saw some of the books and docs did not work for you. If you have the time to try another, I'd love to know how Mark Watson's "Haskell Tutorial and Cookbook" strikes you. It's the one I (and only I, for some reason) often recommend to practical minded haskellers. (Pardon the unthreaded reply) From ietf-dane at dukhovni.org Fri Sep 17 09:42:42 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Fri, 17 Sep 2021 05:42:42 -0400 Subject: [Haskell-cafe] Corecursive folds viewed as coroutines? In-Reply-To: <20210917071927.GD21030@cloudinit-builder> References: <20210917071927.GD21030@cloudinit-builder> Message-ID: <9ECBCCB2-7E67-4ED7-B1CC-B0149207A67A@dukhovni.org> > On 17 Sep 2021, at 3:19 am, Tom Ellis wrote: > > On Fri, Sep 17, 2021 at 01:57:58AM -0400, Viktor Dukhovni wrote: >> Laziness makes it it possible to use folds as coroutines that lazily >> yield a sequence of values. This is not possible in strict languages, >> where you'd need explicit support for coroutines (generators) via >> something like a "yield" primitive. > > Wouldn't an explicit thunk datatype (that takes a lambda as a > "constructor") be sufficient? I can't see why going all the way to > coroutines would be required. Yes, sure, coroutines are but one model. Indeed explicit thunks can simulate laziness in a strict language. But then there's the mind bending recent challenge on r/haskell to implement (in Haskell) a general `foldr` using nothing from the underlying Foldable except its `foldl'` (otherwise, any and all Haskell tools are fine). The implementation needs to be no less lazy than the real `foldr`, forcing no more of the structures spine or elements than `foldr` would. It turns out that pretty much the only solutions reported all use coroutines (unsafePerformIO and forkIO) in order to synchronise demand-driven yields of the structure elements by a strict left fold. This tells me that `foldr` as coroutine is one version of the truth, even if there are alternative valid mental models. {-# LANGUAGE LambdaCase #-} import Control.Concurrent import qualified Data.Foldable as F import System.IO.Unsafe foldr :: Foldable f => (a -> b -> b) -> b -> f a -> b foldr f z xs = unsafeDupablePerformIO $ do next <- newEmptyMVar lock <- newEmptyMVar let yield k a = seq (unsafeDupablePerformIO $ putMVar next (Just a) >> takeMVar lock) k loop = takeMVar next >>= \case Nothing -> return z Just a -> unsafeInterleaveIO (putMVar lock () >> loop) >>= pure . f a forkIO $ F.foldl' yield (pure ()) xs >> putMVar next Nothing loop -- Viktor. From michael.eugene.turner at gmail.com Fri Sep 17 09:54:50 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Fri, 17 Sep 2021 18:54:50 +0900 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: <20210917075847.GF21030@cloudinit-builder> References: <20210917075847.GF21030@cloudinit-builder> Message-ID: On Fri, Sep 17, 2021 at 4:58 PM Tom Ellis wrote: > > Michael, I have an offer for you (in fact two): > > > 1. I will collaborate with you to produce the guide to Haskell's > evaluation that *you* would want to read. > > 2. I will collaborate with you to write the NLP tool that you want to > write in Haskell. I think if I write anything long, it would first have to be my "Haskell in Plain English: A Guide for Lexical Semanticists." It's for linguists who have a little programming experience, and who would like to learn more, both for their research and as a resume item in case linguistics (or rather, the linguistics they specialized in) doesn't work out as a career. This happens. Another bit of code I was reviving (NSM-DALIA, in Prolog, now on github) uses a grammar for Tok Pisin, a Papuan creole, developed by a former NSM researcher who is now reduced to teaching high school. This is sad. Her papers remain unpublished. I'd like to get her work out there, and maybe an NLP treatment will do the trick. I plan to steer clear of the NLP approaches in vogue. I think they are due to run out of steam. This is only my opinion, of course, but I believe that, unless something dramatic happens, Deep Learning is not going to cut it for real natural language understanding. For my target audience (lexical semanticists), they couldn't be less interested anyway. And for graduate students of linguistics who don't make the academic cut (or find they don't want to, or fall out of the academic race out of life necessity), I think they'd learn enough about software concepts to impress hiring managers in interviews. ("Don't know Deep Learning? No problem. We'll train you up on it! When can you start?") If my code (and the primer) works out for this audience, the audience will be pretty small. At this point, maybe it's just a few dozen people in the world, though there is potential for wider audiences. I've chosen Natural Semantic Metalanguage (NSM) not just out of an enduring affection for it. It's also because I feel it's small enough, yet general enough, for its NLP issues to be comprehensively treated at book length, while the code for it (exclusive of GUI frills) would almost certainly be small enough to develop and explain in the book. I'd like to make it clear at the outset that this is for lexical semanticists pursuing the NSM approach. (And perhaps even opposing it! Linguistics is very factional!) Still, I plan to leave explanatory notes for other readers, including people who are not even linguists -- maybe even people who have felt defeated about Haskell in the past, who like my style and how I develop tutorial points, and who have a general interest in natural language. > I can't do these without collaborating with someone like you. I > simply don't know what someone else wants to read. So much of good writing is just figuring out an audience. As I wrote to Viktor above, the section he presented to me in case I had trouble with it could be absolutely ideal for someone with more grounding. They could admire the sentence I struggled with, for how it encapsulates their understanding while refreshing their memory. I'm not sure that gearing a piece toward what /I/ would like to read is a much bigger audience, however, than my "Plain English" chapter. It's a good question. If I had to suggest an approach you could try on your own, it would be this: (1) Smack the reader on page 1 with Core Haskell's almost-C-level entity-relationship diagram, but say something like, "Wow, that's way too much, right? But by the end of this piece, you'll know what it all means, and you'll even be able to go back to it when Haskell behavior is confusing." (2) The next diagram might be just the data structural diagram for some kind of Tiny Lisp. Lists, the Haskell equivalent of atoms, a hash table, how binding happens, etc. (3) Then add lazy evaluation, which is actually where the whole original Haskell group started, so fair enough, right? (4...) Keep adding layers and examples of how to figure out execution paths by looking at each incarnation ... finally .... (n, for small n) The same diagram -- now seen very differently by the reader. > Like you I find exhortions to "learn lambda calculus" and explanations > that "Haskell is lazy which means it doesn't evaluate expressions > until needed" to be thoroughly unhelpful. I understand the evaluation > of Haskell (rather, GHC) through analogies to C and Python (in part). I think some readers on this thread have interpreted me as saying that we should show equivalent code, when exact equivalents are impossible, and in some cases, there is no equivalent anyway except in some even more obscure programming language. Well, I think I qualified my comparative approach, as being a series of starting points for explaining important /differences/. But what I'm getting is knee-jerk reactions to the Heresy of Comparing Anything to the Incomparable Haskell. > Please let me know what you think about my offers. I think the diagram sequence strategy I outline above could /potentially/ fit into the Plain English idea. And there may be /some/ diagrams out there that could be adapted from the Tiny Lisp level, as a starting point. It could be better to think "drawing" first, rather than "writing." Followed by very natural-sounding pseudocode that refers to the drawings, to give a sense of how a Haskell interpreter would interpret. And I'd suggest the power of Silly Examples. Some tutorials get too abstract too soon. Others reflect some onus to get the reader started on something that feels practical, like organizing bookshelves primarily by topic, then by alphabetical order of author last name. But Simple and Silly can be quite disarming AND quite illuminating. For example: Monads are workflows. Workflows can be illustrated as little workers at little desks, each with their own form-processing task, and directional inboxes and outboxes that can be connected by arrows. The Maybe monad seems ridiculously small to be diagrammed that way. But you can still stay disarmingly silly with a little complexity, THEN show the Maybe monad, saying, "See? The concept of workflow applies even to extraordinarily simple workflows, though exactly what kind of dunce they'd have manning THAT kind of desk is a real exercise in imagining bureaucratic inefficiency." For example: a society with a flat 10% tax, but most people are so dumb they can't calculate their taxes. So they send in a form with their year's incomes. But the Internal Revenue Service is almost as stupid, so they outsource it to a company, Gimme Ten Percent, Inc. where people are slightly smarter -- though they still need to use a desk calculator to figure 10% of a number. Then the IRS gets the numbers back, and forwards the results from the outsourced firm to the taxpayers: a tax bill. But some people are so dumb they don't even fill in their income. They just send in the form, with that field blank. Ah: there's the Maybe type! (Sort of.) So that's a different response supplied by Gimme Ten Percent, Inc.: "Please fill in your income. You left it blank on the form." But one day, the CEO for Gimme Ten Percent comes in and announces, "There's this private company that needs us to figure out a recent 10% surcharge on their bills. Except sometimes the number is way too smudgy. Our workflow works for that too!" "There's just one problem, boss." "What's that?" "The girl who knows how to work our single desk calculator got an offer from a Wall Street boutique private-equity firm. They offered to train her in Haskell." OK, that's a stupid joke, but the point is made: Gimme Ten Percent needs an abstraction for its workflows, because it has a government client now, but also a private-sector client with almost exactly the same requirements. I think it beats hearing from Fonzie, over and over, that one should never lend out one's grease-laden comb. And it makes for some pretty concise diagrams -- including Gimme Ten Percent, the Internal Revenue Service of the Republic of Stone Idiots, the Flat Tax Form, the hapless taxpayers, the child-prodigy desk-calculator operator (these things are relative, right?), etc. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry On Fri, Sep 17, 2021 at 4:58 PM Tom Ellis wrote: > > Michael, I have an offer for you (in fact two): > > > 1. I will collaborate with you to produce the guide to Haskell's > evaluation that *you* would want to read. > > 2. I will collaborate with you to write the NLP tool that you want to > write in Haskell. > > > I can't do these without collaborating with someone like you. I > simply don't know what someone else wants to read. > > Like you I find exhortions to "learn lambda calculus" and explanations > that "Haskell is lazy which means it doesn't evaluate expressions > until needed" to be thoroughly unhelpful. I understand the evaluation > of Haskell (rather, GHC) through analogies to C and Python (in part). > > Please let me know what you think about my offers. > > Tom > > > On Fri, Sep 17, 2021 at 12:05:09PM +0900, Michael Turner wrote: > > And I forgot to add: selling power is important, but clarity is too. > > Selling ergonomics is important, but clarity is too. > > > > I once learned a very, very powerful language: APL. Now, to be sure, > > there was a market obstacle -- it had a very extended character set. > > But IBM probably thought, "A very powerful language will sell! And > > that means we'll sell a lot more of the specialized IBM Selectric > > type-balls! This could be our most profitable programming language > > ever, especially considering that type-balls wear out eventually and > > have to be replaced! What's not to like?" I suppose you could say APL > > was ergonomic, because you spent a lot of your keyboard time just > > looking for the right keytop symbol, and it slowed you way down. > > > > The thing is, most code that actually gets used, and even makes money, > > is read more than it's written. Software expense is mostly in the > > maintenance life-cycle, and I think that's still true, even in these > > days of Agile and CI -- it's just that the effort of the former > > "maintenance phase" bleeds more into the early phases. I'd love to be > > so fluent in Haskell that I can appreciate its superior ergonomics, > > and I speak as a former RSI casualty. But frustration over feeling > > powerless every time GHC barfs out another error message you don't > > understand only leads to muscle tension which can inflame chronic RSI, > > and Haskell is pretty frustrating, starting out. Of course, I'm sure > > people will tell me to just relax and take my time. But I have a lot > > of other things to do. > > > > I've noticed an interesting metric for Haskell: github activity is > > more sharply distributed over weekend days than just about any other > > language in the top 40. Is it basically an intellectual hobby > > language, outside of academia? I'm evaluating Haskell for a project, > > one for which I'd like to report some serious progress by the time a > > certain conference rolls around in March. Months ago, I started with > > some confidence that I'd have settled the question. Maybe I'd even > > have a demo all written in Haskell by March, if Haskell seemed right. > > I'm far less confident now. > > > > I'd been warned that the learning curve is steep and long. If my > > complaints about documentation sound anguished, it's for a reason: a > > lot of the problems of getting traction on the slope trace back (for > > me, at least) to writing by people so steeped in Haskell that they no > > longer remember how they themselves absorbed it, the better to explain > > it. And, as Simon Peyton-Jones says in one talk, in the early years, > > the language designers had the incredible luxury of academia -- as he > > admits, they could spend literally years being confused about the > > right path forward, at various points, and it didn't matter much for > > their careers or their goals. That's years of steeping too. And it > > shows. I don't have years. I have months. And lots of other things I > > have to get done. > > > > On Fri, Sep 17, 2021 at 11:27 AM Michael Turner > > wrote: > > > > > > On Fri, Sep 17, 2021 at 5:52 AM Viktor Dukhovni wrote: > > > > > > > > On Wed, Sep 15, 2021 at 04:07:38PM +0900, Michael Turner wrote: > > > > > > > > > The real problem is that the writing sucks. [snip] > > > > > > Vikor: > > > > Can you be a bit more specific about which sort of writing you find > > > > sufficiently unsatisfactory to say "the writing sucks"? > > > > > > It's an axiom of sales: quality is what the customer says it is. > > > You'll evaluate writing differently depending on what sort of audience > > > you're in. > > > > > > I'm in this audience: > > > > > > -- I have a lot of programming experience with a variety of languages. > > > I have limited patience with writing that feels like it's talking down > > > to me. > > > > > > -- I have limited patience for a language whose main appeal seems to > > > be to a niche audience of programmers who want to learn a language in > > > part because they've been told it's a challenge -- I'm not seeking > > > status among other programmers. ("Ooh, he knows Haskell. You have to > > > be really smart to write Haskell.") > > > > > > -- I prefer a presentation that's clear and concise, with a > > > significant reliance on diagrams that show conceptual relations. A > > > picture of how something works is worth a thousand words that tell me > > > how great something was, or how great it's going to be once I'm > > > proficient. > > > > > > > > > > > * Books about Haskell > > > > - Introductory (e.g. http://learnyouahaskell.com/) > > > > > > I started here. I was initially drawn in by the welcoming chattiness. > > > It got old, fast. Fonzie? Really? How many young programmers today > > > even know the TV series Happy Days? Waste of page-space. (But see > > > above -- that's MY reaction. Audiences will differ.) > > > > > > > - Comprehensive (e.g. the classic Real World Haskell) > > > > > > I hadn't looked at this before. So I looked today. > > > > > > Uh-oh: the introductory part reminds me of that old joke about the IBM > > > salesman, back in the mainframe days, when getting a computer up and > > > running the customer's application could take months, from hardware > > > order to production data processing: The salesman sits on the edge of > > > the bed on his honeymoon night, telling his bride out great it's going > > > to be. > > > > > > The first bit of code shows how you'd write a very short function > > > (courtesy of "take", not of any inherent feature of Haskell's > > > programming model) to get the k least elements in a list. A claim is > > > made: it's faster because of laziness. > > > > > > Um, really? Sorting is O(n log n) upper bound no matter what. There's > > > a vaguely game-theoretic proof of this I found delightful back in > > > college, and it came to mind when I read that. How would you arrange > > > numbers in a list so that, no matter what sort algorithm you used, > > > there would be no way in general to get the k smallest elements > > > without a full sort? Well, maybe the authors mean "faster on average, > > > counting using the number of comparisons"? Oh, but wait: isn't there > > > some overhead for implementing laziness? Hm, why aren't they saying > > > something here? > > > > > > My eyes glaze over all the IBM salesman honeymoon bridal suite talk, > > > so I go to chapter one. I skip through all the stuff I already know, > > > and at the end of the chapter, there's bit of code: count the number > > > of lines in input. After months of looking at Haskell code (but a few > > > weeks of not looking at it) I can't quite get it, the way I'd almost > > > instantly get it if it was written in a more conventional programming > > > language. It's just an exercise in putting some code in a file and > > > running it. Supposedly it will build confidence. It has the opposite > > > effect on me. But maybe it's explicated in the next chapter? > > > > > > I turn to chapter two, hoping that the line-counter would be > > > explicated. Oh no: long IBM honeymoon-night salesman talk about Why > > > Types Are Good. Oh, fuck you! I already know why types are good! I > > > even know what's bad about the otherwise-good type systems of several > > > programming languages! WHY ARE YOU WASTING MY TIME?! > > > > > > > - Topic focused (e.g. the IMHO rather excellent Parallel and > > > > Concurrent Haskell) > > > > > > It may be excellent if you're already up to speed on Haskell. I'm a > > > newbie drowning in writing that's not for me. > > > > > > > - Theory focused (e.g. > > > > https://bartoszmilewski.com/category/category-theory/) > > > > > > I bailed halfway through a video from Philip Wadler, a talk about > > > Categories for the Working Hacker (or something) because he still > > > hadn't said anything about how knowing category theory was useful to, > > > uh, you know, a working hacker? I ran across a blog that said: forget > > > category theory. It won't help you. At least not starting out. > > > > > > > * The library reference documentation? > > > > > > Pretty impenetrable for a newbie, though that's hardly unusual for a > > > newbie to any language, with reference docs. > > > > > > > * The GHC User's Guide? > > > > > > Been a while since I looked at it, but not much easier, as I remember. > > > > > > > * The Haskell report? > > > > > > Haven't read it. > > > > > > > * Blog posts? > > > > > > So far, only helpful when they are honest and tell me that I'm having > > > trouble for some very good reasons. I feel less alone. I feel less > > > stupid. > > > > > > > * The Haskell Wiki? > > > > > > Very sloppy, much neglected. I put in some improvements to articles, > > > but a certain syndrome is very much in evidence: it seems mostly > > > written by Haskell experts who can't seem to get back into a newbie > > > mindset (and who maybe never had a mindset like mine), and who often > > > jump from IBM honeymoon salesman talk straight into unnecessarily > > > complex examples. > > > > > > > * r/haskell? > > > > > > Sometimes helpful. > > > > > > > * Haskell mailing lists? > > > > > > When you're being told curtly, "Learn lambda calculus", or someone > > > can't answer your question about something but instead of saying "I > > > don't know where you'd find that", gives you an answer to a question > > > you didn't ask, you're not on a truly beginner-friendly newbies list. > > > Other mailing lists take up topics that feel way over my head at this > > > point. > > > > > > > * All of the above??? > > > > > > So far, pretty much. > > > > > > > I am also curious whether I'm part of the solution or part of the > > > > precipitate. I've recently contributed new documentation for > > > > Data.Foldable and Data.Traversable: > > > > > > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:7 > > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Traversable.html#g:4 > > > > > > OK: > > > > > > "Merging the contribution of the current element with an accumulator > > > value from a partial result is performed by an operator function, > > > either explicitly provided by the caller as in foldr, implicit count > > > as in length, or partly implicit as in foldMap (where each element is > > > mapped into a Monoid, and the monoid's mappend operator performs the > > > merge)." > > > > > > Let me tell you how I tried to read that lo-o-ong sentence. > > > > > > "Merging the contribution of the current element--" > > > > > > Um, you didn't introduce "current element", so "the current element" > > > is confusing. It feels like you're starting in the middle. And wait, > > > is the current element being merged, or is some kind of contribution > > > /from/ the current element being merged? I guess since Haskell is > > > lazy, it could be the latter . . . > > > > > > "--with an accumulator value--" > > > > > > Coming from Erlang, I just call them "accumulators". So is an > > > accumulator value different from an accumulator or . . . what? > > > > > > "--from a partial result--" > > > > > > So, it's a partial result in the form of the accumulator? Or "the > > > contribution of the current element"? I kinda-sorta feels like it must > > > be the accumulator, so, plunging onward . . . > > > > > > "--is performed by an operator function" > > > > > > Uh-oh: passive voice sentence construction. And "operator function" is > > > . . . well, all operators are functions in Haskell, so it's performed > > > by an operator, but-- > > > > > > I could go on for a while, but let it suffice to say, long before I'm > > > halfway through this sentence, the cognitive load is starting to crush > > > me. How many times will I have to read it to understand it? Well, I > > > probably won't understand it with multiple readings. Because there I > > > see "monoid" toward the end (no hyperlink), and again, that feeling: > > > Haskell may be very powerful indeed, but a lot of the writing makes me > > > want to kill somebody. (Don't worry. I don't kill people.) > > > > > > Now, remember what I said about target audiences? I can imagine a > > > reader who would actually admire that sentence. But that reader is > > > someone who has used foldr and foldr a lot, who has a pretty adequate > > > mental model already, and thinks: "Good. It summarizes all my > > > knowledge, while refreshing me on a point that hasn't mattered much in > > > my coding so far." The sentence may contain a few unnecessary words, > > > but for such a reader, these are like drops of water rolling off a > > > duck's back. It might read more smoothly with a few added words, but > > > this reader is mentally inserting such smoothing linkages in his > > > internal conceptual schema, probably without even subvocalizing those > > > words. > > > > > > Still, there might be a way to break it up and with not many added > > > words, satisfy more readers. Do you want to do that? Do you need to do > > > that? Let me tell you something, either way: it'll probably be harder > > > for you than writing the sentence you wrote. > > > > > > This is an interesting point illustrated in a different field, by Paul > > > Krugman, a few years after he started writing about economics for > > > layman-reader outlets like Salon: It was actually harder for him to > > > write the same number of words for a layman, on a given topic, than it > > > was for him to write a journal article to pass peer review. He had to > > > think: "What might my readers NOT quite understand yet? How can I get > > > them there quickly?" > > > > > > As an economist, he could think in graphs and equations. And he could > > > easily say things like "there could be labor-activism-related > > > variations in how downward-sticky wages become in a liquidity trap." > > > If he said that to your average economist, he could count on being > > > understood. It was actually harder for him to write something more > > > generally accessible, like, "When consumers have snapped their purses > > > shut in a recession and during the slow recovery, most bosses will > > > prefer to lay workers off to cut costs, rather than cut wages to keep > > > workers on payroll. However, others may not. It could depend on how > > > much that boss fears that the workers would go out on strike in > > > response to a pay cut." It was harder for him than for me (I'm not an > > > economist) because first he had to realize: if I say it in the way > > > that's most obvious to me, most people won't get it. > > > > > > > are these a step in the right direction, or examples of more writing > > > > that sucks? These are reference documentation, not beginner tutorials, > > > > so a more detailed write up of the concepts, pitfalls, ... things to > > > > keep in mind when using library, ... > > > > > > As I say, for a certain kind of reader, that sentence that I only > > > stumble around in may be fine for your audience. But Haskell has > > > apparently plateaued, after surviving a phase where, as Simon > > > Peyton-Jones points out, almost all new languages die. So it's a > > > question of what you want to be a part of: a relatively insular > > > community? Or a drive to expand the community, by making learning > > > easier? > > > > > > > More of that sort of thing would help me to more quickly learn to use > > > > some of the libraries that lack this sort of overview prose, but perhaps > > > > what you're looking for is something else? > > > > > > I've written at very low levels -- e.g., very tight assembly code to > > > fit into a 512-byte disk boot block on up to very high levels -- > > > attempts at cognitive-linguistic modeling of spreading activation in > > > conceptual networks, in Erlang. My big problem has been finding a > > > treatment of Haskell that roots its model of computation in something > > > more computationally concrete than, say, lambda calculus or category > > > theory. Like I could find for Lisp. Like I could find for Prolog. Like > > > I could find for Erlang. > > > > > > I once tried to get Erlang up on a platform with an old C compiler, > > > and got a little obsessive about it: there was a nasty stack crash > > > before I even got to the Erlang shell prompt, and I basically had to > > > resort to laborious breakpoint debugging to find the problematic line > > > of code. On the way down to that line, I passed data structures and C > > > code that had me thinking, "So that's how they do that. Well, but, it > > > was already pretty obvious. It had to be something like that. But > > > guys: clean up your code, OK?" > > > > > > I have yet to gain any such feeling for Haskell. I once thought I > > > could-- I found a very small 'compiler' for Haskell on github, written > > > in C, that actually worked for a lot of things. (It could swallow > > > Prelude easily.) It was maybe 2000 lines of code. I was encouraged > > > that it generated some kind of VM assembly code. Alas, the VM code > > > emitted turned out to be for some graph-combinator thingie I didn't > > > understand. And I laid the code-study project aside. I thought, > > > certainly, somebody somewhere has drawn a not-too-abstract data > > > structure diagram that shows how thunks relate to data, and how type > > > variables are represented, and how they directly or indirectly link to > > > thunks. With that, I could think about the Haskell execution model > > > with my eyes wandering around the diagram: this happens here, the next > > > thing happens over there, opportunities for parallelism happen on this > > > branch, dispatching of tasks happens down inside this thing, and it > > > all comes back here. And that's why my output looks the way it does. > > > Mystery solved! > > > > > > Now, if somebody harumphs and remonstrates, "That's not how you should > > > try to understand Haskell!" I'm just going to reply, "Maybe it's not > > > how YOU came to YOUR understanding. But look: I'm not you, OK? I'm me. > > > I need to understand how a language works from the nuts and bolts on > > > up. I won't feel confident enough in it otherwise." > > > > > > But I'd only say it that way if I was in a mood to be relatively polite. From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Fri Sep 17 10:15:05 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 17 Sep 2021 11:15:05 +0100 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools In-Reply-To: References: <20210917075847.GF21030@cloudinit-builder> Message-ID: <20210917101505.GA3781@cloudinit-builder> On Fri, Sep 17, 2021 at 06:54:50PM +0900, Michael Turner wrote: > On Fri, Sep 17, 2021 at 4:58 PM Tom Ellis > wrote: > > Michael, I have an offer for you (in fact two): > > > > 1. I will collaborate with you to produce the guide to Haskell's > > evaluation that *you* would want to read. > > > > 2. I will collaborate with you to write the NLP tool that you want to > > write in Haskell. > > I think if I write anything long, it would first have to be my > "Haskell in Plain English: A Guide for Lexical Semanticists." Fair enough. > > I can't do these without collaborating with someone like you. I > > simply don't know what someone else wants to read. > > So much of good writing is just figuring out an audience. As I wrote > to Viktor above, the section he presented to me in case I had trouble > with it could be absolutely ideal for someone with more grounding. > They could admire the sentence I struggled with, for how it > encapsulates their understanding while refreshing their memory. Yes indeed. The audience that I write for is myself since that's the audience I know. I am interested in writing for a more general audience but I don't have motivation at the moment to do so without a member of that general audience on the team. > I'm not sure that gearing a piece toward what /I/ would like to read > is a much bigger audience I suspect the group of people who are interested in yet frustrated by Haskell is *far* bigger than the group of people who are already familiar with Haskell! > If I had to suggest an approach you could try on your own, it would > be this: Thank you for the suggestion. I will bear it in mind if I decide to tackle this in the future. Tom From allbery.b at gmail.com Fri Sep 17 12:02:13 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 17 Sep 2021 08:02:13 -0400 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 17 In-Reply-To: References: Message-ID: On Thu, Sep 16, 2021 at 11:57 PM Michael Turner < michael.eugene.turner at gmail.com> wrote: > Wow, someone on this thread said of me, from what I wrote on the > beginner's list, "He's trying to translate Haskell to C/C++." > Actually no, they were talking about someone on StackOverflow. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael.eugene.turner at gmail.com Fri Sep 17 12:59:03 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Fri, 17 Sep 2021 21:59:03 +0900 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 20 In-Reply-To: References: Message-ID: On Thu, Sep 16, 2021 at 11:57 PM Michael Turner < michael.eugene.turner at gmail.com> wrote: > Wow, someone on this thread said of me, from what I wrote on the > beginner's list, "He's trying to translate Haskell to C/C++." > Brandon Allbery: "Actually no, they were talking about someone on StackOverflow." I'm afraid Anthony Clayden actually WAS talking about me: https://mail.haskell.org/pipermail/haskell-cafe/2021-September/134468.html (Or am I missing some Haskeller in-joke about StackOverflow?) Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry On Fri, Sep 17, 2021 at 9:08 PM wrote: > > Send Haskell-Cafe mailing list submissions to > haskell-cafe at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > or, via email, send a message with subject or body 'help' to > haskell-cafe-request at haskell.org > > You can reach the person managing the list at > haskell-cafe-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Haskell-Cafe digest..." > > > Today's Topics: > > 1. Re: Haskell's "historical futurism" needs better writing, not > better tools (Tom Ellis) > 2. Re: Haskell-Cafe Digest, Vol 217, Issue 17 (Brandon Allbery) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Fri, 17 Sep 2021 11:15:05 +0100 > From: Tom Ellis > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: <20210917101505.GA3781 at cloudinit-builder> > Content-Type: text/plain; charset=us-ascii > > On Fri, Sep 17, 2021 at 06:54:50PM +0900, Michael Turner wrote: > > On Fri, Sep 17, 2021 at 4:58 PM Tom Ellis > > wrote: > > > Michael, I have an offer for you (in fact two): > > > > > > 1. I will collaborate with you to produce the guide to Haskell's > > > evaluation that *you* would want to read. > > > > > > 2. I will collaborate with you to write the NLP tool that you want to > > > write in Haskell. > > > > I think if I write anything long, it would first have to be my > > "Haskell in Plain English: A Guide for Lexical Semanticists." > > Fair enough. > > > > I can't do these without collaborating with someone like you. I > > > simply don't know what someone else wants to read. > > > > So much of good writing is just figuring out an audience. As I wrote > > to Viktor above, the section he presented to me in case I had trouble > > with it could be absolutely ideal for someone with more grounding. > > They could admire the sentence I struggled with, for how it > > encapsulates their understanding while refreshing their memory. > > Yes indeed. The audience that I write for is myself since that's the > audience I know. I am interested in writing for a more general > audience but I don't have motivation at the moment to do so without a > member of that general audience on the team. > > > I'm not sure that gearing a piece toward what /I/ would like to read > > is a much bigger audience > > I suspect the group of people who are interested in yet frustrated by > Haskell is *far* bigger than the group of people who are already > familiar with Haskell! > > > If I had to suggest an approach you could try on your own, it would > > be this: > > Thank you for the suggestion. I will bear it in mind if I decide to > tackle this in the future. > > Tom > > > ------------------------------ > > Message: 2 > Date: Fri, 17 Sep 2021 08:02:13 -0400 > From: Brandon Allbery > To: Michael Turner > Cc: haskell-cafe > Subject: Re: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 17 > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > On Thu, Sep 16, 2021 at 11:57 PM Michael Turner < > michael.eugene.turner at gmail.com> wrote: > > > Wow, someone on this thread said of me, from what I wrote on the > > beginner's list, "He's trying to translate Haskell to C/C++." > > > > Actually no, they were talking about someone on StackOverflow. > > -- > brandon s allbery kf8nh > allbery.b at gmail.com > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > ------------------------------ > > End of Haskell-Cafe Digest, Vol 217, Issue 20 > ********************************************* From barak at pearlmutter.net Fri Sep 17 16:13:01 2021 From: barak at pearlmutter.net (Barak A. Pearlmutter) Date: Fri, 17 Sep 2021 17:13:01 +0100 Subject: [Haskell-cafe] Numerics (was: Re: Trouble with asinh) Message-ID: The numerics in Haskell have not been carefully vetted, for a variety of reasons. Not just under MS Windows, even under Linux. Here's an example: atan has drastic loss of precision in the imaginary direction around zero in the complex domain. $ ghci GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help Prelude> :m + Data.Complex Prelude Data.Complex> tan (1e-20 :+ 0) 1.0e-20 :+ 0.0 Prelude Data.Complex> atan (1e-20 :+ 0) 1.0e-20 :+ (-0.0) Prelude Data.Complex> tan (0 :+ 1e-20) 0.0 :+ 1.0e-20 Prelude Data.Complex> atan (0 :+ 1e-20) 0.0 :+ (-0.0) Although there have been amazing efforts to use fancy PLT methods to improve the numerics of programs using source-to-source transformations and such, the boring janitorial work of checking and fixing numeric issues in the standard library doesn't seem to attract people. To be fair, it isn't my cup of tea either... From lists at richarde.dev Fri Sep 17 17:02:09 2021 From: lists at richarde.dev (Richard Eisenberg) Date: Fri, 17 Sep 2021 17:02:09 +0000 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: <20210917075050.GE21030@cloudinit-builder> References: <20210917075050.GE21030@cloudinit-builder> Message-ID: <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> > On Sep 17, 2021, at 3:50 AM, Tom Ellis wrote: > > On Fri, Sep 17, 2021 at 01:43:01PM +0900, Michael Turner wrote: >> I finally got (most of?) what monads really mean for practical >> programming when none other than Simon Peyton-Jones said F# called a >> very similar construct "workflow," a word he likes. > > Was it literally just a single sentence introducing a new word for a > concept that made you "get it"? Could you elaborate? This is really > quite remarkable. For me, coming from a mostly Java background (but with a healthy dollop of functional programming thrown in the mix -- but no Haskell), the phrase that unlocked monads was "programmable semicolon". Richard -------------- next part -------------- An HTML attachment was scrubbed... URL: From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Fri Sep 17 17:11:06 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 17 Sep 2021 18:11:06 +0100 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> Message-ID: <20210917171106.GI25255@cloudinit-builder> On Fri, Sep 17, 2021 at 05:02:09PM +0000, Richard Eisenberg wrote: > > On Sep 17, 2021, at 3:50 AM, Tom Ellis wrote: > > > > On Fri, Sep 17, 2021 at 01:43:01PM +0900, Michael Turner wrote: > >> I finally got (most of?) what monads really mean for practical > >> programming when none other than Simon Peyton-Jones said F# called a > >> very similar construct "workflow," a word he likes. > > > > Was it literally just a single sentence introducing a new word for a > > concept that made you "get it"? Could you elaborate? This is really > > quite remarkable. > > For me, coming from a mostly Java background (but with a healthy > dollop of functional programming thrown in the mix -- but no > Haskell), the phrase that unlocked monads was "programmable > semicolon". I'm curious what "unlock" means here. Do you mean you could understand the definition of the monad class after coming across "programmable semicolon" but not before? Or do you mean you understood the *purpose* of monads, but not necessarily how one would go about implementing them? Or something else? From carter.schonwald at gmail.com Fri Sep 17 17:16:21 2021 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 17 Sep 2021 13:16:21 -0400 Subject: [Haskell-cafe] Numerics (was: Re: Trouble with asinh) In-Reply-To: References: Message-ID: Hey Barak, is Common Lisp the only extant language to take those issues seriously or are there other examples or better ones? (i bought the common lisp book a year or so ago because its one of the few references i could that talk about language/ library design for numerics / branch cuts etc) please edumacate me :) -Carter On Fri, Sep 17, 2021 at 12:18 PM Barak A. Pearlmutter wrote: > The numerics in Haskell have not been carefully vetted, for a variety > of reasons. Not just under MS Windows, even under Linux. Here's an > example: atan has drastic loss of precision in the imaginary direction > around zero in the complex domain. > > $ ghci > GHCi, version 8.8.4: https://www.haskell.org/ghc/ :? for help > Prelude> :m + Data.Complex > > Prelude Data.Complex> tan (1e-20 :+ 0) > 1.0e-20 :+ 0.0 > > Prelude Data.Complex> atan (1e-20 :+ 0) > 1.0e-20 :+ (-0.0) > > Prelude Data.Complex> tan (0 :+ 1e-20) > 0.0 :+ 1.0e-20 > > Prelude Data.Complex> atan (0 :+ 1e-20) > 0.0 :+ (-0.0) > > Although there have been amazing efforts to use fancy PLT methods to > improve the numerics of programs using source-to-source > transformations and such, the boring janitorial work of checking and > fixing numeric issues in the standard library doesn't seem to attract > people. To be fair, it isn't my cup of tea either... > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From b at chreekat.net Fri Sep 17 18:00:07 2021 From: b at chreekat.net (Bryan Richter) Date: Fri, 17 Sep 2021 21:00:07 +0300 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: <20210917171106.GI25255@cloudinit-builder> References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> <20210917171106.GI25255@cloudinit-builder> Message-ID: I myself heard "programmable semicolon" sometime after monads had clicked for me, but I still appreciate it. To answer Tom's question, what these short single sentences do is explain the *purpose* of monads, which is really quite obscure at first. Listing sequential actions one after the other is so intuitive you see it everywhere. Take baking recipes as one example. Or assembly code. Or poems. Procedural programming languages let you use the same intuition for sequencing actions you've been using since you were carving hieroglyphics into obelisks. When a Haskeller says, "Monads are great! They let you chain effectful actions together!" it can take a very long time to understand they actually mean exactly what they're saying — the usual intuition is that sequencing actions can't possibly be a real problem, so you go round and round in circles trying to understand what "effectful" means, what "action" means, and how these oh-so-important "laws" have anything to do with it. A programmable semicolon cuts right to the truth: yes, really, functional programming had to work hard to solve *that* problem. I can understand why that viewpoint might be long-forgotten by those who were involved in the effort to solve it. :) And I appreciate that it was solved in such a general way that it can be applied to so many seemingly unrelated things! That's the beauty of mathematics! On Fri, 17 Sep 2021, 20.11 Tom Ellis, < tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote: > On Fri, Sep 17, 2021 at 05:02:09PM +0000, Richard Eisenberg wrote: > > > On Sep 17, 2021, at 3:50 AM, Tom Ellis < > tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote: > > > > > > On Fri, Sep 17, 2021 at 01:43:01PM +0900, Michael Turner wrote: > > >> I finally got (most of?) what monads really mean for practical > > >> programming when none other than Simon Peyton-Jones said F# called a > > >> very similar construct "workflow," a word he likes. > > > > > > Was it literally just a single sentence introducing a new word for a > > > concept that made you "get it"? Could you elaborate? This is really > > > quite remarkable. > > > > For me, coming from a mostly Java background (but with a healthy > > dollop of functional programming thrown in the mix -- but no > > Haskell), the phrase that unlocked monads was "programmable > > semicolon". > > I'm curious what "unlock" means here. Do you mean you could > understand the definition of the monad class after coming across > "programmable semicolon" but not before? Or do you mean you > understood the *purpose* of monads, but not necessarily how one would > go about implementing them? Or something else? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From blaze at rusty.zone Fri Sep 17 18:25:23 2021 From: blaze at rusty.zone (Andrey Sverdlichenko) Date: Fri, 17 Sep 2021 14:25:23 -0400 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: References: Message-ID: > Haskell's big problem right now is adoption. I'm not quite sure this is a problem. Haskell and its libraries are designed around math concepts, as opposed to CS concepts (semigroup vs IConcatenable). Learning it all but requires learning some algebra as well, thus a lower adoption rate is expected. Personally, I consider this math requirement a great educational benefit: raising the level of abstraction from "container" to "monoid" helps to make better design decisions. It may be an obstacle for someone who wants quickly put together a new product, but this is the wrong tool selected for a job. A book like "Category theory for programmers" (that exists) and "Algebra for programmers" (that I don't know about) may help with learning and provide practical examples, but explaining math without using math words sounds like a futile attempt. On Fri, Sep 17, 2021 at 12:58 AM Michael Turner < michael.eugene.turner at gmail.com> wrote: > "The seeds of your confusion are very evident from your message". > > The seeds of your unsubstantiated assumptions about me are very > evident from yours. > > "You can't just 'translate' an algorithm from OOP to Haskell" > > Wow, I'm either "trying to translate Haskell to C++" (someone else, > above) or trying to translate C++ to Haskell. > > I'm actually doing neither. I started by trying to understand this: > > https://www.stwing.upenn.edu/~wlovas/hudak/aug.pdf > > (And no, just because Haskell is great for writing little > special-purpose programming languages does not automatically mean it's > up to snuff for handling natural language.) > > I'd originally hoped to fully understand the rather short program in > that paper (full code, in two versions, elsewhere on Paul Jones aca > dite) by getting it to run again, then commenting the code as I began > to understand it. And then, on to more important issues for a fuller > Haskell implementation, issues described here > > https://www.aclweb.org/anthology/C94-2137.pdf > > and here > > http://www.lacus.org/volumes/23/22.sypniewski.pdf > > Both of which are references I dug up and supplied here > > https://en.wikipedia.org/wiki/Applicative_universal_grammar > > as I took the Wikipedia article from stub status to something less > stubby -- it actually started in this state: > > > https://en.wikipedia.org/w/index.php?title=Applicative_universal_grammar&diff=prev&oldid=1020447173 > > The ASCII-art diagrams you see there are output from code that I've > gotten working again. > > I learned about lazy evaluation in college, when I got interested in > how Lisp might implement it. I'm very familiar with the arguments for > purity, especially from learning Erlang some years ago (during which I > wrote my share of accumulator-based tail-recursive functions.) I > prefer static typing but hated the way C++ templates extended the > concept, mostly because the syntax error messages were so bad for so > long. My career includes a time in the late 80s when the kind of > computing power we have in our phones now with multicore processors > filled a box of hardware too heavy to lift. This was at a startup > where the founder was substantially inspired by this stream-oriented > single-assignment language: > > https://en.wikipedia.org/wiki/SISAL > > I started programming at 15. It's been a very rare year, even after > leaving the software profession, when I didn't write at least some > code, learning new things in the process. Which means I've been > looking at programming languages and how to implement things at the > most appropriate level of abstraction possible for just a few months > shy of fifty years. > > The arguments here are following a familiar pattern, one I see in > discussions of everything from programming to government policy. > > (1) I disagree with someone > (2) This person instantly assumes I must be ignorant of what they know > (3) They start Mansplaining It All To Me. > > This is particularly irksome when the person is actually considerably > more ignorant of the subject than I am. > > I'm still ignorant of most of Haskell, to be sure. However, I'm not > ignorant when it comes to writing. (Published articles on request.) A > great deal of what's written about Haskell, usually with very good > intentions, has proved useless to me. Have I had a stroke that leaves > me apparently unharmed, but actually no longer able to absorb a > different programming language? Was I always just too dumb to learn > Haskell? Somehow, I think it's more related to the writing. > > To some extent the community seems to recognize there's a problem -- > e.g., the Monad Tutorial Explosion. I finally got (most of?) what > monads really mean for practical programming when none other than > Simon Peyton-Jones said F# called a very similar construct "workflow," > a word he likes. Wow, plain English instead of a mathematical > abstraction that, in the math introductions, looks weirdly clunky to > me, if anything, but, in any case, very hard to relate to writing > better code. > > Lambda calculus? I have vague memories of Eugene Lawler > > https://en.wikipedia.org/wiki/Eugene_Lawler > > covering it when I took computing theory from him. And again, when I > was grading computing theory homework for this required course for > graduate students (for their prelim exams) for Richard Lipton > > https://en.wikipedia.org/wiki/Richard_Lipton > > in the fall term of 1980 at U.C. Berkeley. > > It's not that I'm too stupid to learn lambda calculus. It's that I > seriously doubt that refreshing my memory on the details is going to > add significantly more to my grasp of functional programming in > Haskell. > > I disagree with some people here. They jump to the conclusion that I'm > some ignorant moron. They also keep trying to sell Haskell as > something dramatically, fundamentally -- nay transcendentally! -- > different from anything I've ever known. > > Are you doing that? Stop. Just stop. Haskell's big problem right now > is adoption. And I'm telling you why adoption has been hard for me. > You lecture back, telling me things I already know, making sweeping > assumptions about me. When you do that, you're not part of the > solution to Haskell's biggest problem right now. You're part of the > problem. > > Regards, > Michael Turner > Executive Director > Project Persephone > 1-25-33 Takadanobaba > Shinjuku-ku Tokyo 169-0075 > Mobile: +81 (90) 5203-8682 > turner at projectpersephone.org > > Understand - http://www.projectpersephone.org/ > Join - http://www.facebook.com/groups/ProjectPersephone/ > Donate - http://www.patreon.com/ProjectPersephone > Volunteer - https://github.com/ProjectPersephone > > "Love does not consist in gazing at each other, but in looking outward > together in the same direction." -- Antoine de Saint-Exupéry > > On Fri, Sep 17, 2021 at 4:19 AM wrote: > > > > Send Haskell-Cafe mailing list submissions to > > haskell-cafe at haskell.org > > > > To subscribe or unsubscribe via the World Wide Web, visit > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > or, via email, send a message with subject or body 'help' to > > haskell-cafe-request at haskell.org > > > > You can reach the person managing the list at > > haskell-cafe-owner at haskell.org > > > > When replying, please edit your Subject line so it is more specific > > than "Re: Contents of Haskell-Cafe digest..." > > > > > > Today's Topics: > > > > 1. Re: Haskell's "historical futurism" needs better writing, not > > better tools (Richard Eisenberg) > > 2. Re: Haskell's "historical futurism" needs better writing, not > > better tools (Jeffrey Brown) > > 3. Re: Haskell's "historical futurism" needs better writing, not > > better tools (Gregory Guthrie) > > 4. Re: Bundle patterns with type aliases (Carter Schonwald) > > 5. Re: Bundle patterns with type aliases (David Feuer) > > 6. Re: Bundle patterns with type aliases (David Feuer) > > > > > > ---------------------------------------------------------------------- > > > > Message: 1 > > Date: Thu, 16 Sep 2021 14:05:19 +0000 > > From: Richard Eisenberg > > To: Anthony Clayden > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > > better writing, not better tools > > Message-ID: > > < > 010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000 at us-east-2.amazonses.com > > > > > > Content-Type: text/plain; charset="utf-8" > > > > I just want to pipe up and say I'm not comfortable with this response. > When I feel this way about writing on a forum, I normally contact the > author in private, but I think posting publicly here has its merits. I'm > hoping that the long correspondence AntC and I have had -- often with > opposing viewpoints but with mutual respect -- with withstand this email. > > > > Michael posted here expressing frustration with his experience learning > and using Haskell. In my opinion, he has spent too much time reading older > papers, written by experts for experts -- which Michael is not. I do not > fault Michael for this: these resources are sometimes what appear when > searching, and we as a community have done a poor job marshaling our > educational resources. (Michael, I just thought of a resource you might > find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource > attempting to do that marshaling. I am not vouching for it here, per se, > but I know others have found it useful.) > > > > However, Michael very specifically said that "just learn > lambda-calculus" was not helpful for him, and so I think it's unhelpful for > someone to respond with "just learn lambda-calculus". There are a number of > other statements in the email below which could be seen as belittling -- > also not helpful. > > > > Instead, I wish that we, as a community, could take posts like Michael's > at face value: this is the experience of someone who wants to learn > Haskell. While some of the conclusions stated in that post are > misunderstandings, it is not the sole fault of the learner for these > misunderstandings: instead, we must try to understand what about our > community and posted materials induced these misunderstandings, and then > seek to improve. Many people in Michael's situation may not have posted at > all -- and so this kind of information can be very hard to get. > > > > Michael, I have no silver bullet to offer to you to try to help you > here. I do tend to agree with AntC that you have developed some > misconceptions that are hindering your continued learning. The terminology > actively hurts here. (To be fair, the first Haskell standard pre-dates both > Java and C++, and so one could argue who got the terms wrong.) For my part, > I am trying to help with this situation both by trying to improve error > messages, and though my support of the Haskell Foundation's Haskell School > initiative (https://github.com/haskellfoundation/HaskellSchool). These > will take time to grow, but my hope is that a future person like you will > have an easier route in. > > > > In the meantime, I implore us to take all expressed experiences as > exactly that: the experience of the person writing. And if they say they > don't want X, please let's not feed them X. :) > > > > Richard > > > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden < > anthony.d.clayden at gmail.com> wrote: > > > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > > > The seeds of your confusion are very evident from your message. How to > back you out of whatever deep rabbit-hole you've managed to get your head > into? > > > > > > > ... Your average reader (already a programmer) would be better > served by a comparative approach: Here's how to say something in a couple > of other programming languages, here's how to say something roughly > equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the > way that C++ or C# are different. (I'll leave others to judge how subtly > different they are.) > > > > > > Haskell is dramatically and fundamentally different. You can't just > 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's > many tales of woe on StackOverflow. Just No. > > > > > > I really don't know how you could have got any experience with Haskell > and say "subtly". > > > > > > I suggest you unlearn everything you think you know about Haskell, and > strike out in an entirely different direction. The best approach would be > to spend a few days playing with lambda calculus. (That's what I did before > tackling Haskell.) > > > > > > > (I've actually been curtly informed on the beginners' list -- yes, > the beginner' list! -- that my problems of comprehension can be solved > simply: "Learn lambda calculus.") > > > > > > Lambda calculus is an excellent place for beginners to start. What > could be easier to learn? It's certainly easier than grokking a Turing > machine; and much easier than Haskell: less than a handful of primitives > yet can compute anything computable. > > > > > > > And since the concepts are seldom described in concrete enough and > time-honored programming language terms (by comparison to other programming > languages) > > > > > > I'm guessing that the concepts you're talking of simply don't > correspond to anything in time-honoured (procedural) programming. Anybody > writing about Haskell (including anybody writing the User Guide) assumes a > base level of understanding of Haskell. You've clearly veered off the track > and haven't yet reached base. Remember the User Guide builds on top of the > Language Report. > > > > > > (On the point of 'time-honoured': lambda calculus is almost exactly > the same age as Turing machines. The first well-known programming language > using lambda-calculus ideas (LISP 1966) is almost exactly the same age as > the first OOP language (Simula 1967). Which is the more time-honoured?) > > > > > > You do have a point that the terminology in Haskell is often mysterious > > > > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", > and he felt this was wise. > > > > > > Yes many have yearned for a more warm-and-cuddly term than "monad". > But the terminology barrier starts before that. > > > > > > Haskell typeclasses are not 'classes' in any sense recognisable from > OOP. There are no objects, no hidden state, no destructive assignment. We > might go back to February 1988 when a strawman for what became typeclasses > used OVERLOAD/INSTANCE. > > > > > > AntC > > > > > > > > > > > > > > > _______________________________________________ > > > Haskell-Cafe mailing list > > > To (un)subscribe, modify options or view archives go to: > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Only members subscribed via the mailman list are allowed to post. > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: < > http://mail.haskell.org/pipermail/haskell-cafe/attachments/20210916/08935eb4/attachment-0001.html > > > > > > ------------------------------ > > > > Message: 2 > > Date: Thu, 16 Sep 2021 09:34:09 -0500 > > From: Jeffrey Brown > > To: Richard Eisenberg > > Cc: haskell-cafe , Anthony Clayden > > > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > > better writing, not better tools > > Message-ID: > > 0dJT_M_WQc9Kqb8JyvdPf9ncPw at mail.gmail.com> > > Content-Type: text/plain; charset="utf-8" > > > > I strongly believe the best study strategy is to be unfaithful to any > > source or subtopic. When I want to learn something, I study whatever > aspect > > of it holds my interest, for only slightly longer than it continues to do > > so. If I continue to want to learn a topic, but lose interest in a > > particular source or subtopic, it's important to stop that particular > > avenue. Otherwise I'll lose motivation for the topic as a whole. > > > > The result is that, while I never learn (say) a language completely, I > > generally learn enough to do whatever I was trying to do. (Sometimes I > > learn enough to decide it's too hard -- and for cases in which that's > bound > > to happen, the quicker the better.) > > > > Almost nobody learns any language completely anyway, and most of those > > who do could have used their time better. Sacrifice is a superpower. > > > > On Thu, Sep 16, 2021 at 9:09 AM Richard Eisenberg > > wrote: > > > > > I just want to pipe up and say I'm not comfortable with this response. > > > When I feel this way about writing on a forum, I normally contact the > > > author in private, but I think posting publicly here has its merits. > I'm > > > hoping that the long correspondence AntC and I have had -- often with > > > opposing viewpoints but with mutual respect -- with withstand this > email. > > > > > > Michael posted here expressing frustration with his experience learning > > > and using Haskell. In my opinion, he has spent too much time reading > older > > > papers, written by experts for experts -- which Michael is not. I do > not > > > fault Michael for this: these resources are sometimes what appear when > > > searching, and we as a community have done a poor job marshaling our > > > educational resources. (Michael, I just thought of a resource you might > > > find useful: http://dev.stephendiehl.com/hask/ is an oft-linked > resource > > > attempting to do that marshaling. I am not vouching for it here, per > se, > > > but I know others have found it useful.) > > > > > > However, Michael very specifically said that "just learn > lambda-calculus" > > > was not helpful for him, and so I think it's unhelpful for someone to > > > respond with "just learn lambda-calculus". There are a number of other > > > statements in the email below which could be seen as belittling -- > also not > > > helpful. > > > > > > Instead, I wish that we, as a community, could take posts like > Michael's > > > at face value: this is the experience of someone who wants to learn > > > Haskell. While some of the conclusions stated in that post are > > > misunderstandings, it is not the sole fault of the learner for these > > > misunderstandings: instead, we must try to understand what about our > > > community and posted materials induced these misunderstandings, and > then > > > seek to improve. Many people in Michael's situation may not have > posted at > > > all -- and so this kind of information can be very hard to get. > > > > > > Michael, I have no silver bullet to offer to you to try to help you > here. > > > I do tend to agree with AntC that you have developed some > misconceptions > > > that are hindering your continued learning. The terminology actively > hurts > > > here. (To be fair, the first Haskell standard pre-dates both Java and > C++, > > > and so one could argue who got the terms wrong.) For my part, I am > trying > > > to help with this situation both by trying to improve error messages, > and > > > though my support of the Haskell Foundation's Haskell School > initiative ( > > > https://github.com/haskellfoundation/HaskellSchool). These will take > time > > > to grow, but my hope is that a future person like you will have an > easier > > > route in. > > > > > > In the meantime, I implore us to take all expressed experiences as > exactly > > > that: the experience of the person writing. And if they say they don't > want > > > X, please let's not feed them X. :) > > > > > > Richard > > > > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden < > anthony.d.clayden at gmail.com> > > > wrote: > > > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > > > The seeds of your confusion are very evident from your message. How to > > > back you out of whatever deep rabbit-hole you've managed to get your > head > > > into? > > > > > > > ... Your average reader (already a programmer) would be better > served > > > by a comparative approach: Here's how to say something in a couple of > > > other programming languages, here's how to say something roughly > > > equivalent in Haskell -- BUT, here's how it's subtly different in > Haskell. > > > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way > > > that C++ or C# are different. (I'll leave others to judge how subtly > > > different they are.) > > > > > > Haskell is dramatically and fundamentally different. You can't just > > > 'translate' an algorithm from OOP to Haskell. Many newbies try, and > there's > > > many tales of woe on StackOverflow. Just No. > > > > > > I really don't know how you could have got any experience with Haskell > and > > > say "subtly". > > > > > > I suggest you unlearn everything you think you know about Haskell, and > > > strike out in an entirely different direction. The best approach would > be > > > to spend a few days playing with lambda calculus. (That's what I did > before > > > tackling Haskell.) > > > > > > > (I've actually been curtly informed on the beginners' list -- yes, > the beginner' list! -- that my problems of comprehension can be solved > simply: "Learn lambda calculus.") > > > > > > > > > Lambda calculus is an excellent place for beginners to start. What > could > > > be easier to learn? It's certainly easier than grokking a Turing > machine; > > > and much easier than Haskell: less than a handful of primitives yet can > > > compute anything computable. > > > > > > > And since the concepts are seldom described in concrete enough and > > > time-honored programming language terms (by comparison to other > > > programming languages) > > > > > > I'm guessing that the concepts you're talking of simply don't > correspond > > > to anything in time-honoured (procedural) programming. Anybody writing > > > about Haskell (including anybody writing the User Guide) assumes a base > > > level of understanding of Haskell. You've clearly veered off the track > and > > > haven't yet reached base. Remember the User Guide builds on top of the > > > Language Report. > > > > > > (On the point of 'time-honoured': lambda calculus is almost exactly the > > > same age as Turing machines. The first well-known programming language > > > using lambda-calculus ideas (LISP 1966) is almost exactly the same age > as > > > the first OOP language (Simula 1967). Which is the more time-honoured?) > > > > > > You do have a point that the terminology in Haskell is often mysterious > > > > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", > and > > > he felt this was wise. > > > > > > Yes many have yearned for a more warm-and-cuddly term than "monad". But > > > the terminology barrier starts before that. > > > > > > Haskell typeclasses are not 'classes' in any sense recognisable from > OOP. > > > There are no objects, no hidden state, no destructive assignment. We > might > > > go back to February 1988 when a strawman for what became typeclasses > used > > > OVERLOAD/INSTANCE. > > > > > > AntC > > > > > > > > > > > > > > > _______________________________________________ > > > Haskell-Cafe mailing list > > > To (un)subscribe, modify options or view archives go to: > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Only members subscribed via the mailman list are allowed to post. > > > > > > > > > _______________________________________________ > > > Haskell-Cafe mailing list > > > To (un)subscribe, modify options or view archives go to: > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Only members subscribed via the mailman list are allowed to post. > > > > > > > > -- > > Jeff Brown | Jeffrey Benjamin Brown > > LinkedIn | Github > > | Twitter > > | Facebook > > | very old Website > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: < > http://mail.haskell.org/pipermail/haskell-cafe/attachments/20210916/e6a8f29b/attachment-0001.html > > > > > > ------------------------------ > > > > Message: 3 > > Date: Thu, 16 Sep 2021 15:28:16 +0000 > > From: Gregory Guthrie > > To: Richard Eisenberg , Anthony Clayden > > > > Cc: "haskell-cafe at haskell.org" > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > > better writing, not better tools > > Message-ID: > > < > DM6PR03MB4331EDE1A046D25E7209B90FA1DC9 at DM6PR03MB4331.namprd03.prod.outlook.com > > > > > > Content-Type: text/plain; charset="utf-8" > > > > Educational research and learning theory shows that learning anything > new is more effective and longer retained when it is connected to and > builds on prior knowledge. > > > > People may understand anything new if presented as a completely new set > of ideas or principles, but that knowledge is not persistent or long > remembered. > > > > I personally find Haskell a good example of this. When teaching it one > can show incrementally how it is the same in many ways as procedural > programming languages. Then how it improves on them with first-class > functions, currying, immutability, type abstractions, etc. These are all > important ideas that they will also see in other IP languages, just much > cleaner and more integrated in Haskell(!). > > > > Basic Haskell programs with these features can then be used as a bisis > for both appreciating the language features and design and FP in general, > and as a stepping stone to more advanced usages. > > > > Then introducing Functors, Monads, .... Are again an easy and well > motivated step for improving on their existing IP experience, and show both > nice abstractions and ideas, and a nice implementation and results. > > > > All of this connects to and builds on what they already know. > > > > Moving into all of the fancier type system features and pragmas, one > enters into a realm where Haskell programs are no longer simple enough to > easily read as they incorporate several levels of new abstractions and > syntax. > > > > But at least students have a good basis for further exploration, and an > appreciation of FP and Haskell. :-) > > > > > > > > From: Haskell-Cafe On Behalf Of > Richard Eisenberg > > Sent: Thursday, September 16, 2021 10:05 AM > > To: Anthony Clayden > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs better > writing, not better tools > > > > I just want to pipe up and say I'm not comfortable with this response. > When I feel this way about writing on a forum, I normally contact the > author in private, but I think posting publicly here has its merits. I'm > hoping that the long correspondence AntC and I have had -- often with > opposing viewpoints but with mutual respect -- with withstand this email. > > > > Michael posted here expressing frustration with his experience learning > and using Haskell. In my opinion, he has spent too much time reading older > papers, written by experts for experts -- which Michael is not. I do not > fault Michael for this: these resources are sometimes what appear when > searching, and we as a community have done a poor job marshaling our > educational resources. (Michael, I just thought of a resource you might > find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource > attempting to do that marshaling. I am not vouching for it here, per se, > but I know others have found it useful.) > > > > However, Michael very specifically said that "just learn > lambda-calculus" was not helpful for him, and so I think it's unhelpful for > someone to respond with "just learn lambda-calculus". There are a number of > other statements in the email below which could be seen as belittling -- > also not helpful. > > > > Instead, I wish that we, as a community, could take posts like Michael's > at face value: this is the experience of someone who wants to learn > Haskell. While some of the conclusions stated in that post are > misunderstandings, it is not the sole fault of the learner for these > misunderstandings: instead, we must try to understand what about our > community and posted materials induced these misunderstandings, and then > seek to improve. Many people in Michael's situation may not have posted at > all -- and so this kind of information can be very hard to get. > > > > Michael, I have no silver bullet to offer to you to try to help you > here. I do tend to agree with AntC that you have developed some > misconceptions that are hindering your continued learning. The terminology > actively hurts here. (To be fair, the first Haskell standard pre-dates both > Java and C++, and so one could argue who got the terms wrong.) For my part, > I am trying to help with this situation both by trying to improve error > messages, and though my support of the Haskell Foundation's Haskell School > initiative (https://github.com/haskellfoundation/HaskellSchool). These > will take time to grow, but my hope is that a future person like you will > have an easier route in. > > > > In the meantime, I implore us to take all expressed experiences as > exactly that: the experience of the person writing. And if they say they > don't want X, please let's not feed them X. :) > > > > Richard > > > > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden < > anthony.d.clayden at gmail.com> wrote: > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > The seeds of your confusion are very evident from your message. How to > back you out of whatever deep rabbit-hole you've managed to get your head > into? > > > > > ... Your average reader (already a programmer) would be better served > by a comparative approach: Here's how to say something in a couple of other > programming languages, here's how to say something roughly equivalent in > Haskell -- BUT, here's how it's subtly different in Haskell. > > > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way > that C++ or C# are different. (I'll leave others to judge how subtly > different they are.) > > > > > > Haskell is dramatically and fundamentally different. You can't just > 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's > many tales of woe on StackOverflow. Just No. > > > > > > I really don't know how you could have got any experience with Haskell > and say "subtly". > > > > > > I suggest you unlearn everything you think you know about Haskell, and > strike out in an entirely different direction. The best approach would be > to spend a few days playing with lambda calculus. (That's what I did before > tackling Haskell.) > > > > > > > > > (I've actually been curtly informed on the beginners' list -- yes, the > beginner' list! -- that my problems of comprehension can be solved simply: > "Learn lambda calculus.") > > > > > > Lambda calculus is an excellent place for beginners to start. What could > be easier to learn? It's certainly easier than grokking a Turing machine; > and much easier than Haskell: less than a handful of primitives yet can > compute anything computable. > > > > > > > And since the concepts are seldom described in concrete enough and > time-honored programming language terms (by comparison to other programming > languages) > > > > > > I'm guessing that the concepts you're talking of simply don't correspond > to anything in time-honoured (procedural) programming. Anybody writing > about Haskell (including anybody writing the User Guide) assumes a base > level of understanding of Haskell. You've clearly veered off the track and > haven't yet reached base. Remember the User Guide builds on top of the > Language Report. > > > > > > (On the point of 'time-honoured': lambda calculus is almost exactly the > same age as Turing machines. The first well-known programming language > using lambda-calculus ideas (LISP 1966) is almost exactly the same age as > the first OOP language (Simula 1967). Which is the more time-honoured?) > > > > > > You do have a point that the terminology in Haskell is often mysterious > > > > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", > and he felt this was wise. > > > > > > Yes many have yearned for a more warm-and-cuddly term than "monad". But > the terminology barrier starts before that. > > > > > > Haskell typeclasses are not 'classes' in any sense recognisable from > OOP. There are no objects, no hidden state, no destructive assignment. We > might go back to February 1988 when a strawman for what became typeclasses > used OVERLOAD/INSTANCE. > > > > > > AntC > > > > > > > > > > > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: < > http://mail.haskell.org/pipermail/haskell-cafe/attachments/20210916/cf601806/attachment-0001.html > > > > > > ------------------------------ > > > > Message: 4 > > Date: Thu, 16 Sep 2021 14:21:58 -0400 > > From: Carter Schonwald > > To: David Feuer , GHC Users List > > , ghc-devs < > ghc-devs at haskell.org> > > Cc: "haskell-cafe at haskell.org" > > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > > Message-ID: > > SGbqiCznhw at mail.gmail.com> > > Content-Type: text/plain; charset="utf-8" > > > > These are great ideas! Could you please create a ghc tracker ticket with > a > > tiny examples or two? > > > > There may be specific technical reasons we might not be able to do so for > > type synonyms in ghc, but I don’t see any obvious barriers in the case of > > David’s excellent idea, I’ve def seen lots of great code out there where > > you’d really want either associated pattern synonyms or to bundle pattern > > synonyms with the exported public interface for a type class. > > > > I’m sure there’s some devil in the details but these sound lovely. Step > -1 > > is making up 1-2 toy examples and explaining what and why you want it on > a > > ghc ticket! > > > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer > wrote: > > > > > I would like that, along with the ability to bundle patterns with > classes. > > > > > > On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > > > > > >> Is there currently a way to 'bundle' a pattern with a type alias? And > if > > >> not, could that capability be added to the PatternSynonyms GHC > extension? > > >> (Is this the right place to ask, or should I be asking a GHC list?) > > >> > > >> --Keith > > >> Sent from my phone with K-9 Mail. > > >> _______________________________________________ > > >> Haskell-Cafe mailing list > > >> To (un)subscribe, modify options or view archives go to: > > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >> Only members subscribed via the mailman list are allowed to post. > > > > > > _______________________________________________ > > > Haskell-Cafe mailing list > > > To (un)subscribe, modify options or view archives go to: > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: < > http://mail.haskell.org/pipermail/haskell-cafe/attachments/20210916/ef761378/attachment-0001.html > > > > > > ------------------------------ > > > > Message: 5 > > Date: Thu, 16 Sep 2021 15:08:45 -0400 > > From: David Feuer > > To: Carter Schonwald > > Cc: "haskell-cafe at haskell.org" , GHC Users > > List , ghc-devs > > > > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > > Message-ID: > > hsah3a5St3q0t7zeQ at mail.gmail.com> > > Content-Type: text/plain; charset="utf-8" > > > > Here's an example: > > > > pattern State :: (s -> (a, s)) -> State s a > > pattern State f <- (coerce . runStateT -> f) where > > State = state > > > > This would be very nice to bundle with the State type synonym. > > > > On Thu, Sep 16, 2021, 2:22 PM Carter Schonwald < > carter.schonwald at gmail.com> > > wrote: > > > > > These are great ideas! Could you please create a ghc tracker ticket > with a > > > tiny examples or two? > > > > > > There may be specific technical reasons we might not be able to do so > for > > > type synonyms in ghc, but I don’t see any obvious barriers in the case > of > > > David’s excellent idea, I’ve def seen lots of great code out there > where > > > you’d really want either associated pattern synonyms or to bundle > pattern > > > synonyms with the exported public interface for a type class. > > > > > > I’m sure there’s some devil in the details but these sound lovely. > Step > > > -1 is making up 1-2 toy examples and explaining what and why you want > it on > > > a ghc ticket! > > > > > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer > wrote: > > > > > >> I would like that, along with the ability to bundle patterns with > classes. > > >> > > >> On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > > >> > > >>> Is there currently a way to 'bundle' a pattern with a type alias? > And if > > >>> not, could that capability be added to the PatternSynonyms GHC > extension? > > >>> (Is this the right place to ask, or should I be asking a GHC list?) > > >>> > > >>> --Keith > > >>> Sent from my phone with K-9 Mail. > > >>> _______________________________________________ > > >>> Haskell-Cafe mailing list > > >>> To (un)subscribe, modify options or view archives go to: > > >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >>> Only members subscribed via the mailman list are allowed to post. > > >> > > >> _______________________________________________ > > >> Haskell-Cafe mailing list > > >> To (un)subscribe, modify options or view archives go to: > > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >> Only members subscribed via the mailman list are allowed to post. > > > > > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: < > http://mail.haskell.org/pipermail/haskell-cafe/attachments/20210916/82745d58/attachment-0001.html > > > > > > ------------------------------ > > > > Message: 6 > > Date: Thu, 16 Sep 2021 15:12:57 -0400 > > From: David Feuer > > To: Carter Schonwald > > Cc: "haskell-cafe at haskell.org" , GHC Users > > List , ghc-devs > > > > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > > Message-ID: > > gOBVLYBHOrwVDwbpY_G6rg at mail.gmail.com> > > Content-Type: text/plain; charset="utf-8" > > > > Here's a class example: > > > > class (MFoldable t, Monoid t) => Sequence t where > > singleton :: Elem t -> t > > .... > > > > One might wish to write pattern synonyms for viewing the ends of a > > sequence, like the ones in Data.Sequence, and bundle them with this > class. > > > > On Thu, Sep 16, 2021, 2:22 PM Carter Schonwald < > carter.schonwald at gmail.com> > > wrote: > > > > > These are great ideas! Could you please create a ghc tracker ticket > with a > > > tiny examples or two? > > > > > > There may be specific technical reasons we might not be able to do so > for > > > type synonyms in ghc, but I don’t see any obvious barriers in the case > of > > > David’s excellent idea, I’ve def seen lots of great code out there > where > > > you’d really want either associated pattern synonyms or to bundle > pattern > > > synonyms with the exported public interface for a type class. > > > > > > I’m sure there’s some devil in the details but these sound lovely. > Step > > > -1 is making up 1-2 toy examples and explaining what and why you want > it on > > > a ghc ticket! > > > > > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer > wrote: > > > > > >> I would like that, along with the ability to bundle patterns with > classes. > > >> > > >> On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > > >> > > >>> Is there currently a way to 'bundle' a pattern with a type alias? > And if > > >>> not, could that capability be added to the PatternSynonyms GHC > extension? > > >>> (Is this the right place to ask, or should I be asking a GHC list?) > > >>> > > >>> --Keith > > >>> Sent from my phone with K-9 Mail. > > >>> _______________________________________________ > > >>> Haskell-Cafe mailing list > > >>> To (un)subscribe, modify options or view archives go to: > > >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >>> Only members subscribed via the mailman list are allowed to post. > > >> > > >> _______________________________________________ > > >> Haskell-Cafe mailing list > > >> To (un)subscribe, modify options or view archives go to: > > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >> Only members subscribed via the mailman list are allowed to post. > > > > > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: < > http://mail.haskell.org/pipermail/haskell-cafe/attachments/20210916/1569e2b4/attachment.html > > > > > > ------------------------------ > > > > Subject: Digest Footer > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > > > > ------------------------------ > > > > End of Haskell-Cafe Digest, Vol 217, Issue 16 > > ********************************************* > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jerzy.karczmarczuk at unicaen.fr Fri Sep 17 18:31:24 2021 From: jerzy.karczmarczuk at unicaen.fr (Jerzy Karczmarczuk) Date: Fri, 17 Sep 2021 20:31:24 +0200 Subject: [Haskell-cafe] Numerics (was: Re: Trouble with asinh) In-Reply-To: References: Message-ID: <32be9982-6be3-c136-c0b4-7622f3d88404@unicaen.fr> Le 17/09/2021 à 19:16, Carter Schonwald a écrit : > Hey Barak, is Common Lisp the only extant language to take those > issues seriously or are there other examples or better ones? // tan / atan troubles cited by Barak. Common Lisp?? But even the ugly Python reacts better to such examples: *>>> from numpy import * >>> rr, ii = 1.0e-20+0j, 1.0e-20j * *>>> tan(rr),arctan(rr) ((1e-20+0j), (1e-20+0j)) >>> tan(ii),arctan(ii) (1e-20j, 1e-20j)* *==* This works also with cmath (with arctan as atan). ** Jerzy Karczmarczuk -- L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast. https://www.avast.com/antivirus -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Fri Sep 17 19:47:19 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Fri, 17 Sep 2021 15:47:19 -0400 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> Message-ID: On Fri, Sep 17, 2021 at 05:02:09PM +0000, Richard Eisenberg wrote: > > Was it literally just a single sentence introducing a new word for a > > concept that made you "get it"? Could you elaborate? This is really > > quite remarkable. > > For me, coming from a mostly Java background (but with a healthy > dollop of functional programming thrown in the mix -- but no Haskell), > the phrase that unlocked monads was "programmable semicolon". No single exposition is optimal for all learners. Some are visual-spacial, others verbal-sequential, and there are likely other learning styles I've not heard of. Therefore, even with good writing, some readers will have to work harder at understanding the material than others, because they have to translate the explanations into a form that works for them. Also some readers are learning programming and Haskell at the same time, while others are experienced programmers, but not in Haskell or another ML-family or functional language. A reader far removed from the target audience of the writer may find a well written document largely unhelpful. There's no silver bullet. I haven't yet run into a "Haskell the language" book for experienced programmers that cuts to the chase and covers Haskell concisely a la K&R, focusing much more on the language than on how to write code (only as much code as it takes to minimally illustrate a language feature). Such a book would be challenging, because beyond writing basic numeric expresssions a large part of the language is needed all at once before one can write even some fairly simple functions. An off the cuff list of topics likely poorly ordered: * Basic expressions - Int, Word, Integer, Natural and Double - Infix operators, associativity and precedence, parentheses - Sections, (+), (.) and ($) - let and where - layout * Program structure - Function signature, head and body - patterns and pattern bindings - "case" and "if/then/else" - guards and pattern guards - modules, imports, and exports * User defined types - Algebraic data types, sums, products + Tuples + List (mention Array and Vector) + String (and mention Text) + Maybe + Either - Newtypes - Type aliases - GADTs - Existential types * More standard types - Array (immutable) - Vector (immutable) * Lazy evaluation and strictness - Space efficiency, seq and BangPatterns - ByteString strict, lazy and builders - Text strict, lazy and builders - Strict fields and StrictData * Type classes and constraints - Integral - Monoid - Semigroup - Foldable + Strict and lazy folds * Functors, Monads and Applicatives - State and IO Monads - map, fmap and ap - File I/O - Streaming - Applicative option parsing? * IO, ST and mutable values - MVector - MArray ... lots more ... before long we have a book that's considerably larger than K&R. This then leads to some frustration for the experienced programmer impatient to learn the basics of the language and get productive right away without relearning too much from the ground up. But then perhaps even modern C++ or Java has a rather non-trivial learning curve if one is starting from K&R C. There may not be a book that reasonably efficiently brings an experienced non-Haskell programmer to minimal proficiency, and the separation of pure functions from I/O means having to learn abstractions that don't come up in most other languages. For me, the journey was worth it, and the right book would surely have helped, (and would still help, I am far from the summit) but in the end it still takes effort and time. -- Viktor. P.S. Re: mental models of monads: Personally [verbal sequential], I find strained analogies unhelpful and distracting, so no desk clerks shuffling forms for me. I internalised Haskell monads, by implementing the Functor, Applicative and Monad instances for Reader and State a few times from scratch. Once those were solid, ReaderT and StateT and their MonadTrans instances. Unsurpsingly, I have a mental model built around sequencing of internal state updates while passing data from one state to use in choosing the next state transition. I do appreciate "programmable semicolon", but only *after* getting a more concrete intituition for the standard examples. From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Fri Sep 17 20:14:23 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 17 Sep 2021 21:14:23 +0100 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> Message-ID: <20210917201423.GK25255@cloudinit-builder> On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > I haven't yet run into a "Haskell the language" book for experienced > programmers that cuts to the chase and covers Haskell concisely a la > K&R, focusing much more on the language than on how to write code (only > as much code as it takes to minimally illustrate a language feature). The Haskell Report is a good start. From jo at durchholz.org Fri Sep 17 20:29:41 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Fri, 17 Sep 2021 22:29:41 +0200 Subject: [Haskell-cafe] On finding the right exposition... (Monads) In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> Message-ID: Am 17.09.21 um 21:47 schrieb Viktor Dukhovni: > Personally [verbal sequential], I find strained analogies unhelpful > and distracting, so no desk clerks shuffling forms for me. > > I internalised Haskell monads, by implementing the Functor, Applicative > and Monad instances for Reader and State a few times from scratch. Once > those were solid, ReaderT and StateT and their MonadTrans instances. > > Unsurpsingly, I have a mental model built around sequencing of internal > state updates while passing data from one state to use in choosing the > next state transition. I have been finding the Monad expositions misleading - that idea that monads are for sequencing or transitions or mutable state always felt wrong to me, since the monad laws don't talk about any of these things at all. And as far as I could understand the concept, monads are not about state, they're about "composing a linear sequence of functions". The functions' types need not be the same (that would degenerate into the concept of associativity), but the result type of one function must be the parameter type of the next. The monad can do whatever it likes with the functions - typically, wrap them in some other function and construct a function composition; there isn't much else you can do with them, though you're not doing much justice to the Maybe monad if you see it as a pipeline. Ah... right... and of course the pseudo associativity. I.e. it doesn't matter what parts of the total sequence you construct first. Of course, state transitions are a fine application of this concept. Or anything else where you see a function as a computation step and you want to run these steps in sequence. It's just that there are more kinds of monads. Except if you see Maybe as "do these operations in sequence until you hit the first that returns None, then abort". It depends on seeing functions as executable things though, and that's not really what Haskell is trying to be (or was trying to be 20 years ago, maybe everybody is now happy that Haskel finally can express imperative stuff via monads... no idea what people think) Regards, Jo From ietf-dane at dukhovni.org Fri Sep 17 20:39:15 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Fri, 17 Sep 2021 16:39:15 -0400 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: <20210917201423.GK25255@cloudinit-builder> References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> <20210917201423.GK25255@cloudinit-builder> Message-ID: On Fri, Sep 17, 2021 at 09:14:23PM +0100, Tom Ellis wrote: > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > I haven't yet run into a "Haskell the language" book for experienced > > programmers that cuts to the chase and covers Haskell concisely a la > > K&R, focusing much more on the language than on how to write code (only > > as much code as it takes to minimally illustrate a language feature). > > The Haskell Report is a good start. I agree that the report is a useful reference, but it is a specification, not a book from which to learn the language. I wouldn't actually suggest that anyone learn C by reading the C11 specication, or Haskell by working their way through the report. The report would of course be a useful source of topics and material for a Haskell the language book. -- Viktor. From allbery.b at gmail.com Fri Sep 17 20:47:09 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Fri, 17 Sep 2021 16:47:09 -0400 Subject: [Haskell-cafe] On finding the right exposition... (Monads) In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> Message-ID: I suspect a lot of people were pleased that they'd finally gotten rid of lazy Result -> Request. On Fri, Sep 17, 2021 at 4:34 PM Joachim Durchholz wrote: > Am 17.09.21 um 21:47 schrieb Viktor Dukhovni: > > Personally [verbal sequential], I find strained analogies unhelpful > > and distracting, so no desk clerks shuffling forms for me. > > > > I internalised Haskell monads, by implementing the Functor, Applicative > > and Monad instances for Reader and State a few times from scratch. Once > > those were solid, ReaderT and StateT and their MonadTrans instances. > > > > Unsurpsingly, I have a mental model built around sequencing of internal > > state updates while passing data from one state to use in choosing the > > next state transition. > > I have been finding the Monad expositions misleading - that idea that > monads are for sequencing or transitions or mutable state always felt > wrong to me, since the monad laws don't talk about any of these things > at all. > > And as far as I could understand the concept, monads are not about > state, they're about "composing a linear sequence of functions". The > functions' types need not be the same (that would degenerate into the > concept of associativity), but the result type of one function must be > the parameter type of the next. > The monad can do whatever it likes with the functions - typically, wrap > them in some other function and construct a function composition; there > isn't much else you can do with them, though you're not doing much > justice to the Maybe monad if you see it as a pipeline. > Ah... right... and of course the pseudo associativity. I.e. it doesn't > matter what parts of the total sequence you construct first. > > Of course, state transitions are a fine application of this concept. > Or anything else where you see a function as a computation step and you > want to run these steps in sequence. > It's just that there are more kinds of monads. > Except if you see Maybe as "do these operations in sequence until you > hit the first that returns None, then abort". It depends on seeing > functions as executable things though, and that's not really what > Haskell is trying to be (or was trying to be 20 years ago, maybe > everybody is now happy that Haskel finally can express imperative stuff > via monads... no idea what people think) > > Regards, > Jo > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Fri Sep 17 20:50:25 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Fri, 17 Sep 2021 16:50:25 -0400 Subject: [Haskell-cafe] On finding the right exposition... (Monads) In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> Message-ID: On Fri, Sep 17, 2021 at 10:29:41PM +0200, Joachim Durchholz wrote: > > Unsurpsingly, I have a mental model built around sequencing of internal > > state updates while passing data from one state to use in choosing the > > next state transition. > > I have been finding the Monad expositions misleading - that idea that > monads are for sequencing or transitions or mutable state always felt > wrong to me, since the monad laws don't talk about any of these things > at all. That's the nature of mental models, they're first approximations with possible refinements. Yes, there are monads for which State is a poor analogy. The `Cont` monad comes to mind, one needs to "think different" when reasoning about `callCC`, `shift` and `reset` `State` as a mental model for monads captures basic sequencing with possible internal "effects" well enough to be a reasonable first approximation. Already with List exploring all possible paths the fit is not ideal. -- Viktor. From david.feuer at gmail.com Fri Sep 17 20:52:26 2021 From: david.feuer at gmail.com (David Feuer) Date: Fri, 17 Sep 2021 16:52:26 -0400 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> <20210917201423.GK25255@cloudinit-builder> Message-ID: The Report is also a bit outdated in spots. Along with outdated library info, there's also a very old polymorphic recursion enhancement in GHC (and I believe also Hugs and other defunct implementations) that should've been added to Haskell 2010 but wasn't. On Fri, Sep 17, 2021, 4:42 PM Viktor Dukhovni wrote: > On Fri, Sep 17, 2021 at 09:14:23PM +0100, Tom Ellis wrote: > > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > > I haven't yet run into a "Haskell the language" book for experienced > > > programmers that cuts to the chase and covers Haskell concisely a la > > > K&R, focusing much more on the language than on how to write code (only > > > as much code as it takes to minimally illustrate a language feature). > > > > The Haskell Report is a good start. > > I agree that the report is a useful reference, but it is a > specification, not a book from which to learn the language. I wouldn't > actually suggest that anyone learn C by reading the C11 specication, or > Haskell by working their way through the report. > > The report would of course be a useful source of topics and material for > a Haskell the language book. > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Fri Sep 17 20:53:32 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Fri, 17 Sep 2021 21:53:32 +0100 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> <20210917201423.GK25255@cloudinit-builder> Message-ID: <20210917205332.GL25255@cloudinit-builder> On Fri, Sep 17, 2021 at 04:39:15PM -0400, Viktor Dukhovni wrote: > On Fri, Sep 17, 2021 at 09:14:23PM +0100, Tom Ellis wrote: > > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > > I haven't yet run into a "Haskell the language" book for experienced > > > programmers that cuts to the chase and covers Haskell concisely a la > > > K&R, focusing much more on the language than on how to write code (only > > > as much code as it takes to minimally illustrate a language feature). > > > > The Haskell Report is a good start. > > I agree that the report is a useful reference, but it is a > specification, not a book from which to learn the language. I wouldn't > actually suggest that anyone learn C by reading the C11 specication, or > Haskell by working their way through the report. My memory of K&R may be deceiving me, but I seem to recall it is a lot closer to the Haskell Report than the C11 standard is. I would be interested in the opinion of others who have read these documents more recently. From barak at pearlmutter.net Fri Sep 17 20:54:13 2021 From: barak at pearlmutter.net (Barak A. Pearlmutter) Date: Fri, 17 Sep 2021 21:54:13 +0100 Subject: [Haskell-cafe] Numerics (was: Re: Trouble with asinh) In-Reply-To: References: Message-ID: I suspect that most implementations of Common Lisp just call the C standard library catan(3) etc, which are well tuned. $ clisp Welcome to GNU CLISP 2.49.92 (2018-02-18) [1]> (atan #c(0 1d-40)) #C(0 1.0d-40) In this particular case, the problem is that the Haskell Data.Complex code has its own implementation of atan, which uses a log(1 + x) in calculating the imaginary part. A foreign function call to the appropriate libm routine would robustly address this, but that would be difficult because it's trying to be generic over RealFloat a => Complex a, instead of special casing Complex Float / Complex Double. Anyway, the Standard Prelude code for this is naïve: it should call log1p, at the very least—which it actually goes to the trouble of defining correctly, but not exporting. From cdsmith at gmail.com Fri Sep 17 20:59:09 2021 From: cdsmith at gmail.com (Chris Smith) Date: Fri, 17 Sep 2021 16:59:09 -0400 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> Message-ID: On Fri, Sep 17, 2021 at 3:52 PM Viktor Dukhovni wrote: > No single exposition is optimal for all learners. Some are > visual-spacial, others verbal-sequential, and there are likely other > learning styles I've not heard of. > If you'll forgive the slight argumentativeness, I do want to point out, as someone who follows education research quite a bit, that this learning styles hypothesis is a pretty well-known myth. It sounds good and feels true, but has been falsified every time someone has tried to gather evidence to validate it. There are some related statements that are true. For example, different people certainly have different preferences for modes of presentation, but those preferences don't actually correlate with how well they learn. Feeling confused or unsatisfied doesn't mean you're not learning! For another example, people definitely do learn better when they see information from several different points of view, but it's apparently not because different people learn best from different points of view, but rather because all people learn best when they have more different perspectives to integrate. And for a last example, people definitely do have preferences and abilities for learning different kinds of content, which are in turn most naturally communicated in certain ways, but it's apparently the natural way to present an idea that matters more in terms of learning, not the individual's preferences for style. This is actually pretty related to what we're talking about here. If it were true that different people understand monads better when they are presented in ways that match the individual's style of learning, reliable evidence of this would be revolutionary in education research. (Meaning: it's very, very likely not to be true, though I cannot point to research that studies understanding monads, in particular.) But luckily, the solution to this myth is just *not* to differentiate, but rather to provide all of these points of view to everyone who is learning, whether they *feel* that this is the right presentation or it *feels* like it's making sense to them or not. When evaluating our own learning experiences, we should be careful to remember that the times we were learning were probably actually the times we felt a bit confused. The presentation that finally made sense probably wasn't the most helpful one. See https://www.google.com/search?q=learning+styles+myth for lots of sources. -------------- next part -------------- An HTML attachment was scrubbed... URL: From trebla at vex.net Fri Sep 17 21:02:23 2021 From: trebla at vex.net (Albert Y. C. Lai) Date: Fri, 17 Sep 2021 17:02:23 -0400 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> Message-ID: I agree with improving teaching/learning materials. But here is a small point I object to: On 2021-09-17 3:47 p.m., Viktor Dukhovni wrote: > On Fri, Sep 17, 2021 at 05:02:09PM +0000, Richard Eisenberg wrote: > > No single exposition is optimal for all learners. Some are > visual-spacial, others verbal-sequential, and there are likely other > learning styles I've not heard of. Please consult for example https://www.youtube.com/watch?v=rhgwIhB58PA It is long past high time to kill that outdated zombie myth. What I stand behind is: Every student needs every perspective they can get their hands on. But it is not because every student is only good at just one thing. From keith.wygant at gmail.com Fri Sep 17 21:04:27 2021 From: keith.wygant at gmail.com (Keith) Date: Fri, 17 Sep 2021 21:04:27 +0000 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: <7E95F060-6A82-4F5C-94D8-B21458C672BF@gmail.com> Perhaps it would make sense to have a 'using the class' section and a 'writing instances' section. The first would focus on more concrete and intuitive examples. The second would explain how and why to follow the laws, maybe with specific ways to avoid pitfalls and extra work (e.g. when you can and can't DeriveFoldable, when to use `foldMapDefault` when to define only `foldr` or `foldMap` or to use `toList` to define others. It's super important that folks gan define legal instances so things don't brow up in their faces (e.g. an Applicative instance that zips but defines `pure` as a singleton). But often all they need to know is `DeriveTraversable` exists and works as long as you don't define things in strange ways (like conceptually reversed lists). --Keith Sent from my phone with K-9 Mail. On 17 September 2021 08:30:37 UTC, Ignat Insarov wrote: >Hello Viktor. > >Thank you for your continuous effort. > >I have been writing Haskell for years now and even getting paid for >it. I care nothing for the laws — I rarely apply equational reasoning. >I am a visual person, to me intuitive grasp is the tool of choice. I >also know a few newcomers to Haskell and I am certain they make zero >use of the laws. > >My thus informed view is that laws are fine in the end and useless at the start. > >On Fri, 17 Sept 2021 at 04:48, Viktor Dukhovni wrote: >> >> On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: >> >> > The last time I went to look at the laws it took me a couple minutes to >> > find them. I use them to write instances. Pretty important, IMO. >> >> I agree the laws are important to document, I just don't think they >> belong at the top of the module. The beginner to intermediate users >> will be using the library and existing instances for some time before >> they start to write their own instances. >> >> If more modules adopt something like the style of the new Data.Foldable, >> experienced users will know to look for the laws at the end, if not >> still present at the top of the module. >> >> Of course perhaps the community would prefer the original Laws first >> format, I'm fine with that emerging as the consensus. Perhaps worthy >> of a separate thread (made it so). >> >> Of course the conjectured users who might most benefit from not being >> intimidated by being exposed to laws before they're ready to understand >> them might not be present on this forum... >> >> -- >> Viktor. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >_______________________________________________ >Haskell-Cafe mailing list >To (un)subscribe, modify options or view archives go to: >http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From douglas.mcilroy at dartmouth.edu Sat Sep 18 01:47:34 2021 From: douglas.mcilroy at dartmouth.edu (Douglas McIlroy) Date: Fri, 17 Sep 2021 21:47:34 -0400 Subject: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools Message-ID: > Lambda calculus is an excellent place for beginners to start. > What could be easier to learn? It's certainly easier than grokking > a Turing machine; and much easier than Haskell: less than a > handful of primitives yet can compute anything computable. There's a category error (in the sense of logic, not algebra) here. Learning a language is not comparable to understanding a program. The concept of lambda calculus is far more subtle than that of Turing machine. But if you know both, a program is likely to be much easier to understand when presented in lambda calculus than when presented as a Turing machine. Doug From michael.eugene.turner at gmail.com Sat Sep 18 02:56:37 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Sat, 18 Sep 2021 11:56:37 +0900 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning Message-ID: Well, this is certainly blowing up into something bigger than I thought it would. (At one point last night, 12 people had my "Haskell in Plain English" essay/chapter open on Google Docs, a very unintentional side effect.) Me: "I finally got (most of?) what monads really mean for practical programming when none other than Simon Peyton-Jones said F# called a very similar construct "workflow," a word he likes." A response: "Was it literally just a single sentence introducing a new word for a concept that made you "get it"? Could you elaborate? This is really quite remarkable." Richard Eisenberg: "For me, coming from a mostly Java background (but with a healthy dollop of functional programming thrown in the mix -- but no Haskell), the phrase that unlocked monads was "programmable semicolon"." I think one explanation for the Monad Tutorial Explosion (and how it still didn't work for a lot of people) is that there's no single right metaphor that will finally make monads "click". It depends on what combination of conceptions (and perhaps all misconceptions to be dispelled) is floating around in given mind. And minds vary. Workflow is a metaphor at one useful level. "Programmable semicolon" is a metaphor at another useful level. Semicolon as imperative-language separator actually hides a lot that's going on in a real CPU. Even if the imperative language is assembly language, the compiled instructions go to an instruction fetch/decode unit that -- these days especially -- can be engaged in a bewildering number of tasks, including finishing up several previous instructions, translating the decoded instruction to what amounts to microcode that get sent to an instruction cache, and fetching the next few instructions even as it's been decoding the instruction fetched into a little to-do list for the CPU. Perhaps we can think of instruction fetch/decode as "monadal" -- it's wildly (but not chaotically) mapping a previous state of the machine into new one. After all, it's all still Turing machines down there somewhere (but even the Turing machine was mathematically defined as a function that maps one tape-state to the next while it's also mapping its internal state to a new state.) So the semicolon can be thought of as lexically exposing the fetch-decode operator in the CPU's own little program. The "workflow" metaphor is at a higher level. If you think of how incoming data can be sorted and parceled out as if to a number of desks in an office, with forms processed at a desk going from one outbox to another desk's inbox, you're ignoring exact sequencing. It's the view where you're labeling desks by their specialized tasks and drawing outbox-inbox connections. In this view, it matters little that, in the one-instruction-at-a-time CPU model, there's only one "clerk" who (ridiculously, I know) puts a form in an inbox, then takes it out again, puts it in the inbox of another desk, then sits down at that other desk, takes the same form out and does the very specific form-processing task assigned to that desk. You can instead imagine it as some sluggish bureaucracy where everyone else but the single busy clerk is waiting for a form to hit their empty inboxes. The fact is, "one-instruction-at-a-time CPUs" hardly exist anymore except in the cheapest microcontrollers -- there are all multitasking like crazy. And this is because CPU designers work very hard to see how much of the little bureaucracy they can actually keep busy, ideally at all times, but at least at high throughput for average instruction streams, even if 100% utilization is seldom reached. (Lambda, the Ultimate Semicolon?) Bryan: "Listing sequential actions one after the other is so intuitive you see it everywhere. Take baking recipes as one example. Or assembly code. Or poems." Yes, sequencing just grows out of the fact of time. You'd think that poems aren't really sequences of tasks to do. But in a way, they are, and in a sense that matters for my attempts at natural-language understanding. There IS an implicit imperative in the energy required to speak: the subtext of any statement addressed to another person (even when it's dead poet to living reader) is: think about what I'm saying. Each new word in a sentence being spoken maps the listener's mind-state to a new one. The purpose of the sequencing is to build up state in the listener's mind. "When a Haskeller says, "Monads are great! They let you chain effectful actions together!" it can take a very long time to understand they actually mean exactly what they're saying — the usual intuition is that sequencing actions can't possibly be a real problem, so you go round and round in circles trying to understand what "effectful" means, what "action" means, and how these oh-so-important "laws" have anything to do with it." Yes, it's sort of like aliens from outer space with a very alien consciousness, and a different relation to the dimension of time, and they are exulting (to each other, and to themselves, really, more than to you): "Periods at the ends of sentences are great! They enable these strange blobs of protoplasm who call themselves 'human' to more easily map the states of these internal things they call 'neurons' into new states. No wonder we've been having such trouble trying to tell them what to do, using our intuitively obvious gestaltic visual patterns that allow us to grasp, with our quantum-computer brains, a whole meaning at once, through our retinas." (Yes, I am riffing a little here on the SF movie Arrival.) Math is this world where we can feel a little like that. Instead of thinking of a function as a machine that takes inputs, grinds away for a little while, and extrudes outputs, you can think of all inputs and output as already existing, and reason logically from the resulting properties. Haskell's laziness helps you fake what you can't really have: infinite workspace and the ability to do everything in an instant. It's a fake-it-til-you-make-it language, and you don't have to be Buzz Lightyear going to infinity and beyond, perhaps to all the way to the galaxy Aleph-omega. You just have to make a Haskell program do something that people like as much as their Buzz Lightyear doll. The math view is a useful view at one level, but it can only help you so much. I greatly enjoyed the level where I could define a Turing machine as a mapper from one infinite tape to another, then imagine all possible Turing machines as a countably infinite set. I could then prove, with Cantor diagonalization (abstractly, at least, though not very intuitively) that there are things Turing machines can't do. I loved that. But I also listened to grad students mutter about how recursive function theory may be beautiful and all, but it's now classical, and therefore dead for their own practical purposes (getting a PhD, getting onto tenure track.) And by then I knew I wasn't good enough at math to make a go of computing theory in their world, as a career, no matter what. I think Simon Peyton-Jones had a similar experience of academia -- he wasn't a John Hughes -- but he found a way through anyway. Bryan: "I can understand why that [puzzled newbie] viewpoint might be long-forgotten by those who were involved in the effort to solve it. :) And I appreciate that it was solved in such a general way that it can be applied to so many seemingly unrelated things! That's the beauty of mathematics!" Yes, it's there. But in user experience design (and writings about Haskell ARE part of its user experience) there's a saying: the intuitive is the familiar. At some point in gaining sophistication, it's no longer intuitively obvious to you why something wasn't intuitively obvious for you before. You're so absorbed in where you are that you don't remember quite how you got there. You might even assume that everyone who has gotten where you are has gotten there by the same route. And, if you can dimly remember how you got a flash of inspiration, you might end up writing yet another monad tutorial that few people understand. "Workflow" helped me. And now "programmable semicolon" is helping a little, in another way. I presented a strategy at the NSMCon-2021 conference: think of NSM reductive paraphrasing as writing very complete and precise code for natural-language terms and grammar rules, using NSM primes and syntax as a kind of logic programming language -- one that might even be very simply translatable to Prolog. I did some coding experiments and saw a problem: viewed more procedurally -- i.e., with each line of an NSM explication adding to a conceptual schema of a natural-language meaning -- NSM wasn't single-assignment. A Prolog interpreter couldn't just try a match, looking at each statement of an explication in relative isolation, and bail out when a statement failed to be true in the given context of the attempted match. It had to drag some state along just to resolve what the NSM prime "this" referred to. (Think of "it" in GHCI.) OK: effects. But wait, more: scoped effects. You want to strip some schema-stuff back out if a match failed midway through, then try another match somewhere else. OK: I need a context stack to store assertions that succeeded. Uh-oh, Prolog doesn't give me that paper trail. Dang. And I still want the one-for-one translation of sentences in an NSM reductive paraphrase to something like Prolog. OK: I need to grab control of sequencing, so that I can not only use the intrinsic Horn clause resolution without pain. But I also want it to hold onto the assertions that succeeded, and knit them into the growing conceptual schema that's part of the state. AND I want it roll those back out, transactionally, if a match didn't succeed. It turns out that Prolog makes this not too much harder than, say, a Lisp with transactional memory. So: I think I might now return to my Prolog code and see if I was unconsciously reinventing some kind of monad. Because because I felt forced by Prolog's limits to write my own semicolon. It wasn't too hard, though the resulting code required for NSM explications looks clunkier now. (Prolog is very limited in syntax extensibility.) Maybe there's some way in which Haskell makes it easier still, and nicer-looking too. None of which is to say that "programmable semicolon" will immediately help everyone pick the conceptual lock of monads. But for those who just bonk on "programmable semicolon", it might help to point out that the load-operate-store model of CPUs is a lie these days. Say a little about why it's not true. Then again pose semicolon as a kind of operator. People like to think, "OK, this statement will finish, and the one after the semicolon will start." It's a convenient view, even though in fact, while the imperative statement is in progress, the CPU might have already fetched instructions beyond it, and scheduled them for speculative execution. Or, you can tell them, "Just learn lambda calculus, then study monads algebraically, and here's a side dish of category theory while I'm it. Bon appetit." How's that working for you, guys? It doesn't work for me. And I don't think it's because I can't do the math. It's that I often write code to see whether I'm thinking about a problem the right way. And is that so bad? I believe it was in Stewart Brand's "II Cybernetic Frontiers" where a researcher at Xerox PARC, Steve ("Slug") Russell, one of their star hackers, was described by his peers as "thinking with his fingertips." I'm no star hacker, but "workflow" feels like it will make my fingertips smarter. "Programmable semicolon" feels like it will make my fingertips smarter. You think top-down mathematically? Well, bon appetit. It's not to my taste. No single way is likely to work for all. Math is not some fundamental reality. It's not even reality -- in fact, it gains a lot of its power precisely from being imaginary. And it's just a bunch of metaphors too. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry From anthony.d.clayden at gmail.com Sat Sep 18 03:35:29 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Sat, 18 Sep 2021 15:35:29 +1200 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 Message-ID: >>* Haskell's big problem right now is adoption. * Heh heh, this sentence is multi-ways ambiguous. As in the 'problem' is that there's too many adopters/the wrong sort of people trying to adopt Haskell. The 'problem' is that Haskell is not keeping to its objective to "avoid success at all costs". > I'm not quite sure this is a problem. Haskell and its libraries are designed around math concepts, as opposed to CS concepts (semigroup vs IConcatenable). Learning it all but requires learning some algebra as well, thus a lower adoption rate is expected. Thank you for saying that out loud. I've been feeling for some time that GHC is getting harder to use. You're telling me that because I don't get Category Theory you want to throw me out of using Haskell. People who are allergic to Lambda-calculus are already excluded. So the ostensible difficulty on these threads: that the documentation is unhelpful, is not the problem at all. In fact it's deliberate that the docos are exclusionary. As part of this grand plan, Viktor is deliberately making the Libraries docos impenetrable. (By which I mean: the style is clear, but the material is unlearnable. Apparently I need to know what is an endomorphism before I can write a Foldable instance) And that explains a paradox: I learnt Haskell over a decade ago. There was far less intro material; and certainly no store of StackOverflow questions/answers. It should have been more difficult to learn than today. But I don't remember learning being as difficult as the claims on this thread. (Memory can deceive, I guess.) Back then Haskell was a much smaller, simpler language. There was less that could go wrong at the type level; and the error messages didn't keep recommending to switch on bamboozling features that (as it turned out) made the difficulty harder. Don't go claiming that if I switch off those features today it's as if I was still using H2010. Simply not true. I know that's not true, because I can still go back and use Hugs, or use GHC v7.10 (vintage ~2015), and have a much more pleasant/less bamboozling experience. Then "Haskell's big problem right now" is (depending on your point of view) either GHC or too many of the wrong adopters. And with Dependent Types coming along GHC is going to get a lot worse. (Maybe GHC will eventually get through the fog, throw out a load of cruft and become on average as usable as v7.10. I'm not prepared to go through the pain for 5 years to find out. I'll stick with v7.10.) -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Sat Sep 18 06:03:11 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Sat, 18 Sep 2021 02:03:11 -0400 Subject: [Haskell-cafe] Best to not go there... In-Reply-To: References: Message-ID: On Sat, Sep 18, 2021 at 03:35:29PM +1200, Anthony Clayden wrote: > In fact it's deliberate that the docos are exclusionary. As part of > this grand plan, Viktor is deliberately making the Libraries docos > impenetrable. (By which I mean: the style is clear, but the material > is unlearnable. Apparently I need to know what is an endomorphism > before I can write a Foldable instance) I believe I'm owed an apology. The above is inappropriate snark that does not belong on this forum. If we start finger pointing at people driving away participation, perhaps a look in the mirror is warranted. It's not like I took a bunch of extant accessible background material and made it harder to read. There was none there to be found. So my excuse could be that in the worst case if it is doing nothing for you, then just stop reading it and you're no worse off. However, I am not planning to hide behind that. Yes, I slipped up and labeled those particular `b -> b` terms "endomorphisms" without explaining or motivating the use of the term. I should probably have left the term out, or else justified its use (deeper down the rabbit hole, so I doubt you'd go there) by observing that we're transforming the original fold into a fold of function terms under composition, which of course requires these to have the same input and output types, i.e. be "endomorphisms". This is probably how a tiny fragment of that thought process slipped into the final text. Mea culpa, but it is then rather a leap to say "Viktor is deliberately making the Libraries docos impenetrable". I might note that the concept of endomorphisms already appeared in the "Laws" section of the GHC 7.10 documentation (unsabotaged by me) in the form of unexplained "Endo" and "appEndo" terms: https://hackage.haskell.org/package/base-4.8.0.0/docs/Data-Foldable.html Foldable instances are expected to satisfy the following laws: foldr f z t = appEndo (foldMap (Endo . f) t ) z foldl f z t = appEndo (getDual (foldMap (Dual . Endo . flip f) t)) z ... I did (with recent moral support it seems) move the laws section to the end of the docs, precisely because I thought many a reader would find the section more puzzling than helpful. Though I likely slipped up more than once by using some avoidable jargon, this seems a rather thin justification for condemning the entire effort as deliberate obfuscation. The goal of the writeup is to cover topics to which mere synopses don't do enough justice. Somewhat advanced material is properly in scope. No writeup will cater to all audiences, sorry it did not work out for you. -- Viktor. P.S. I'll elide "endomorphism" for the next update. If you'd like to write some text from a more approachable perspective that augments or replaces the current text, by all means open an MR in gitlab, and if it does a better job, I'll be among those cheering for it to be merged. From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Sat Sep 18 07:30:12 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Sat, 18 Sep 2021 08:30:12 +0100 Subject: [Haskell-cafe] Best to not go there... In-Reply-To: References: Message-ID: <20210918073012.GM25255@cloudinit-builder> On Sat, Sep 18, 2021 at 02:03:11AM -0400, Viktor Dukhovni wrote: > On Sat, Sep 18, 2021 at 03:35:29PM +1200, Anthony Clayden wrote: > > In fact it's deliberate that the docos are exclusionary. As part of > > this grand plan, Viktor is deliberately making the Libraries docos > > impenetrable. (By which I mean: the style is clear, but the material > > is unlearnable. Apparently I need to know what is an endomorphism > > before I can write a Foldable instance) > > I believe I'm owed an apology. The above is inappropriate snark that > does not belong on this forum. If we start finger pointing at people > driving away participation, perhaps a look in the mirror is warranted. Fully agreed. Base has lacked important documentation for *years*. Anyone could have volunteered to improve it during those years but no one did. In the end it was Viktor who made the effort. He deserves our thanks and support and constructive suggestions for futher improvements. Thanks Viktor! Here's to continued collaborative improvement of our ecosystem. > If you'd like to write some text from a more approachable perspective > that augments or replaces the current text, by all means open an MR in > gitlab, and if it does a better job, I'll be among those cheering for it > to be merged. Indeed. Tom From david.feuer at gmail.com Sat Sep 18 07:35:30 2021 From: david.feuer at gmail.com (David Feuer) Date: Sat, 18 Sep 2021 03:35:30 -0400 Subject: [Haskell-cafe] Best to not go there... In-Reply-To: <20210918073012.GM25255@cloudinit-builder> References: <20210918073012.GM25255@cloudinit-builder> Message-ID: I should have said earlier that while I disagree with Viktor about typeclass laws, I'm very much in favor of his goal of making the documentation more approachable. On Sat, Sep 18, 2021, 3:30 AM Tom Ellis < tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote: > On Sat, Sep 18, 2021 at 02:03:11AM -0400, Viktor Dukhovni wrote: > > On Sat, Sep 18, 2021 at 03:35:29PM +1200, Anthony Clayden wrote: > > > In fact it's deliberate that the docos are exclusionary. As part of > > > this grand plan, Viktor is deliberately making the Libraries docos > > > impenetrable. (By which I mean: the style is clear, but the material > > > is unlearnable. Apparently I need to know what is an endomorphism > > > before I can write a Foldable instance) > > > > I believe I'm owed an apology. The above is inappropriate snark that > > does not belong on this forum. If we start finger pointing at people > > driving away participation, perhaps a look in the mirror is warranted. > > Fully agreed. Base has lacked important documentation for *years*. > Anyone could have volunteered to improve it during those years but no > one did. In the end it was Viktor who made the effort. He deserves > our thanks and support and constructive suggestions for futher > improvements. Thanks Viktor! Here's to continued collaborative > improvement of our ecosystem. > > > If you'd like to write some text from a more approachable perspective > > that augments or replaces the current text, by all means open an MR in > > gitlab, and if it does a better job, I'll be among those cheering for it > > to be merged. > > Indeed. > > Tom > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Sat Sep 18 08:00:02 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Sat, 18 Sep 2021 09:00:02 +0100 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: References: Message-ID: <20210918080002.GN25255@cloudinit-builder> On Sat, Sep 18, 2021 at 11:56:37AM +0900, Michael Turner wrote: > Workflow is a metaphor at one useful level. "Programmable semicolon" > is a metaphor at another useful level. [...] > "Workflow" helped me. And now "programmable semicolon" is helping a > little, in another way. What troubles me about "workflow" and "programmable semicolon" is the question of whether they also apply to Arrow[1]. * If they do, then in what sense can "workflow" and "programmable semicolon" said to help with understanding of *Monad*? * If they don't, then why not? I don't see it. One possible answer is that they do, but those descriptions are only intended to improve understanding about purpose not about technical details (I think this is what Michael is suggesting). Tom [1] https://www.stackage.org/haddock/lts-17.7/base-4.14.1.0/Control-Arrow.html From b at chreekat.net Sat Sep 18 09:15:40 2021 From: b at chreekat.net (Bryan Richter) Date: Sat, 18 Sep 2021 12:15:40 +0300 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> <20210917201423.GK25255@cloudinit-builder> Message-ID: I started learning Haskell by reading the Report, and I warmly recommend that strategy. In particular, I just skipped over the terminology that didn't make sense to me yet, and I didn't try too hard to keep the big picture in my head (suggestion to future versions: put all the BNF diagrams in the same place!) Even with a rudimentary read-through, I was already advanced beyond the likes of LYAH and ready to start running simple programs in ghci. Even today I sometimes know things about syntax that surprise my colleagues. I didn't need to know monads yet. The build tool challenges were a bigger stumbling block at that point. But best of all, I was familiar with the reference material, so I could easily go back and reread things when necessary! On Fri, 17 Sep 2021, 23.40 Viktor Dukhovni, wrote: > On Fri, Sep 17, 2021 at 09:14:23PM +0100, Tom Ellis wrote: > > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > > I haven't yet run into a "Haskell the language" book for experienced > > > programmers that cuts to the chase and covers Haskell concisely a la > > > K&R, focusing much more on the language than on how to write code (only > > > as much code as it takes to minimally illustrate a language feature). > > > > The Haskell Report is a good start. > > I agree that the report is a useful reference, but it is a > specification, not a book from which to learn the language. I wouldn't > actually suggest that anyone learn C by reading the C11 specication, or > Haskell by working their way through the report. > > The report would of course be a useful source of topics and material for > a Haskell the language book. > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Sat Sep 18 09:19:52 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sat, 18 Sep 2021 11:19:52 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <20210918080002.GN25255@cloudinit-builder> References: <20210918080002.GN25255@cloudinit-builder> Message-ID: <22AF45B6-2FF5-42D3-B372-2FBD54532DDB@gmail.com> This is monad: f(g(h(…))) To make sequence out of functions. > > said to help with understanding of *Monad*? Greetings. Branimir. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Sat Sep 18 09:24:37 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sat, 18 Sep 2021 11:24:37 +0200 Subject: [Haskell-cafe] [BUG] Criterion is tied to x86 architecture Message-ID: Problem as I work on Apple M1 processor, can’t compile Criterion as it use x86 specific features. Greetings, Branimir. From jaro.reinders at gmail.com Sat Sep 18 09:55:32 2021 From: jaro.reinders at gmail.com (Jaro Reinders) Date: Sat, 18 Sep 2021 11:55:32 +0200 Subject: [Haskell-cafe] [BUG] Criterion is tied to x86 architecture In-Reply-To: References: Message-ID: <990cf778-738b-3e60-791c-9fb86bb09d4f@gmail.com> This issue: https://github.com/haskell/criterion/issues/238, makes it seem like this should be fixed with criterion-measurement-0.1.3.0. If that doesn't work then I suggest placing a comment or opening a new issue there. Cheers, Jaro On 18-09-2021 11:24, Branimir Maksimovic wrote: > Problem as I work on Apple M1 processor, can’t compile > Criterion as it use x86 specific features. > > Greetings, Branimir. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > From jo at durchholz.org Sat Sep 18 10:34:21 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Sat, 18 Sep 2021 12:34:21 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <22AF45B6-2FF5-42D3-B372-2FBD54532DDB@gmail.com> References: <20210918080002.GN25255@cloudinit-builder> <22AF45B6-2FF5-42D3-B372-2FBD54532DDB@gmail.com> Message-ID: <34d27e9a-8736-62c6-23ea-8d7a38b4613a@durchholz.org> Am 18.09.21 um 11:19 schrieb Branimir Maksimovic: > This is monad: > f(g(h(…))) > > To make sequence out of functions. Ah, no. That's just function composition. A monad can do more - e.g. Maybe interleaves the functions with a check whether it was passed in Nothing. Regards, Jo From coot at coot.me Sat Sep 18 11:40:19 2021 From: coot at coot.me (coot at coot.me) Date: Sat, 18 Sep 2021 11:40:19 +0000 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. Message-ID: Consider the following existential type: ``` data Some where Some :: a -> Some ``` The following (bidirectional) pattern synonym is accepted: ``` pattern Any :: a -> Some pattern Any a = Some a ``` However using an explicit `forall` results in a type error: ``` pattern Any :: forall a. a -> Some pattern Any a = Some ``` ``` Patterns.hs:63:23: error: • Couldn't match expected type ‘a’ with actual type ‘a1’ ‘a1’ is a rigid type variable bound by a pattern with constructor: Some :: forall a. a -> Some, in a pattern synonym declaration at Patterns.hs:63:18-23 ‘a’ is a rigid type variable bound by the signature for pattern synonym ‘Any’ at Patterns.hs:62:23 • In the declaration for pattern synonym ‘Any’ • Relevant bindings include a :: a1 (bound at Patterns.hs:63:23) | 63 | pattern Any a <- Some a | ^ ``` This is indpendent whether `ExplicitForAll` or `ScopedTypedVariables` extensions are enabled or not. Is there a way around it, or is this a missing feature? Best regards, Marcin Szamotulski Sent with ProtonMail Secure Email. -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 509 bytes Desc: OpenPGP digital signature URL: From michael.eugene.turner at gmail.com Sat Sep 18 11:49:46 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Sat, 18 Sep 2021 20:49:46 +0900 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 22 In-Reply-To: References: Message-ID: "I don't remember learning being as difficult as the claims on this thread. (Memory can deceive, I guess.)" Yes, it can. What really matters for that question is quantification. How hard was it for other people a decade ago? How hard is it now? What kinds of people were learning a decade ago? What kinds of people are learning now? Without measures, you're just offering anecdotal evidence. You say that Haskell is having problems because it wasn't true to the faith of "Avoid success at all costs". I always thought that was supposed to be a wryly paradoxical statement of strategy, not an "objective"; it was an impishly witty design-methodology heuristic, not a hymn. Perhaps I'm misreading the community spirit at Haskell Foundation, but it seems the tune shifted a while back. You feel that the wrong kinds of people are learning Haskell now, that it's "adopting" too many problem children. Thank you for your generous offer to help me dig myself out of the hole you said I dug for myself, though I can't understand why. After all, you've made it clear that you think I'm a problem child. How else to explain why you distorted what I've said elsewhere, in your summary of my positions, when you could have just linked to my actual words, in archives, and let them speak for themselves? "This juvenile delinquent has got Haskell all wrong -- stop him before he vandalizes again!" But I suppose it's just in your humanitarian nature to help even us juvenile delinquents. Still, are you sure you don't have things upside down? I'm afraid I can't offer much to you, from the way I feel the direction of gravity. >From where I am, I think the only thing I can send downward to you is a shovel full of dirt. Is GHC part of the problem? I'm pretty sure of that. Are lots of people getting Haskell wrong? That's symptomatic, at least. Has Haskell gotten too big. I wouldn't be surprised. Should more mathematical approaches be emphasized? I'm not against it, as long as there's emphasis where it's due -- for some Haskellers coming up, it may be better to bring in the math later, when they are already feeling certain patterns in coding but don't quite know how they can be concisely and rigorously expressed, and applied. But over and above all that, you can't learn Haskell by sitting with a reference manual, and trying things out in GHCI. Nor can you learn it very easily by studying relatively mature code. And if "avoiding success" means a book is giving examples that don't work anymore, that's more frustration for readers who are already feeling the steepness of the learning curve. People who want to learn need better things to read. What's "better"? It'll vary according to the reader. I'm a reader who doesn't need another sermon about, say, the virtues of static types -- I converted to that religion long ago. I'm a reader who keeps the machine level in mind, because I've been on projects where a new release of a product that used to be fast enough is suddenly extremely slow on startup initialization -- e.g., someone rewrote an SQL query in the ORM to be "more elegant" but unfortunately also as if disk-head seeks, platter rotations, and block reads were as virtually instantaneous as, say, a line fetch from L3 cache. The problem isn't overpopulation, it isn't like all those Irish that Reverend Malthus thought should starve to death because, well, they'll just breed out of control otherwise. It's the problem of professionalization, which software has always had. Entry is cheap and easy. Hardly a month goes by that we don't hear of some (supposed) miracle of modern software science from some senior in high school who started a software company. Turnover is high. This means a lot of internal treadmills to retain knowledge of how the code works. Lots of people burn out in ten years -- a ten years that, in other engineering professions, is the point at which you're considered fully seasoned, ready to hit your stride. Why the continuing immaturity? Software hasn't killed a lot of people (yet, he says, scanning the sky nervously for drones.) As long as most software was mostly in corporate information systems, the casualties tended to be only corporate-political. If you were such a casualty, it was a bit like being a player in an MMPORG. You could get "reincarnated" in another division, or another corporation, no matter how ignominious your failure. Not much karmic justice either. Even if you perpetrated fraud, which most financial firms prefer to cover up than prosecute, sending you on, because it would be bad PR to send your case to trial and have customers discover that the firm is not as good about internal security threats as it claims. To some extent, it's the very softness of software that has kept the field so immature. Mistakes are made, but unlike a shifty bridge or a shaky plane, they can be corrected cheaply and (for now) safely -- or at least, any new bugs that your patch introduced are subtler, less frequently manifested, easier to blame on someone else. Or maybe you jumped to another company by the time your code became a problem. Never have to grow up, not me! But one sign of maturity in an engineering profession is that it stops being a priesthood/guild and starts being a public responsibility. And that starts with clear communication, within and beyond the profession. Better tools are nice, of course. But if they are effectively impenetrable to those outside the guild, you're not really solving the problem. A firmer grounding in theory is also very important. But if it's hermetic incantations and thumping of mathematical bibles, that's also not good, clear communication, within and beyond the profession. Haskell has survived what is, for programming languages, a truly staggering infant mortality rate. But what stage of life is it in, now? Who are the models of maturity, for use of Haskell professionally? How can they be elevated to influence, both within and beyond Haskell programmer subculture? Bishops and guild masters were ultimately answerable to feudal lords, and modern institutions that fund software development are significantly feudal, both internally and in their interactions with other institutions. Professionalism confers an advantage: You can speak with the authority of backing from your own institution, its own ethics and values, its own standards -- as long as that profession has proven that it's motivated from a sense of public responsibility. But your profession has to speak clearly, as clearly as possible, on all levels, to maintain itself as an institution, to remain influential -- i.e., from a stance of being IN these feudal mini-worlds but not OF them. This is because, in a way, apart from the brains of its members, clear communication is the only real asset a professional institution has. And that's where better writing comes in. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry On Sat, Sep 18, 2021 at 12:40 PM wrote: > > Send Haskell-Cafe mailing list submissions to > haskell-cafe at haskell.org > > To subscribe or unsubscribe via the World Wide Web, visit > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > or, via email, send a message with subject or body 'help' to > haskell-cafe-request at haskell.org > > You can reach the person managing the list at > haskell-cafe-owner at haskell.org > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Haskell-Cafe digest..." > > > Today's Topics: > > 1. Re: Numerics (was: Re: Trouble with asinh) (Jerzy Karczmarczuk) > 2. On finding the right exposition... (Viktor Dukhovni) > 3. Re: On finding the right exposition... (Tom Ellis) > 4. Re: On finding the right exposition... (Monads) > (Joachim Durchholz) > 5. Re: On finding the right exposition... (Viktor Dukhovni) > 6. Re: On finding the right exposition... (Monads) (Brandon Allbery) > 7. Re: On finding the right exposition... (Monads) (Viktor Dukhovni) > 8. Re: On finding the right exposition... (David Feuer) > 9. Re: On finding the right exposition... (Tom Ellis) > 10. Re: Numerics (was: Re: Trouble with asinh) (Barak A. Pearlmutter) > 11. Re: On finding the right exposition... (Chris Smith) > 12. Re: On finding the right exposition... (Albert Y. C. Lai) > 13. Re: Haskell reference documentation, laws first or laws last? > (Keith) > 14. Re: Haskell's "historical futurism" needs better writing, not > better tools (Douglas McIlroy) > 15. Better writing about Haskell through multi-metaphor learning > (Michael Turner) > 16. Re: Haskell-Cafe Digest, Vol 217, Issue 16 (Anthony Clayden) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Fri, 17 Sep 2021 20:31:24 +0200 > From: Jerzy Karczmarczuk > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Numerics (was: Re: Trouble with asinh) > Message-ID: <32be9982-6be3-c136-c0b4-7622f3d88404 at unicaen.fr> > Content-Type: text/plain; charset="utf-8"; Format="flowed" > > Le 17/09/2021 à 19:16, Carter Schonwald a écrit : > > > Hey Barak, is Common Lisp the only extant language to take those > > issues seriously or are there other examples or better ones? > > // tan / atan troubles cited by Barak. > > Common Lisp?? > > But even the ugly Python reacts better to such examples: > > *>>> from numpy import * > >>> rr, ii = 1.0e-20+0j, 1.0e-20j > * > > *>>> tan(rr),arctan(rr) > ((1e-20+0j), (1e-20+0j)) > >>> tan(ii),arctan(ii) > (1e-20j, 1e-20j)* > > *==* > > This works also with cmath (with arctan as atan). > ** > > Jerzy Karczmarczuk > > > > > -- > L'absence de virus dans ce courrier électronique a été vérifiée par le logiciel antivirus Avast. > https://www.avast.com/antivirus > > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 2 > Date: Fri, 17 Sep 2021 15:47:19 -0400 > From: Viktor Dukhovni > To: haskell-cafe at haskell.org > Subject: [Haskell-cafe] On finding the right exposition... > Message-ID: > Content-Type: text/plain; charset=us-ascii > > On Fri, Sep 17, 2021 at 05:02:09PM +0000, Richard Eisenberg wrote: > > > > Was it literally just a single sentence introducing a new word for a > > > concept that made you "get it"? Could you elaborate? This is really > > > quite remarkable. > > > > For me, coming from a mostly Java background (but with a healthy > > dollop of functional programming thrown in the mix -- but no Haskell), > > the phrase that unlocked monads was "programmable semicolon". > > No single exposition is optimal for all learners. Some are > visual-spacial, others verbal-sequential, and there are likely other > learning styles I've not heard of. > > Therefore, even with good writing, some readers will have to work harder > at understanding the material than others, because they have to > translate the explanations into a form that works for them. > > Also some readers are learning programming and Haskell at the same time, > while others are experienced programmers, but not in Haskell or another > ML-family or functional language. > > A reader far removed from the target audience of the writer may find a > well written document largely unhelpful. There's no silver bullet. > > I haven't yet run into a "Haskell the language" book for experienced > programmers that cuts to the chase and covers Haskell concisely a la > K&R, focusing much more on the language than on how to write code (only > as much code as it takes to minimally illustrate a language feature). > > Such a book would be challenging, because beyond writing basic numeric > expresssions a large part of the language is needed all at once before > one can write even some fairly simple functions. > > An off the cuff list of topics likely poorly ordered: > > * Basic expressions > - Int, Word, Integer, Natural and Double > - Infix operators, associativity and precedence, parentheses > - Sections, (+), (.) and ($) > - let and where > - layout > * Program structure > - Function signature, head and body > - patterns and pattern bindings > - "case" and "if/then/else" > - guards and pattern guards > - modules, imports, and exports > * User defined types > - Algebraic data types, sums, products > + Tuples > + List (mention Array and Vector) > + String (and mention Text) > + Maybe > + Either > - Newtypes > - Type aliases > - GADTs > - Existential types > * More standard types > - Array (immutable) > - Vector (immutable) > * Lazy evaluation and strictness > - Space efficiency, seq and BangPatterns > - ByteString strict, lazy and builders > - Text strict, lazy and builders > - Strict fields and StrictData > * Type classes and constraints > - Integral > - Monoid > - Semigroup > - Foldable > + Strict and lazy folds > * Functors, Monads and Applicatives > - State and IO Monads > - map, fmap and ap > - File I/O > - Streaming > - Applicative option parsing? > * IO, ST and mutable values > - MVector > - MArray > ... lots more ... > > before long we have a book that's considerably larger than K&R. This > then leads to some frustration for the experienced programmer impatient > to learn the basics of the language and get productive right away > without relearning too much from the ground up. > > But then perhaps even modern C++ or Java has a rather non-trivial > learning curve if one is starting from K&R C. > > There may not be a book that reasonably efficiently brings an > experienced non-Haskell programmer to minimal proficiency, and > the separation of pure functions from I/O means having to learn > abstractions that don't come up in most other languages. > > For me, the journey was worth it, and the right book would surely have > helped, (and would still help, I am far from the summit) but in the end > it still takes effort and time. > > -- > Viktor. > > P.S. Re: mental models of monads: > > Personally [verbal sequential], I find strained analogies unhelpful > and distracting, so no desk clerks shuffling forms for me. > > I internalised Haskell monads, by implementing the Functor, Applicative > and Monad instances for Reader and State a few times from scratch. Once > those were solid, ReaderT and StateT and their MonadTrans instances. > > Unsurpsingly, I have a mental model built around sequencing of internal > state updates while passing data from one state to use in choosing the > next state transition. > > I do appreciate "programmable semicolon", but only *after* getting a > more concrete intituition for the standard examples. > > > ------------------------------ > > Message: 3 > Date: Fri, 17 Sep 2021 21:14:23 +0100 > From: Tom Ellis > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] On finding the right exposition... > Message-ID: <20210917201423.GK25255 at cloudinit-builder> > Content-Type: text/plain; charset=us-ascii > > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > I haven't yet run into a "Haskell the language" book for experienced > > programmers that cuts to the chase and covers Haskell concisely a la > > K&R, focusing much more on the language than on how to write code (only > > as much code as it takes to minimally illustrate a language feature). > > The Haskell Report is a good start. > > > ------------------------------ > > Message: 4 > Date: Fri, 17 Sep 2021 22:29:41 +0200 > From: Joachim Durchholz > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] On finding the right exposition... > (Monads) > Message-ID: > Content-Type: text/plain; charset=utf-8; format=flowed > > Am 17.09.21 um 21:47 schrieb Viktor Dukhovni: > > Personally [verbal sequential], I find strained analogies unhelpful > > and distracting, so no desk clerks shuffling forms for me. > > > > I internalised Haskell monads, by implementing the Functor, Applicative > > and Monad instances for Reader and State a few times from scratch. Once > > those were solid, ReaderT and StateT and their MonadTrans instances. > > > > Unsurpsingly, I have a mental model built around sequencing of internal > > state updates while passing data from one state to use in choosing the > > next state transition. > > I have been finding the Monad expositions misleading - that idea that > monads are for sequencing or transitions or mutable state always felt > wrong to me, since the monad laws don't talk about any of these things > at all. > > And as far as I could understand the concept, monads are not about > state, they're about "composing a linear sequence of functions". The > functions' types need not be the same (that would degenerate into the > concept of associativity), but the result type of one function must be > the parameter type of the next. > The monad can do whatever it likes with the functions - typically, wrap > them in some other function and construct a function composition; there > isn't much else you can do with them, though you're not doing much > justice to the Maybe monad if you see it as a pipeline. > Ah... right... and of course the pseudo associativity. I.e. it doesn't > matter what parts of the total sequence you construct first. > > Of course, state transitions are a fine application of this concept. > Or anything else where you see a function as a computation step and you > want to run these steps in sequence. > It's just that there are more kinds of monads. > Except if you see Maybe as "do these operations in sequence until you > hit the first that returns None, then abort". It depends on seeing > functions as executable things though, and that's not really what > Haskell is trying to be (or was trying to be 20 years ago, maybe > everybody is now happy that Haskel finally can express imperative stuff > via monads... no idea what people think) > > Regards, > Jo > > > ------------------------------ > > Message: 5 > Date: Fri, 17 Sep 2021 16:39:15 -0400 > From: Viktor Dukhovni > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] On finding the right exposition... > Message-ID: > Content-Type: text/plain; charset=us-ascii > > On Fri, Sep 17, 2021 at 09:14:23PM +0100, Tom Ellis wrote: > > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > > I haven't yet run into a "Haskell the language" book for experienced > > > programmers that cuts to the chase and covers Haskell concisely a la > > > K&R, focusing much more on the language than on how to write code (only > > > as much code as it takes to minimally illustrate a language feature). > > > > The Haskell Report is a good start. > > I agree that the report is a useful reference, but it is a > specification, not a book from which to learn the language. I wouldn't > actually suggest that anyone learn C by reading the C11 specication, or > Haskell by working their way through the report. > > The report would of course be a useful source of topics and material for > a Haskell the language book. > > -- > Viktor. > > > ------------------------------ > > Message: 6 > Date: Fri, 17 Sep 2021 16:47:09 -0400 > From: Brandon Allbery > To: Joachim Durchholz > Cc: haskell-cafe > Subject: Re: [Haskell-cafe] On finding the right exposition... > (Monads) > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > I suspect a lot of people were pleased that they'd finally gotten rid of > lazy Result -> Request. > > On Fri, Sep 17, 2021 at 4:34 PM Joachim Durchholz wrote: > > > Am 17.09.21 um 21:47 schrieb Viktor Dukhovni: > > > Personally [verbal sequential], I find strained analogies unhelpful > > > and distracting, so no desk clerks shuffling forms for me. > > > > > > I internalised Haskell monads, by implementing the Functor, Applicative > > > and Monad instances for Reader and State a few times from scratch. Once > > > those were solid, ReaderT and StateT and their MonadTrans instances. > > > > > > Unsurpsingly, I have a mental model built around sequencing of internal > > > state updates while passing data from one state to use in choosing the > > > next state transition. > > > > I have been finding the Monad expositions misleading - that idea that > > monads are for sequencing or transitions or mutable state always felt > > wrong to me, since the monad laws don't talk about any of these things > > at all. > > > > And as far as I could understand the concept, monads are not about > > state, they're about "composing a linear sequence of functions". The > > functions' types need not be the same (that would degenerate into the > > concept of associativity), but the result type of one function must be > > the parameter type of the next. > > The monad can do whatever it likes with the functions - typically, wrap > > them in some other function and construct a function composition; there > > isn't much else you can do with them, though you're not doing much > > justice to the Maybe monad if you see it as a pipeline. > > Ah... right... and of course the pseudo associativity. I.e. it doesn't > > matter what parts of the total sequence you construct first. > > > > Of course, state transitions are a fine application of this concept. > > Or anything else where you see a function as a computation step and you > > want to run these steps in sequence. > > It's just that there are more kinds of monads. > > Except if you see Maybe as "do these operations in sequence until you > > hit the first that returns None, then abort". It depends on seeing > > functions as executable things though, and that's not really what > > Haskell is trying to be (or was trying to be 20 years ago, maybe > > everybody is now happy that Haskel finally can express imperative stuff > > via monads... no idea what people think) > > > > Regards, > > Jo > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > -- > brandon s allbery kf8nh > allbery.b at gmail.com > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 7 > Date: Fri, 17 Sep 2021 16:50:25 -0400 > From: Viktor Dukhovni > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] On finding the right exposition... > (Monads) > Message-ID: > Content-Type: text/plain; charset=us-ascii > > On Fri, Sep 17, 2021 at 10:29:41PM +0200, Joachim Durchholz wrote: > > > > Unsurpsingly, I have a mental model built around sequencing of internal > > > state updates while passing data from one state to use in choosing the > > > next state transition. > > > > I have been finding the Monad expositions misleading - that idea that > > monads are for sequencing or transitions or mutable state always felt > > wrong to me, since the monad laws don't talk about any of these things > > at all. > > That's the nature of mental models, they're first approximations with > possible refinements. Yes, there are monads for which State is a poor > analogy. The `Cont` monad comes to mind, one needs to "think different" > when reasoning about `callCC`, `shift` and `reset` > > `State` as a mental model for monads captures basic sequencing with > possible internal "effects" well enough to be a reasonable first > approximation. Already with List exploring all possible paths the > fit is not ideal. > > -- > Viktor. > > > ------------------------------ > > Message: 8 > Date: Fri, 17 Sep 2021 16:52:26 -0400 > From: David Feuer > To: "haskell-cafe at haskell.org" > Subject: Re: [Haskell-cafe] On finding the right exposition... > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > The Report is also a bit outdated in spots. Along with outdated library > info, there's also a very old polymorphic recursion enhancement in GHC (and > I believe also Hugs and other defunct implementations) that should've been > added to Haskell 2010 but wasn't. > > On Fri, Sep 17, 2021, 4:42 PM Viktor Dukhovni > wrote: > > > On Fri, Sep 17, 2021 at 09:14:23PM +0100, Tom Ellis wrote: > > > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > > > I haven't yet run into a "Haskell the language" book for experienced > > > > programmers that cuts to the chase and covers Haskell concisely a la > > > > K&R, focusing much more on the language than on how to write code (only > > > > as much code as it takes to minimally illustrate a language feature). > > > > > > The Haskell Report is a good start. > > > > I agree that the report is a useful reference, but it is a > > specification, not a book from which to learn the language. I wouldn't > > actually suggest that anyone learn C by reading the C11 specication, or > > Haskell by working their way through the report. > > > > The report would of course be a useful source of topics and material for > > a Haskell the language book. > > > > -- > > Viktor. > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 9 > Date: Fri, 17 Sep 2021 21:53:32 +0100 > From: Tom Ellis > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] On finding the right exposition... > Message-ID: <20210917205332.GL25255 at cloudinit-builder> > Content-Type: text/plain; charset=us-ascii > > On Fri, Sep 17, 2021 at 04:39:15PM -0400, Viktor Dukhovni wrote: > > On Fri, Sep 17, 2021 at 09:14:23PM +0100, Tom Ellis wrote: > > > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > > > I haven't yet run into a "Haskell the language" book for experienced > > > > programmers that cuts to the chase and covers Haskell concisely a la > > > > K&R, focusing much more on the language than on how to write code (only > > > > as much code as it takes to minimally illustrate a language feature). > > > > > > The Haskell Report is a good start. > > > > I agree that the report is a useful reference, but it is a > > specification, not a book from which to learn the language. I wouldn't > > actually suggest that anyone learn C by reading the C11 specication, or > > Haskell by working their way through the report. > > My memory of K&R may be deceiving me, but I seem to recall it is a lot > closer to the Haskell Report than the C11 standard is. I would be > interested in the opinion of others who have read these documents more > recently. > > > ------------------------------ > > Message: 10 > Date: Fri, 17 Sep 2021 21:54:13 +0100 > From: "Barak A. Pearlmutter" > To: Carter Schonwald > Cc: Haskell Cafe > Subject: Re: [Haskell-cafe] Numerics (was: Re: Trouble with asinh) > Message-ID: > > Content-Type: text/plain; charset="UTF-8" > > I suspect that most implementations of Common Lisp just call the C > standard library catan(3) etc, which are well tuned. > > $ clisp > Welcome to GNU CLISP 2.49.92 (2018-02-18) > [1]> (atan #c(0 1d-40)) > #C(0 1.0d-40) > > In this particular case, the problem is that the Haskell Data.Complex > code has its own implementation of atan, which uses a log(1 + x) in > calculating the imaginary part. A foreign function call to the > appropriate libm routine would robustly address this, but that would > be difficult because it's trying to be generic over RealFloat a => > Complex a, instead of special casing Complex Float / Complex Double. > Anyway, the Standard Prelude code for this is naïve: it should call > log1p, at the very least—which it actually goes to the trouble of > defining correctly, but not exporting. > > > ------------------------------ > > Message: 11 > Date: Fri, 17 Sep 2021 16:59:09 -0400 > From: Chris Smith > To: haskell-cafe > Subject: Re: [Haskell-cafe] On finding the right exposition... > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > On Fri, Sep 17, 2021 at 3:52 PM Viktor Dukhovni > wrote: > > > No single exposition is optimal for all learners. Some are > > visual-spacial, others verbal-sequential, and there are likely other > > learning styles I've not heard of. > > > > If you'll forgive the slight argumentativeness, I do want to point out, as > someone who follows education research quite a bit, that this learning > styles hypothesis is a pretty well-known myth. It sounds good and feels > true, but has been falsified every time someone has tried to gather > evidence to validate it. > > There are some related statements that are true. For example, different > people certainly have different preferences for modes of presentation, but > those preferences don't actually correlate with how well they learn. > Feeling confused or unsatisfied doesn't mean you're not learning! For > another example, people definitely do learn better when they see > information from several different points of view, but it's apparently not > because different people learn best from different points of view, but > rather because all people learn best when they have more different > perspectives to integrate. And for a last example, people definitely do > have preferences and abilities for learning different kinds of content, > which are in turn most naturally communicated in certain ways, but it's > apparently the natural way to present an idea that matters more in terms of > learning, not the individual's preferences for style. > > This is actually pretty related to what we're talking about here. If it > were true that different people understand monads better when they are > presented in ways that match the individual's style of learning, reliable > evidence of this would be revolutionary in education research. (Meaning: > it's very, very likely not to be true, though I cannot point to research > that studies understanding monads, in particular.) But luckily, the > solution to this myth is just *not* to differentiate, but rather to provide > all of these points of view to everyone who is learning, whether they > *feel* that > this is the right presentation or it *feels* like it's making sense to them > or not. When evaluating our own learning experiences, we should be careful > to remember that the times we were learning were probably actually the > times we felt a bit confused. The presentation that finally made sense > probably wasn't the most helpful one. > > See https://www.google.com/search?q=learning+styles+myth for lots of > sources. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 12 > Date: Fri, 17 Sep 2021 17:02:23 -0400 > From: "Albert Y. C. Lai" > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] On finding the right exposition... > Message-ID: > Content-Type: text/plain; charset=utf-8; format=flowed > > I agree with improving teaching/learning materials. But here is a small > point I object to: > > On 2021-09-17 3:47 p.m., Viktor Dukhovni wrote: > > On Fri, Sep 17, 2021 at 05:02:09PM +0000, Richard Eisenberg wrote: > > > > No single exposition is optimal for all learners. Some are > > visual-spacial, others verbal-sequential, and there are likely other > > learning styles I've not heard of. > > Please consult for example https://www.youtube.com/watch?v=rhgwIhB58PA > > It is long past high time to kill that outdated zombie myth. > > What I stand behind is: Every student needs every perspective they can > get their hands on. > > But it is not because every student is only good at just one thing. > > > ------------------------------ > > Message: 13 > Date: Fri, 17 Sep 2021 21:04:27 +0000 > From: Keith > To: Haskell Cafe > Subject: Re: [Haskell-cafe] Haskell reference documentation, laws > first or laws last? > Message-ID: <7E95F060-6A82-4F5C-94D8-B21458C672BF at gmail.com> > Content-Type: text/plain; charset="utf-8" > > Perhaps it would make sense to have a 'using the class' section and a 'writing instances' section. > The first would focus on more concrete and intuitive examples. > The second would explain how and why to follow the laws, maybe with specific ways to avoid pitfalls and extra work (e.g. when you can and can't DeriveFoldable, when to use `foldMapDefault` when to define only `foldr` or `foldMap` or to use `toList` to define others. > > It's super important that folks gan define legal instances so things don't brow up in their faces (e.g. an Applicative instance that zips but defines `pure` as a singleton). But often all they need to know is `DeriveTraversable` exists and works as long as you don't define things in strange ways (like conceptually reversed lists). > --Keith > Sent from my phone with K-9 Mail. > > On 17 September 2021 08:30:37 UTC, Ignat Insarov wrote: > >Hello Viktor. > > > >Thank you for your continuous effort. > > > >I have been writing Haskell for years now and even getting paid for > >it. I care nothing for the laws — I rarely apply equational reasoning. > >I am a visual person, to me intuitive grasp is the tool of choice. I > >also know a few newcomers to Haskell and I am certain they make zero > >use of the laws. > > > >My thus informed view is that laws are fine in the end and useless at the start. > > > >On Fri, 17 Sept 2021 at 04:48, Viktor Dukhovni wrote: > >> > >> On Thu, Sep 16, 2021 at 06:51:42PM -0400, David Feuer wrote: > >> > >> > The last time I went to look at the laws it took me a couple minutes to > >> > find them. I use them to write instances. Pretty important, IMO. > >> > >> I agree the laws are important to document, I just don't think they > >> belong at the top of the module. The beginner to intermediate users > >> will be using the library and existing instances for some time before > >> they start to write their own instances. > >> > >> If more modules adopt something like the style of the new Data.Foldable, > >> experienced users will know to look for the laws at the end, if not > >> still present at the top of the module. > >> > >> Of course perhaps the community would prefer the original Laws first > >> format, I'm fine with that emerging as the consensus. Perhaps worthy > >> of a separate thread (made it so). > >> > >> Of course the conjectured users who might most benefit from not being > >> intimidated by being exposed to laws before they're ready to understand > >> them might not be present on this forum... > >> > >> -- > >> Viktor. > >> _______________________________________________ > >> Haskell-Cafe mailing list > >> To (un)subscribe, modify options or view archives go to: > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >> Only members subscribed via the mailman list are allowed to post. > >_______________________________________________ > >Haskell-Cafe mailing list > >To (un)subscribe, modify options or view archives go to: > >http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > >Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Message: 14 > Date: Fri, 17 Sep 2021 21:47:34 -0400 > From: Douglas McIlroy > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > better writing, not better tools > Message-ID: > > Content-Type: text/plain; charset="UTF-8" > > > Lambda calculus is an excellent place for beginners to start. > > What could be easier to learn? It's certainly easier than grokking > > a Turing machine; and much easier than Haskell: less than a > > handful of primitives yet can compute anything computable. > > There's a category error (in the sense of logic, not algebra) here. > Learning a language is not comparable to understanding a program. > The concept of lambda calculus is far more subtle than that of > Turing machine. But if you know both, a program is likely to be > much easier to understand when presented in lambda calculus > than when presented as a Turing machine. > > Doug > > > ------------------------------ > > Message: 15 > Date: Sat, 18 Sep 2021 11:56:37 +0900 > From: Michael Turner > To: haskell-cafe at haskell.org > Subject: [Haskell-cafe] Better writing about Haskell through > multi-metaphor learning > Message-ID: > > Content-Type: text/plain; charset="UTF-8" > > Well, this is certainly blowing up into something bigger than I > thought it would. (At one point last night, 12 people had my "Haskell > in Plain English" essay/chapter open on Google Docs, a very > unintentional side effect.) > > Me: "I finally got (most of?) what monads really mean for practical > programming when none other than Simon Peyton-Jones said F# called a > very similar construct "workflow," a word he likes." > > A response: "Was it literally just a single sentence introducing a > new word for a concept that made you "get it"? Could you elaborate? > This is really quite remarkable." > > Richard Eisenberg: "For me, coming from a mostly Java background (but > with a healthy dollop of functional programming thrown in the mix -- > but no Haskell), the phrase that unlocked monads was "programmable > semicolon"." > > I think one explanation for the Monad Tutorial Explosion (and how it > still didn't work for a lot of people) is that there's no single right > metaphor that will finally make monads "click". It depends on what > combination of conceptions (and perhaps all misconceptions to be > dispelled) is floating around in given mind. And minds vary. > > Workflow is a metaphor at one useful level. "Programmable semicolon" > is a metaphor at another useful level. > > Semicolon as imperative-language separator actually hides a lot that's > going on in a real CPU. Even if the imperative language is assembly > language, the compiled instructions go to an instruction fetch/decode > unit that -- these days especially -- can be engaged in a bewildering > number of tasks, including finishing up several previous instructions, > translating the decoded instruction to what amounts to microcode that > get sent to an instruction cache, and fetching the next few > instructions even as it's been decoding the instruction fetched into a > little to-do list for the CPU. Perhaps we can think of instruction > fetch/decode as "monadal" -- it's wildly (but not chaotically) mapping > a previous state of the machine into new one. After all, it's all > still Turing machines down there somewhere (but even the Turing > machine was mathematically defined as a function that maps one > tape-state to the next while it's also mapping its internal state to a > new state.) So the semicolon can be thought of as lexically exposing > the fetch-decode operator in the CPU's own little program. > > The "workflow" metaphor is at a higher level. If you think of how > incoming data can be sorted and parceled out as if to a number of > desks in an office, with forms processed at a desk going from one > outbox to another desk's inbox, you're ignoring exact sequencing. It's > the view where you're labeling desks by their specialized tasks and > drawing outbox-inbox connections. In this view, it matters little > that, in the one-instruction-at-a-time CPU model, there's only one > "clerk" who (ridiculously, I know) puts a form in an inbox, then takes > it out again, puts it in the inbox of another desk, then sits down at > that other desk, takes the same form out and does the very specific > form-processing task assigned to that desk. You can instead imagine it > as some sluggish bureaucracy where everyone else but the single busy > clerk is waiting for a form to hit their empty inboxes. The fact is, > "one-instruction-at-a-time CPUs" hardly exist anymore except in the > cheapest microcontrollers -- there are all multitasking like crazy. > And this is because CPU designers work very hard to see how much of > the little bureaucracy they can actually keep busy, ideally at all > times, but at least at high throughput for average instruction > streams, even if 100% utilization is seldom reached. (Lambda, the > Ultimate Semicolon?) > > Bryan: "Listing sequential actions one after the other is so intuitive > you see it everywhere. Take baking recipes as one example. Or assembly > code. Or poems." > > Yes, sequencing just grows out of the fact of time. You'd think that > poems aren't really sequences of tasks to do. But in a way, they are, > and in a sense that matters for my attempts at natural-language > understanding. There IS an implicit imperative in the energy required > to speak: the subtext of any statement addressed to another person > (even when it's dead poet to living reader) is: think about what I'm > saying. Each new word in a sentence being spoken maps the listener's > mind-state to a new one. The purpose of the sequencing is to build up > state in the listener's mind. > > "When a Haskeller says, "Monads are great! They let you chain effectful > actions together!" it can take a very long time to understand they actually > mean exactly what they're saying — the usual intuition is that sequencing > actions can't possibly be a real problem, so you go round and round in > circles trying to understand what "effectful" means, what "action" means, > and how these oh-so-important "laws" have anything to do with it." > > Yes, it's sort of like aliens from outer space with a very alien > consciousness, and a different relation to the dimension of time, and > they are exulting (to each other, and to themselves, really, more than > to you): > > "Periods at the ends of sentences are great! They enable these strange > blobs of protoplasm who call themselves 'human' to more easily map the > states of these internal things they call 'neurons' into new states. > No wonder we've been having such trouble trying to tell them what to > do, using our intuitively obvious gestaltic visual patterns that allow > us to grasp, with our quantum-computer brains, a whole meaning at > once, through our retinas." > > (Yes, I am riffing a little here on the SF movie Arrival.) > > Math is this world where we can feel a little like that. Instead of > thinking of a function as a machine that takes inputs, grinds away for > a little while, and extrudes outputs, you can think of all inputs and > output as already existing, and reason logically from the resulting > properties. Haskell's laziness helps you fake what you can't really > have: infinite workspace and the ability to do everything in an > instant. It's a fake-it-til-you-make-it language, and you don't have > to be Buzz Lightyear going to infinity and beyond, perhaps to all the > way to the galaxy Aleph-omega. You just have to make a Haskell program > do something that people like as much as their Buzz Lightyear doll. > > The math view is a useful view at one level, but it can only help you > so much. I greatly enjoyed the level where I could define a Turing > machine as a mapper from one infinite tape to another, then imagine > all possible Turing machines as a countably infinite set. I could then > prove, with Cantor diagonalization (abstractly, at least, though not > very intuitively) that there are things Turing machines can't do. I > loved that. > > But I also listened to grad students mutter about how recursive > function theory may be beautiful and all, but it's now classical, and > therefore dead for their own practical purposes (getting a PhD, > getting onto tenure track.) And by then I knew I wasn't good enough at > math to make a go of computing theory in their world, as a career, no > matter what. I think Simon Peyton-Jones had a similar experience of > academia -- he wasn't a John Hughes -- but he found a way through > anyway. > > Bryan: "I can understand why that [puzzled newbie] viewpoint might be > long-forgotten by those who were involved in the effort to solve it. > :) And I appreciate that it was solved in such a general way that it > can be applied to so many seemingly unrelated things! That's the > beauty of mathematics!" > > Yes, it's there. But in user experience design (and writings about > Haskell ARE part of its user experience) there's a saying: the > intuitive is the familiar. At some point in gaining sophistication, > it's no longer intuitively obvious to you why something wasn't > intuitively obvious for you before. You're so absorbed in where you > are that you don't remember quite how you got there. You might even > assume that everyone who has gotten where you are has gotten there by > the same route. And, if you can dimly remember how you got a flash of > inspiration, you might end up writing yet another monad tutorial that > few people understand. > > "Workflow" helped me. And now "programmable semicolon" is helping a > little, in another way. > > I presented a strategy at the NSMCon-2021 conference: think of NSM > reductive paraphrasing as writing very complete and precise code for > natural-language terms and grammar rules, using NSM primes and syntax > as a kind of logic programming language -- one that might even be very > simply translatable to Prolog. > > I did some coding experiments and saw a problem: viewed more > procedurally -- i.e., with each line of an NSM explication adding to a > conceptual schema of a natural-language meaning -- NSM wasn't > single-assignment. A Prolog interpreter couldn't just try a match, > looking at each statement of an explication in relative isolation, and > bail out when a statement failed to be true in the given context of > the attempted match. It had to drag some state along just to resolve > what the NSM prime "this" referred to. (Think of "it" in GHCI.) > > OK: effects. But wait, more: scoped effects. You want to strip some > schema-stuff back out if a match failed midway through, then try > another match somewhere else. OK: I need a context stack to store > assertions that succeeded. Uh-oh, Prolog doesn't give me that paper > trail. Dang. And I still want the one-for-one translation of sentences > in an NSM reductive paraphrase to something like Prolog. > > OK: I need to grab control of sequencing, so that I can not only use > the intrinsic Horn clause resolution without pain. But I also want it > to hold onto the assertions that succeeded, and knit them into the > growing conceptual schema that's part of the state. AND I want it roll > those back out, transactionally, if a match didn't succeed. It turns > out that Prolog makes this not too much harder than, say, a Lisp with > transactional memory. > > So: I think I might now return to my Prolog code and see if I was > unconsciously reinventing some kind of monad. Because because I felt > forced by Prolog's limits to write my own semicolon. It wasn't too > hard, though the resulting code required for NSM explications looks > clunkier now. (Prolog is very limited in syntax extensibility.) Maybe > there's some way in which Haskell makes it easier still, and > nicer-looking too. > > None of which is to say that "programmable semicolon" will immediately > help everyone pick the conceptual lock of monads. But for those who > just bonk on "programmable semicolon", it might help to point out that > the load-operate-store model of CPUs is a lie these days. Say a little > about why it's not true. Then again pose semicolon as a kind of > operator. People like to think, "OK, this statement will finish, and > the one after the semicolon will start." It's a convenient view, even > though in fact, while the imperative statement is in progress, the CPU > might have already fetched instructions beyond it, and scheduled them > for speculative execution. > > Or, you can tell them, "Just learn lambda calculus, then study monads > algebraically, and here's a side dish of category theory while I'm it. > Bon appetit." How's that working for you, guys? It doesn't work for > me. And I don't think it's because I can't do the math. It's that I > often write code to see whether I'm thinking about a problem the right > way. > > And is that so bad? I believe it was in Stewart Brand's "II Cybernetic > Frontiers" where a researcher at Xerox PARC, Steve ("Slug") Russell, > one of their star hackers, was described by his peers as "thinking > with his fingertips." > > I'm no star hacker, but "workflow" feels like it will make my > fingertips smarter. "Programmable semicolon" feels like it will make > my fingertips smarter. You think top-down mathematically? Well, bon > appetit. It's not to my taste. No single way is likely to work for > all. Math is not some fundamental reality. It's not even reality -- in > fact, it gains a lot of its power precisely from being imaginary. And > it's just a bunch of metaphors too. > > Regards, > Michael Turner > Executive Director > Project Persephone > 1-25-33 Takadanobaba > Shinjuku-ku Tokyo 169-0075 > Mobile: +81 (90) 5203-8682 > turner at projectpersephone.org > > Understand - http://www.projectpersephone.org/ > Join - http://www.facebook.com/groups/ProjectPersephone/ > Donate - http://www.patreon.com/ProjectPersephone > Volunteer - https://github.com/ProjectPersephone > > "Love does not consist in gazing at each other, but in looking outward > together in the same direction." -- Antoine de Saint-Exupéry > > > ------------------------------ > > Message: 16 > Date: Sat, 18 Sep 2021 15:35:29 +1200 > From: Anthony Clayden > To: haskell-cafe at haskell.org > Subject: Re: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 > Message-ID: > > Content-Type: text/plain; charset="utf-8" > > >>* Haskell's big problem right now is adoption. > * > > Heh heh, this sentence is multi-ways ambiguous. As in the 'problem' is > that there's too many adopters/the wrong sort of people trying to > adopt Haskell. The 'problem' is that Haskell is not keeping to its > objective to "avoid success at all costs". > > > I'm not quite sure this is a problem. Haskell and its libraries are designed around math concepts, as opposed to CS concepts (semigroup vs IConcatenable). Learning it all but requires learning some algebra as well, thus a lower adoption rate is expected. > > > Thank you for saying that out loud. I've been feeling for some time > that GHC is getting harder to use. You're telling me that because I > don't get Category Theory you want to throw me out of using Haskell. > People who are allergic to Lambda-calculus are already excluded. > > So the ostensible difficulty on these threads: that the documentation > is unhelpful, is not the problem at all. In fact it's deliberate that > the docos are exclusionary. As part of this grand plan, Viktor is > deliberately making the Libraries docos impenetrable. (By which I > mean: the style is clear, but the material is unlearnable. Apparently > I need to know what is an endomorphism before I can write a Foldable > instance) > > And that explains a paradox: I learnt Haskell over a decade ago. There > was far less intro material; and certainly no store of StackOverflow > questions/answers. It should have been more difficult to learn than > today. But I don't remember learning being as difficult as the claims > on this thread. (Memory can deceive, I guess.) > > Back then Haskell was a much smaller, simpler language. There was less > that could go wrong at the type level; and the error messages didn't > keep recommending to switch on bamboozling features that (as it turned > out) made the difficulty harder. Don't go claiming that if I switch > off those features today it's as if I was still using H2010. Simply > not true. > > I know that's not true, because I can still go back and use Hugs, or > use GHC v7.10 (vintage ~2015), and have a much more pleasant/less > bamboozling experience. > > > Then "Haskell's big problem right now" is (depending on your point of > view) either GHC or too many of the wrong adopters. And with Dependent > Types coming along GHC is going to get a lot worse. (Maybe GHC will > eventually get through the fog, throw out a load of cruft and become > on average as usable as v7.10. I'm not prepared to go through the pain > for 5 years to find out. I'll stick with v7.10.) > -------------- next part -------------- > An HTML attachment was scrubbed... > URL: > > ------------------------------ > > Subject: Digest Footer > > _______________________________________________ > Haskell-Cafe mailing list > Haskell-Cafe at haskell.org > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > ------------------------------ > > End of Haskell-Cafe Digest, Vol 217, Issue 22 > ********************************************* From branimir.maksimovic at gmail.com Sat Sep 18 12:11:31 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sat, 18 Sep 2021 14:11:31 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <34d27e9a-8736-62c6-23ea-8d7a38b4613a@durchholz.org> References: <20210918080002.GN25255@cloudinit-builder> <22AF45B6-2FF5-42D3-B372-2FBD54532DDB@gmail.com> <34d27e9a-8736-62c6-23ea-8d7a38b4613a@durchholz.org> Message-ID: <0AF02494-6710-47FD-A252-3AC5C0032390@gmail.com> I don“t see how does that anything to do with Monad ČP It“s just what you pass as return value. Do { … ... } that’s just syntactic sugar, to look more nicely. Greetings, Branimir. > On 18.09.2021., at 12:34, Joachim Durchholz wrote: > > Am 18.09.21 um 11:19 schrieb Branimir Maksimovic: >> This is monad: >> f(g(h(…))) >> To make sequence out of functions. > > Ah, no. That's just function composition. > > A monad can do more - e.g. Maybe interleaves the functions with a check whether it was passed in Nothing. > > Regards, > Jo > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From anthony.d.clayden at gmail.com Sat Sep 18 12:12:08 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Sun, 19 Sep 2021 00:12:08 +1200 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. Message-ID: The end of your error message: > | > 63 | pattern Any a <- Some a > | ^ Appears to have program text (a mono-directional pattern binding) that doesn't correspond to the program text you quote. Whereas > pattern Any :: forall a. a -> Some > pattern Any a = Some Is a implicitly bi-directional pattern binding that will never work. (The free var `a` on LHS does not appear in RHS.) I'm suspecting the explicit forall is not much to do with it. -------------- next part -------------- An HTML attachment was scrubbed... URL: From coot at coot.me Sat Sep 18 14:32:04 2021 From: coot at coot.me (coot at coot.me) Date: Sat, 18 Sep 2021 14:32:04 +0000 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. In-Reply-To: References: Message-ID: On Saturday, September 18th, 2021 at 14:12, Anthony Clayden wrote: > The end of your error message: > > > | > > 63 | pattern Any a <- Some a > > | ^ > > Appears to have program text (a mono-directional pattern binding) that doesn't correspond to the program text you quote. I just tried both ways of writing bidirectional pattern synonmys, neither worked with explicit `forall`. > I'm suspecting the explicit forall is not much to do with it. With an implicit forall, the code does type check. Regards, Marcin -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 509 bytes Desc: OpenPGP digital signature URL: From jkb at jkbsc.co.uk Sat Sep 18 14:41:30 2021 From: jkb at jkbsc.co.uk (John Beattie) Date: Sat, 18 Sep 2021 15:41:30 +0100 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> <20210917201423.GK25255@cloudinit-builder> Message-ID: <20210918144130.GA492846@fladday.local> Seconded. This worked for me also as a good starting point. The report is quite readable. On 2021-09-18 12:15 +0300, Bryan Richter wrote: > I started learning Haskell by reading the Report, and I warmly recommend that > strategy. In particular, I just skipped over the terminology that didn't make > sense to me yet, and I didn't try too hard to keep the big picture in my head > (suggestion to future versions: put all the BNF diagrams in the same place!) > > Even with a rudimentary read-through, I was already advanced beyond the likes > of LYAH and ready to start running simple programs in ghci. Even today I > sometimes know things about syntax that surprise my colleagues. > > I didn't need to know monads yet. The build tool challenges were a bigger > stumbling block at that point. > > But best of all, I was familiar with the reference material, so I could easily > go back and reread things when necessary! > > > On Fri, 17 Sep 2021, 23.40 Viktor Dukhovni, wrote: > > On Fri, Sep 17, 2021 at 09:14:23PM +0100, Tom Ellis wrote: > > On Fri, Sep 17, 2021 at 03:47:19PM -0400, Viktor Dukhovni wrote: > > > I haven't yet run into a "Haskell the language" book for experienced > > > programmers that cuts to the chase and covers Haskell concisely a la > > > K&R, focusing much more on the language than on how to write code (only > > > as much code as it takes to minimally illustrate a language feature). > > > > The Haskell Report is a good start. > > I agree that the report is a useful reference, but it is a > specification, not a book from which to learn the language.  I wouldn't > actually suggest that anyone learn C by reading the C11 specication, or > Haskell by working their way through the report. > > The report would of course be a useful source of topics and material for > a Haskell the language book. > > -- >     Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From a.pelenitsyn at gmail.com Sat Sep 18 18:02:11 2021 From: a.pelenitsyn at gmail.com (Artem Pelenitsyn) Date: Sat, 18 Sep 2021 14:02:11 -0400 Subject: [Haskell-cafe] Numerics (was: Re: Trouble with asinh) In-Reply-To: References: Message-ID: Hey Barak, These are really good points. They seem worth submitting to the GHC issue tracker. This would be a first step on the way to improve the current (not ideal, as you say) state. — Best, Artem On Fri, Sep 17, 2021 at 5:06 PM Barak A. Pearlmutter wrote: > I suspect that most implementations of Common Lisp just call the C > standard library catan(3) etc, which are well tuned. > > $ clisp > Welcome to GNU CLISP 2.49.92 (2018-02-18) > [1]> (atan #c(0 1d-40)) > #C(0 1.0d-40) > > In this particular case, the problem is that the Haskell Data.Complex > code has its own implementation of atan, which uses a log(1 + x) in > calculating the imaginary part. A foreign function call to the > appropriate libm routine would robustly address this, but that would > be difficult because it's trying to be generic over RealFloat a => > Complex a, instead of special casing Complex Float / Complex Double. > Anyway, the Standard Prelude code for this is naïve: it should call > log1p, at the very least—which it actually goes to the trouble of > defining correctly, but not exporting. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From caeeh at yandex.com Sat Sep 18 18:29:27 2021 From: caeeh at yandex.com (Caeeh) Date: Sat, 18 Sep 2021 21:29:27 +0300 Subject: [Haskell-cafe] Shrink function names Message-ID: <236921631989669@mail.yandex.com> An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sat Sep 18 18:41:01 2021 From: david.feuer at gmail.com (David Feuer) Date: Sat, 18 Sep 2021 14:41:01 -0400 Subject: [Haskell-cafe] Shrink function names In-Reply-To: <236921631989669@mail.yandex.com> References: <236921631989669@mail.yandex.com> Message-ID: I don't know if this is possible, but maybe you could use -opta (or -optlc or -optlo) to pass an appropriate option to the assembler (or LLVM compiler). Or -optlm to pass something to the linker. GHC itself probably doesn't support what you're trying to do, because obfuscating object code has never been a development priority. On Sat, Sep 18, 2021, 2:30 PM Caeeh wrote: > How can the names of functions from the generated executable be > hidden/shrinked/erased? > I tried with -O2 option in GHC, but it does not work. In the binary I > found names that are present in the source code. I want to remove them. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexis.praga at gmail.com Sat Sep 18 18:52:24 2021 From: alexis.praga at gmail.com (Alexis Praga) Date: Sat, 18 Sep 2021 20:52:24 +0200 Subject: [Haskell-cafe] Cabal or stack in 2021 ? Message-ID: Hi, As an intermediate beginner, I've been back into Haskell for the last months for a small project, using stack as the building tool. Why stack ? A few years back, I learned that it was the "best" way to build projects to avoid "cabal hell", which I understood at the time as "managing dependencies with cabal is hard". As such, I've use stack since and have been quite happy with it. The only drawback is that building a project can be quite long. This is usually not a problem, except for writing Haskell scripts using shelly (for example), where the stack layout is a bit impractical for fast-paced development. A solution is to use `runghc` or a script interpreter [1]. However, I've seen some projects where cabal is used to build directly instead of cabal, so it looks like the situation improved. My question is this: in 2021, is there a reason to switch back to cabal ? Thanks, [1] https://www.fpcomplete.com/haskell/tutorial/stack-script/ -- Alexis Praga -------------- next part -------------- An HTML attachment was scrubbed... URL: From coot at coot.me Sat Sep 18 19:06:54 2021 From: coot at coot.me (coot at coot.me) Date: Sat, 18 Sep 2021 19:06:54 +0000 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: References: Message-ID: Hi Alexis, There are several reasons: * reproducible nix style local builds.  By specifying hackage index one can build against the same set of packages locally and on CI. * has access to whole hackage, though at times requires a bit of thought, most of the time it works just fine. * `cabal.project` and `cabal.project.local`: the first corresponds to `stack.yaml`, the other does not have a counter part in stack.  For example, this is very useful, when one wants to modify ghc options per package, e.g. adding or removing `-Werror` ghc option, or configuring a ghc plugin * some options work better than in stack. One example is `--allow-newer`. * one can experiment with backpack, Cheers Marcin Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Saturday, September 18th, 2021 at 20:52, Alexis Praga wrote: > Hi, > > As an intermediate beginner, I've been back into Haskell for the last > > months for a small project, using stack as the building tool. > > Why stack ? A few years back, I learned that it was the "best" way to build > > projects to avoid "cabal hell", which I understood at the time as > > "managing dependencies with cabal is hard". > > As such, I've use stack since and have been quite happy with it. The > > only drawback is that building a project can be quite long. > > This is usually not a problem, except for writing Haskell scripts using > > shelly (for example), where the stack layout is a bit impractical for > > fast-paced development. A solution is to use `runghc` or a script > > interpreter [1]. > > However, I've seen some projects where cabal is used to build directly > > instead of cabal, so it looks like the situation improved. > > My question is this: in 2021, is there a reason to switch back to cabal ? > > Thanks, > > [1] https://www.fpcomplete.com/haskell/tutorial/stack-script/ > > -- > >    Alexis Praga -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 509 bytes Desc: OpenPGP digital signature URL: From ietf-dane at dukhovni.org Sat Sep 18 19:13:32 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Sat, 18 Sep 2021 15:13:32 -0400 Subject: [Haskell-cafe] Shrink function names In-Reply-To: <236921631989669@mail.yandex.com> References: <236921631989669@mail.yandex.com> Message-ID: On Sat, Sep 18, 2021 at 09:29:27PM +0300, Caeeh wrote: >
How can the names of functions from the generated executable > be hidden/shrinked/erased?
I tried with -O2 option in GHC, > but it does not work. In the binary I found names that are present in > the source code. I want to remove them.
Did you "strip" the executable? Are the functions in question exported by their module? If you compile the program below, the executable will have the "unstripped" executable with have the string "secretName", but it disappears if you "strip" it (GHC option: -optl-s): module Main (main) where import Data.Maybe import System.Environment secretName :: [String] -> Maybe Int secretName = fmap ((+ 42) . read) . listToMaybe {-# NOINLINE secretName #-} main :: IO () main = secretName <$> getArgs >>= mapM_ print Demo: $ rm foo.o foo.hi; ghc -O2 foo.hs; strings -a foo | grep secretName [1 of 1] Compiling Main ( foo.hs, foo.o ) Linking foo ... Main_secretName_closure Main_secretName_info $ rm foo.o foo.hi; ghc -optl-s -O2 foo.hs; strings -a foo | grep secretName [1 of 1] Compiling Main ( foo.hs, foo.o ) Linking foo ... -- Viktor. From olf at aatal-apotheke.de Sat Sep 18 23:07:24 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Sun, 19 Sep 2021 01:07:24 +0200 Subject: [Haskell-cafe] On finding the right exposition... Message-ID: Perhaps one thing that speaks in favour of Anthony Clayden's suggestion to learn lambda calculus before/along Haskell is this: Haskell shares the evaluation model with the lambda calculus. One of Michael Turner's points of criticism was, as I understand it, insufficient documentation about the inner workings of Haskell [1]. Haskell needs constructs like the ST monad because of the evaluation model. Once the learner knows, perhaps by experimenting with it on paper or on [2,3], that a lambda term can be reduced in several ways, and confluence guarantees that all ways result in the same normal form, then some things might be much clearer: * Which freedoms the compiler can exercise in evaluating your program. * Why one needs the State monad for ordering sequences of effects (the programmable semicolon) [4]. * How the various tricks and pitfalls around lazy and strict functions work, e.g. Viktor's new Foldable documentation. I looked at the first chapter of my K&R. It presents small example C programs and explains what they do. Taking small Haskell programs and explaining how these lambda terms are reduced to normal form would be a comparable (and desirable, in Michael's view) approach? The Haskell language report does not say anything in this respect, as far as I can see. Only translation of syntactic constructs to core Haskell is given. Olaf [1] Of course the documentation is out there somewhere, but not written in a style which pleases learners like Michael. [2] https://lambdacalc.io/ [3] https://capra.cs.cornell.edu/lambdalab/ [4] I tried to convince myself that the state monad indeed sequences effects. In a pure lambda world I think this should mean that a certain lambda term has only one way of being reduced. Is the following valid reasoning? type State s a = s -> (a,s) When Church-encoding the tuple (a,s) one finds that (m :: State s a) >>= (k :: a -> State s b) = \s -> m s k so the only applicable rule is beta-reducing m when applying to some s. From cdsmith at gmail.com Sat Sep 18 23:20:17 2021 From: cdsmith at gmail.com (Chris Smith) Date: Sat, 18 Sep 2021 19:20:17 -0400 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: Message-ID: I don't think it quite makes sense to say that Haskell shares the evaluation model with lambda calculus, because I don't think it's fair to say that lambda calculus has any specific evaluation model at all. Do you mean substitution, for example? But that's only one way to implement lambda calculus, and not one that is shared by any widely used Haskell implementation. But I do agree there's a point here. There's a simplicity that the purely functional fragment of Haskell shares with the lambda calculus, which I wish were easier to get across to new Haskell programmers. That simplicity is precisely what allows the lambda calculus, as well as the purely functional fragment of Haskell, to have a meaning *without* answering the question of how it is evaluated. (Even in more complex programming languages, the notion of evaluation that is used to define the language is often not the same one that's used by implementations, of course. But nevertheless these languages must be defined in terms of some model of evaluation, where the purely functional fragment of Haskell doesn't.) I struggle with this. In some very real ways, I consider it the most important point of learning Haskell for many programmers. But it's also not a prerequisite to using Haskell for practical purposes. For me, since I learned Haskell in order to just experience the cool ideas that it contains (and only 15 years later got my first job programming in Haskell), that's reason enough. But, within reason at least, it's the learner's goals that matter most when learning. Someone who isn't looking to understand the fundamental simplicity of a portion of Haskell isn't likely to be motivated to work through the effort it takes to understand it. So there must be some ways, at least, to learn Haskell without focusing on that particular aspect of the language. A Haskell programmer won't be as good of a Haskell programmer as they could be without understanding it, and will struggle to write idiomatic pure code. But one must start somewhere. New Python programmers don't write idiomatic or perfect Python, either! On Sat, Sep 18, 2021 at 7:11 PM Olaf Klinke wrote: > Perhaps one thing that speaks in favour of Anthony Clayden's suggestion > to learn lambda calculus before/along Haskell is this: > Haskell shares the evaluation model with the lambda calculus. One of > Michael Turner's points of criticism was, as I understand it, > insufficient documentation about the inner workings of Haskell [1]. > Haskell needs constructs like the ST monad because of the evaluation > model. Once the learner knows, perhaps by experimenting with it on > paper or on [2,3], that a lambda term can be reduced in several ways, > and confluence guarantees that all ways result in the same normal form, > then some things might be much clearer: > * Which freedoms the compiler can exercise in evaluating your program. > * Why one needs the State monad for ordering sequences of effects (the > programmable semicolon) [4]. > * How the various tricks and pitfalls around lazy and strict functions > work, e.g. Viktor's new Foldable documentation. > > I looked at the first chapter of my K&R. It presents small example C > programs and explains what they do. Taking small Haskell programs and > explaining how these lambda terms are reduced to normal form would be a > comparable (and desirable, in Michael's view) approach? The Haskell > language report does not say anything in this respect, as far as I can > see. Only translation of syntactic constructs to core Haskell is given. > > Olaf > > [1] Of course the documentation is out there somewhere, but not written > in a style which pleases learners like Michael. > [2] https://lambdacalc.io/ > [3] https://capra.cs.cornell.edu/lambdalab/ > [4] I tried to convince myself that the state monad indeed sequences > effects. In a pure lambda world I think this should mean that a certain > lambda term has only one way of being reduced. Is the following valid > reasoning? > type State s a = s -> (a,s) > When Church-encoding the tuple (a,s) one finds that > (m :: State s a) >>= (k :: a -> State s b) > = \s -> m s k > so the only applicable rule is beta-reducing m when applying to some s. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sat Sep 18 23:20:56 2021 From: david.feuer at gmail.com (David Feuer) Date: Sat, 18 Sep 2021 19:20:56 -0400 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: Message-ID: GHC's use of a State-like monad to represent I/O is semantically bogus, a fact that rears its head in a few compiler transformations (including strictness analysis). I wouldn't take it as a good mental model. On Sat, Sep 18, 2021, 7:09 PM Olaf Klinke wrote: > Perhaps one thing that speaks in favour of Anthony Clayden's suggestion > to learn lambda calculus before/along Haskell is this: > Haskell shares the evaluation model with the lambda calculus. One of > Michael Turner's points of criticism was, as I understand it, > insufficient documentation about the inner workings of Haskell [1]. > Haskell needs constructs like the ST monad because of the evaluation > model. Once the learner knows, perhaps by experimenting with it on > paper or on [2,3], that a lambda term can be reduced in several ways, > and confluence guarantees that all ways result in the same normal form, > then some things might be much clearer: > * Which freedoms the compiler can exercise in evaluating your program. > * Why one needs the State monad for ordering sequences of effects (the > programmable semicolon) [4]. > * How the various tricks and pitfalls around lazy and strict functions > work, e.g. Viktor's new Foldable documentation. > > I looked at the first chapter of my K&R. It presents small example C > programs and explains what they do. Taking small Haskell programs and > explaining how these lambda terms are reduced to normal form would be a > comparable (and desirable, in Michael's view) approach? The Haskell > language report does not say anything in this respect, as far as I can > see. Only translation of syntactic constructs to core Haskell is given. > > Olaf > > [1] Of course the documentation is out there somewhere, but not written > in a style which pleases learners like Michael. > [2] https://lambdacalc.io/ > [3] https://capra.cs.cornell.edu/lambdalab/ > [4] I tried to convince myself that the state monad indeed sequences > effects. In a pure lambda world I think this should mean that a certain > lambda term has only one way of being reduced. Is the following valid > reasoning? > type State s a = s -> (a,s) > When Church-encoding the tuple (a,s) one finds that > (m :: State s a) >>= (k :: a -> State s b) > = \s -> m s k > so the only applicable rule is beta-reducing m when applying to some s. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Sat Sep 18 23:29:49 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sun, 19 Sep 2021 01:29:49 +0200 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: Message-ID: <3014826B-F657-4912-AF97-E05A9283C4F9@gmail.com> Most important thing when learning Haskell is that everything is function no constants and variables like in imperative language. So a = 5 is function a lambas are just syntactic sugar you can do same with local functions. Don’t make fog and build simple things complicated. Also learn to teach that when you need variable in functional language you have to use handle to access it. Greetings, Branimir. > On 19.09.2021., at 01:20, Chris Smith wrote: > > I don't think it quite makes sense to say that Haskell shares the evaluation model with lambda calculus, because I don't think it's fair to say that lambda calculus has any specific evaluation model at all. Do you mean substitution, for example? But that's only one way to implement lambda calculus, and not one that is shared by any widely used Haskell implementation. > > But I do agree there's a point here. There's a simplicity that the purely functional fragment of Haskell shares with the lambda calculus, which I wish were easier to get across to new Haskell programmers. That simplicity is precisely what allows the lambda calculus, as well as the purely functional fragment of Haskell, to have a meaning without answering the question of how it is evaluated. (Even in more complex programming languages, the notion of evaluation that is used to define the language is often not the same one that's used by implementations, of course. But nevertheless these languages must be defined in terms of some model of evaluation, where the purely functional fragment of Haskell doesn't.) > > I struggle with this. In some very real ways, I consider it the most important point of learning Haskell for many programmers. But it's also not a prerequisite to using Haskell for practical purposes. For me, since I learned Haskell in order to just experience the cool ideas that it contains (and only 15 years later got my first job programming in Haskell), that's reason enough. But, within reason at least, it's the learner's goals that matter most when learning. Someone who isn't looking to understand the fundamental simplicity of a portion of Haskell isn't likely to be motivated to work through the effort it takes to understand it. So there must be some ways, at least, to learn Haskell without focusing on that particular aspect of the language. A Haskell programmer won't be as good of a Haskell programmer as they could be without understanding it, and will struggle to write idiomatic pure code. But one must start somewhere. New Python programmers don't write idiomatic or perfect Python, either! > > On Sat, Sep 18, 2021 at 7:11 PM Olaf Klinke > wrote: > Perhaps one thing that speaks in favour of Anthony Clayden's suggestion > to learn lambda calculus before/along Haskell is this: > Haskell shares the evaluation model with the lambda calculus. One of > Michael Turner's points of criticism was, as I understand it, > insufficient documentation about the inner workings of Haskell [1]. > Haskell needs constructs like the ST monad because of the evaluation > model. Once the learner knows, perhaps by experimenting with it on > paper or on [2,3], that a lambda term can be reduced in several ways, > and confluence guarantees that all ways result in the same normal form, > then some things might be much clearer: > * Which freedoms the compiler can exercise in evaluating your program. > * Why one needs the State monad for ordering sequences of effects (the > programmable semicolon) [4]. > * How the various tricks and pitfalls around lazy and strict functions > work, e.g. Viktor's new Foldable documentation. > > I looked at the first chapter of my K&R. It presents small example C > programs and explains what they do. Taking small Haskell programs and > explaining how these lambda terms are reduced to normal form would be a > comparable (and desirable, in Michael's view) approach? The Haskell > language report does not say anything in this respect, as far as I can > see. Only translation of syntactic constructs to core Haskell is given. > > Olaf > > [1] Of course the documentation is out there somewhere, but not written > in a style which pleases learners like Michael. > [2] https://lambdacalc.io/ > [3] https://capra.cs.cornell.edu/lambdalab/ > [4] I tried to convince myself that the state monad indeed sequences > effects. In a pure lambda world I think this should mean that a certain > lambda term has only one way of being reduced. Is the following valid > reasoning? > type State s a = s -> (a,s) > When Church-encoding the tuple (a,s) one finds that > (m :: State s a) >>= (k :: a -> State s b) > = \s -> m s k > so the only applicable rule is beta-reducing m when applying to some s. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony.d.clayden at gmail.com Sun Sep 19 00:24:53 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Sun, 19 Sep 2021 12:24:53 +1200 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. Message-ID: > With an implicit forall, the code does type check. So to recap. Explicit/implicit forall doesn't seem to matter here (both compile, both work): > pattern Justy :: a -> Maybe a > pattern Justy x = Just x > > pattern Justy2 :: forall a. a -> Maybe a > pattern Justy2 x = Just x (The docos for Pattern Synonyms don't give any examples with explicit `forall`; neither do they discuss whether it makes a difference. I'm inclined to say don't bother with outermost `forall`.) But it does matter here: > data Some where > Some :: a -> Some > > pattern Any :: a -> Some > pattern Any x = Some x > > pattern Any2 :: forall a. a -> Some > pattern Any2 x = Some x > > pattern Any3 :: (forall a. a) -> Some > pattern Any3 x = Some x `Any` is accepted; `Any2` and `Any3` are rejected with a type mismatch/rigid tyvar message per your o.p. (I'm not surprised `Any3` is rejected.) The message complains about the binding line, not the signature. If you don't give a signature for `Any`, we get (with `-fprint-explicit-foralls`) `Any :: forall {a}. a -> Some`, which is the same as for `Justy, Justy2 :: forall {a}. a -> Maybe a` mutatis mutandis. As to 'working', I presume your actual code doesn't merely have an existential for `Some`(?) but rather a constraint. Otherwise pattern-matching with `(Any x)` or with `(Some x)` you can't do anything with the `x` on RHS. Your o.p. asked > Is there a way around it, or is this a missing feature? What feature would you like that you think is "missing"? Do you think a pattern's explicit `forall` for an existential data constructor should do something different vs for a regular datatype? This could just be a stray loose end that nobody anticipated with Pattern Synonyms. -------------- next part -------------- An HTML attachment was scrubbed... URL: From michael.eugene.turner at gmail.com Sun Sep 19 01:00:23 2021 From: michael.eugene.turner at gmail.com (Michael Turner) Date: Sun, 19 Sep 2021 10:00:23 +0900 Subject: [Haskell-cafe] Writing about Haskell, and the Lambda Sidebar Message-ID: The debate over how much theory to give newbies seems endless, and there are good arguments on both sides. Maybe the synthesis is to just offer expository prose AND the mathematical approach, on the same page, side by side. Notational compression has its points. When I was in college and getting a little impatient with an expository text, whether it was something algorithmic or in the physical sciences, I'd often write the tightest thing I could, using not much more than set-theoretic notation. I even made a little game of it: could I almost completely eliminate English words? This gave my eye a much smaller space to range over. (Later, I heard this recommended by my favorite CS professor, Bernard Mont-Reynaud, a former student of Knuth's.) Although it's bad study practice to rewrite the text, this seemed an allowable exception. Whatever the philosophical problems of naive set theory, they didn't matter because computers are pretty naive anyway. And you could abstract away machine details; these were, in a way, still annoyingly present even back in the day when it was common to publish algorithm papers with Algol in them, which often still seemed too verbose to me. A few times, I thought I could mark up my textbook with, "I have discovered a truly concise way to express what this page says, and it CAN fit in the margin!" The debate over math-first-or-not is really an old problem: syllabus sequencing. But syllabus sequencing isn't quite learning sequencing. To be sure, you really do need to fully learn some concepts as the foundation for later ones. But psychologists have found that a feeling of "not quite getting it" isn't necessarily bad. It can even be good. Strangely, concepts can finally gel long after you've convinced yourself that they just overflowed from your overfilled brain. It's been suggested that a mild state of anxiety actually helps absorption of concepts at a subconscious level, after which they start to float back up and swim at your command when you need to apply them. So instead of arguing where the lambda calculus chapter should go (or anything else mathematical for that matter) how about putting the math in sidebars? When I was in college, I probably would have ended up in the Haskell text sidebar out of impatience. These days, with math study literally decades behind me, I might instead look over on that side with a little anxiety, and often press on impatiently in the main text after thinking, "I didn't get that." But that wouldn't mean I wasn't absorbing anything. I might even be learning faster, in a longer-term view. Because learning gels at different levels at different times, under different pressures, it might even be more efficient theory-acquisition for me than a solidly mathematical chapter, no matter where in the text it appeared. Regards, Michael Turner Executive Director Project Persephone 1-25-33 Takadanobaba Shinjuku-ku Tokyo 169-0075 Mobile: +81 (90) 5203-8682 turner at projectpersephone.org Understand - http://www.projectpersephone.org/ Join - http://www.facebook.com/groups/ProjectPersephone/ Donate - http://www.patreon.com/ProjectPersephone Volunteer - https://github.com/ProjectPersephone "Love does not consist in gazing at each other, but in looking outward together in the same direction." -- Antoine de Saint-Exupéry From ietf-dane at dukhovni.org Sun Sep 19 01:44:39 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Sat, 18 Sep 2021 21:44:39 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: On Thu, Sep 16, 2021 at 09:56:37PM -0400, Viktor Dukhovni wrote: > Surely a one click link from the Prelude re-export is no worse than a 1-click link > in the module table of contents? > > I am rather reluctant beat new readers over the head with laws that often are much > too abstract to add clarity. I've opened an MR: https://gitlab.haskell.org/ghc/ghc/-/merge_requests/6555 that adds a "Laws" link to the class head haddocks, and attempts to improve some prose that was found a bit wanting in the recent threads. https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Prelude.html#g:11 https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#overview The Overview of Data.Foldable is aimed at a novice to intermediate Haskell programmer, not a complete beginner or someone long familiar with the ins and outs of folds. The idea is to help the reader be able to reason about the various Foldable methods and choose the right one for the task at hand. Maybe, though not the main intent, to write better Foldable instances (if not simply derived). Perhaps the intended audience should be explicitly stated, to save complete beginners who are not ready for it, or seasoned Haskellers who don't need it the trouble of figuring out whether the content is for them??? -- Viktor. From david.feuer at gmail.com Sun Sep 19 01:57:09 2021 From: david.feuer at gmail.com (David Feuer) Date: Sat, 18 Sep 2021 21:57:09 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: I'll try to take a look. When writing instances (which I consider a beginner-level activity), it's really important to learn to follow the laws. While that may just sound like a bunch of theory, it turns out that in practice violating typeclass laws leads to seriously unintuitive behavior, breaking the expectations users have developed after using many instances. On Sat, Sep 18, 2021, 9:47 PM Viktor Dukhovni wrote: > On Thu, Sep 16, 2021 at 09:56:37PM -0400, Viktor Dukhovni wrote: > > > Surely a one click link from the Prelude re-export is no worse than a > 1-click link > > in the module table of contents? > > > > I am rather reluctant beat new readers over the head with laws that > often are much > > too abstract to add clarity. > > I've opened an MR: > https://gitlab.haskell.org/ghc/ghc/-/merge_requests/6555 > > that adds a "Laws" link to the class head haddocks, and attempts to > improve some prose that was found a bit wanting in the recent threads. > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Prelude.html#g:11 > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#overview > > The Overview of Data.Foldable is aimed at a novice to intermediate > Haskell programmer, not a complete beginner or someone long familiar > with the ins and outs of folds. The idea is to help the reader be able > to reason about the various Foldable methods and choose the right one > for the task at hand. Maybe, though not the main intent, to write better > Foldable instances (if not simply derived). > > Perhaps the intended audience should be explicitly stated, to save > complete beginners who are not ready for it, or seasoned Haskellers who > don't need it the trouble of figuring out whether the content is for > them??? > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From kai.prott at hotmail.de Sun Sep 19 02:12:12 2021 From: kai.prott at hotmail.de (Kai-Oliver Prott) Date: Sun, 19 Sep 2021 04:12:12 +0200 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. In-Reply-To: References: Message-ID: I only followed the discussion relatively loosely, so apologies if the following is not helpful. The declaration for `Any2 `can be modified slightly to get it accepted wit the explicit forall. Note that a pattern type signature has some quirks w.r.t quantification of existential and universal type variables. pattern Any2 :: forall . forall a. a -> Some If I remember correctly, the first forall in a pattern signature quantifies universal type variables and the second quantifies existentials. If only one is given, it is assumed to be for universals. If none are given, GHC tries to infer any quantification. This should be described in the "Pattern Synonyms" (Pickering et al) paper. I guess the printed type when asking GHC could be improved. But it might be that GHC is doing the "correct" thing since `:t Any` asks for the type of `Any` in an expression and not as a pattern signature. For constraints, there is a similar story w.r.t provided and required constraints. Cheers, Kai Prott On 19.09.21 02:24, Anthony Clayden wrote: > > With an implicit forall, the code does type check. > > So to recap. Explicit/implicit forall doesn't seem to matter here > (both compile, both work): > > >    pattern Justy ::  a -> Maybe a > >    pattern Justy x = Just x > > > >    pattern Justy2 :: forall a. a -> Maybe a > >    pattern Justy2 x = Just x > > (The docos for Pattern Synonyms don't give any examples with explicit > `forall`; neither do they discuss whether it makes a difference. I'm > inclined to say don't bother with outermost `forall`.) > > But it does matter here: > > >    data Some where > >      Some :: a -> Some > > > >    pattern Any :: a -> Some > >    pattern Any x = Some x > > > >    pattern Any2 :: forall a. a -> Some > >    pattern Any2 x = Some x > > > >    pattern Any3 :: (forall a. a) -> Some > >    pattern Any3 x = Some x > > > `Any` is accepted; `Any2` and `Any3` are rejected with a type > mismatch/rigid tyvar message per your o.p. (I'm not surprised `Any3` > is rejected.) The message complains about the binding line, not the > signature. If you don't give a signature for `Any`, we get (with > `-fprint-explicit-foralls`) `Any :: forall {a}. a -> Some`, which is > the same as for `Justy, Justy2 :: forall {a}. a -> Maybe a` mutatis > mutandis. > > As to 'working', I presume your actual code doesn't merely have an > existential for `Some`(?) but rather a constraint. Otherwise > pattern-matching with `(Any x)` or with `(Some x)` you can't do > anything with the `x` on RHS. > > Your o.p. asked > > > Is there a way around it, or is this a missing feature? > What feature would you like that you think is "missing"? Do you think > a pattern's explicit `forall` for an existential data constructor > should do something different vs for a regular datatype? > This could just be a stray loose end that nobody anticipated with > Pattern Synonyms. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony.d.clayden at gmail.com Sun Sep 19 03:00:08 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Sun, 19 Sep 2021 15:00:08 +1200 Subject: [Haskell-cafe] On finding the right exposition... Message-ID: > GHC's use of a State-like monad to represent I/O is semantically bogus, .... I wouldn't take it as a good mental model. Indeed. I fondly remember that in my intro text (the 'Gentle Introduction'), there was a warning this section is not so gentle. But I was already well through the book so it didn't seem such a drama. I'd already figured that 'mentally evaluating' code wasn't about contents of memory locations. For Monads esp I/O, 'programmable semicolon' or 'workflow' might be a better model. Ref the current discussion, I'm expecting a learner would spend a long time writing expressions at the ghci prompt; investigating their type; chucking in a few in-line decls with `let { }`. Dropping those decls into a source file -- which would contain only decls, not even a `module { }` header. A few simple `do{ ; }` blocks at the prompt. I was advocating lambda-calculus for the pure function evaluation parts of an intro. Higher-order functions, partial evaluation, operator sections, (un)currying. The o.p. was having trouble with a signature like `(a -> b -> c) -> a -> b -> d`. Later remarks expressed surprise why function application wasn't written `add(x, y)`. The (very old) paper mentioned was nearly all pure code. Without a firm basis grokking type signatures, the Monad operators are going to seem deeply weird. If you're used to 'higher-order function' meaning something that passes round an entry point for a block of code, partial application will take some head-scratching. And I can see if you're used to `x ++` meaning something and `x+=1` meaning something similar and `* y` meaning something completely different and `(x +)` being a syntax error, Haskell is going to feel strange. (Aside: to this day, that sort of ad-hoc syntax makes me gag. K&R should be publicly flogged on a regular basis. Why couldn't they just follow the model of BCPL, which is far more elegant and consistent in its syntax. They stole nearly everything else from BCPL.) Which reminds me ... My all-time favourite language intro text is still http://rabbit.eng.miami.edu/info/bcpl_reference_manual.pdf This serves also as a language definition.This was thrown at undergrads, and they were left to get on with it. (There was also a 'User Guide' that talked about the operating environment, debugging, IO and file handling -- essentially equiv to Haskell's Appendixes on the base modules.) I note again, the language is small and elegant (expressible in A5 minimanual format). Similarly, you can get enough of lambda-calculus on a few sheets of A4. I contrast that 'Category Theory for Programmers' (mentioned in this thread) is 500 pages, and not even a language primer, although it contains snippets of code. How many hundred pages must I read before I'm allowed to write a Foldable instance? I'm up to 100, and we seem to be still preparing the ground for what is an endomorph. -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony.d.clayden at gmail.com Sun Sep 19 03:34:29 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Sun, 19 Sep 2021 15:34:29 +1200 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. Message-ID: Thank you Kai-Oliver. > pattern Any2 :: forall . forall a. a -> Some We're friends here. I think I can share that my reaction was a rather loud WTF??!!?? And there's not a mention in the docos that this is even a thing. I feel like dragging whoever's responsible to the headmaster's office. Ok that seems to work -- in the sense that pattern-matching on it yields an `x` that's unusable on RHS just as much as the `Any` decl with implicit `forall`, or with no type signature at all. What would be useful is to be able to introduce a constraint into the sig, so I can do something like > foo (Any2 x) y = x == y After playing with it, all I'm getting is weird rejections. > pattern Any2 :: forall . forall a. () => (Eq a) => a -> Some > * Pattern synonym `Any2' has one argument > but its type signature has 1 fewer arrows I need to put the constraints inside the scope of the `forall a.`. A single `(Show a) => a -> Some` complains no instance provided. -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony.d.clayden at gmail.com Sun Sep 19 03:59:06 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Sun, 19 Sep 2021 15:59:06 +1200 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. Message-ID: > And there's not a mention in the docos that this is even a thing. To moderate myself ... There's one example pattern sig with explicit `forall`s, and it's wrt existentials/GADTs. https://ghc.gitlab.haskell.org/ghc/doc/users_guide/exts/pattern_synonyms.html?highlight=pattern%20synonym#typing-of-pattern-synonyms, bullet wrt lexically-scoped tyvars. It doesn't say you can have a dangling `forall` quantifying nothing -- indeed that you need such a thing in this case. It looks like if you want to constrain the existential, you have to declare that in the datatype, then repeat it in the sig for the pattern. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Sun Sep 19 04:12:09 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Sun, 19 Sep 2021 00:12:09 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: On Sat, Sep 18, 2021 at 09:57:09PM -0400, David Feuer wrote: > I'll try to take a look. When writing instances (which I consider a > beginner-level activity), it's really important to learn to follow the > laws. While that may just sound like a bunch of theory, it turns out that > in practice violating typeclass laws leads to seriously unintuitive > behavior, breaking the expectations users have developed after using many > instances. If that's the intent, the laws for Foldable need a substantially better explanation that the given equations, which shed very little light on the actual requirements. It would probably be most productive to add new prose explaining the laws to the "Defining instances" section: https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:19 and reference the laws also from there, if someone wants the concise form for QuickCheck property tests or the like. I am no longer a novice, and yet would still have a hard time making any use of the laws as written in constructing instances. Instead, I'd ignore the laws and write a natural intuitive instance, and it would invariably work. The text in "Definining Instances" aims to help readers ensure the implementations are reasonably efficient, but presently does not drag in the laws. As the author of the laws section, perhaps you'd be willing to contribute explanatory prose??? -- Viktor. From david.feuer at gmail.com Sun Sep 19 04:25:05 2021 From: david.feuer at gmail.com (David Feuer) Date: Sun, 19 Sep 2021 00:25:05 -0400 Subject: [Haskell-cafe] Haskell reference documentation, laws first or laws last? In-Reply-To: References: Message-ID: Foldable doesn't have much in the way of interesting laws, really. And I'm not sure how to make the relationships between foldMap, foldr, foldl, foldr', and foldl' clear to beginners. I'll have to think on that a bit. foldMap unifies finite, left-finite, right-finite, and doubly infinite structures, which is a tricky thing to explain to beginners! On Sun, Sep 19, 2021, 12:14 AM Viktor Dukhovni wrote: > On Sat, Sep 18, 2021 at 09:57:09PM -0400, David Feuer wrote: > > > I'll try to take a look. When writing instances (which I consider a > > beginner-level activity), it's really important to learn to follow the > > laws. While that may just sound like a bunch of theory, it turns out that > > in practice violating typeclass laws leads to seriously unintuitive > > behavior, breaking the expectations users have developed after using many > > instances. > > If that's the intent, the laws for Foldable need a substantially better > explanation that the given equations, which shed very little light on > the actual requirements. > > It would probably be most productive to add new prose explaining the > laws to the "Defining instances" section: > > > https://dnssec-stats.ant.isi.edu/~viktor/haskell/docs/libraries/base/Data-Foldable.html#g:19 > > and reference the laws also from there, if someone wants the concise > form for QuickCheck property tests or the like. > > I am no longer a novice, and yet would still have a hard time making any > use of the laws as written in constructing instances. Instead, I'd > ignore the laws and write a natural intuitive instance, and it would > invariably work. The text in "Definining Instances" aims to help > readers ensure the implementations are reasonably efficient, but > presently does not drag in the laws. > > As the author of the laws section, perhaps you'd be willing to > contribute explanatory prose??? > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From caeeh at yandex.com Sun Sep 19 05:39:57 2021 From: caeeh at yandex.com (Caeeh) Date: Sun, 19 Sep 2021 08:39:57 +0300 Subject: [Haskell-cafe] Shrink function names In-Reply-To: References: <236921631989669@mail.yandex.com> Message-ID: <253641632029840@mail.yandex.com> An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Sun Sep 19 06:59:15 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Sun, 19 Sep 2021 02:59:15 -0400 Subject: [Haskell-cafe] Shrink function names In-Reply-To: <253641632029840@mail.yandex.com> References: <236921631989669@mail.yandex.com> <253641632029840@mail.yandex.com> Message-ID: <67751D5A-5309-4E38-9552-D17F33BD9C8D@dukhovni.org> > On 19 Sep 2021, at 1:39 am, Caeeh wrote: > > @Viktor > Thx. This is working as mentioned. I somehow expected that the shrinking of functions would have the same effect on the data types. Do you have any idea how this can be achieved? Is it even possible? The best I was able to do, was also add '-dno-typeable-binds', which drops some unexported type names, but the secret constructor name remained. I don't know how to suppress unexported constructor names appearing in the compiled code, perhaps someone else does, or it might not be possible... -- Viktor. From coot at coot.me Sun Sep 19 07:49:38 2021 From: coot at coot.me (coot at coot.me) Date: Sun, 19 Sep 2021 07:49:38 +0000 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. In-Reply-To: References: Message-ID: Thank's Kai-Oliver,  it worked in the real setting as well, though the errors could be somewhat improved. For example both of these type signatures are accepted: ``` pattern Any :: forall . forall a. () => () => a -> Some pattern Any :: forall . () => forall a. () => a -> Some ``` But in my real scenario the first one is giving a puzzling error about the pattern match number of arguments not agreeing with the number of arrows in the type. I  needed to realized that the second type makes more sense, and it worked.  Btw the real thing I was trying to type with explicit quantification / existentials is this one: https://github.com/input-output-hk/ouroboros-network/blob/coot/typed-protocols-rewrite/typed-protocols/src/Network/TypedProtocol/Peer/Client.hs#L97 Thanks again both of you Kai & Anthony. Have a nice Sunday, Marcin Sent with ProtonMail Secure Email. ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ On Sunday, September 19th, 2021 at 04:12, Kai-Oliver Prott wrote: > I only followed the discussion relatively loosely, so apologies if the following is not helpful. > > The declaration for `Any2 `can be modified slightly to get it accepted wit the explicit forall. Note that a pattern type signature has some quirks w.r.t quantification of existential and universal type variables. > > pattern Any2 :: forall . forall a. a -> Some > > If I remember correctly, the first forall in a pattern signature quantifies universal type variables and the second quantifies existentials. If only one is given, it is assumed to be for universals. > > If none are given, GHC tries to infer any quantification. This should be described in the "Pattern Synonyms" (Pickering et al) paper. > > I guess the printed type when asking GHC could be improved. But it might be that GHC is doing the "correct" thing since `:t Any` asks for the type of `Any` in an expression and not as a pattern signature. > > For constraints, there is a similar story w.r.t provided and required constraints. > > Cheers, > > Kai Prott > > On 19.09.21 02:24, Anthony Clayden wrote: > > > > With an implicit forall, the code does type check. > > > > So to recap. Explicit/implicit forall doesn't seem to matter here (both compile, both work): > > > > >    pattern Justy ::  a -> Maybe a > > > > >    pattern Justy x = Just x > > >>    pattern Justy2 :: forall a. a -> Maybe a > > > > >    pattern Justy2 x = Just x > > > > (The docos for Pattern Synonyms don't give any examples with explicit `forall`; neither do they discuss whether it makes a difference. I'm inclined to say don't bother with outermost `forall`.) > > > > But it does matter here: > > > > >    data Some where > > > > >      Some :: a -> Some > > > > > > > > > >    pattern Any :: a -> Some > > > > >    pattern Any x = Some x > > > > > > > > > >    pattern Any2 :: forall a. a -> Some > > > > >    pattern Any2 x = Some x > > >>    pattern Any3 :: (forall a. a) -> Some > > > > >    pattern Any3 x = Some x > > > > `Any` is accepted; `Any2` and `Any3` are rejected with a type mismatch/rigid tyvar message per your o.p. (I'm not surprised `Any3` is rejected.) The message complains about the binding line, not the signature. If you don't give a signature for `Any`, we get (with `-fprint-explicit-foralls`) `Any :: forall {a}. a -> Some`, which is the same as for `Justy, Justy2 :: forall {a}. a -> Maybe a` mutatis mutandis. > > > > As to 'working', I presume your actual code doesn't merely have an existential for `Some`(?) but rather a constraint. Otherwise pattern-matching with `(Any x)` or with `(Some x)` you can't do anything with the `x` on RHS. > > > > Your o.p. asked > > > > > Is there a way around it, or is this a missing feature? > > > > What feature would you like that you think is "missing"? Do you think a pattern's explicit `forall` for an existential data constructor should do something different vs for a regular datatype? > > > > This could just be a stray loose end that nobody anticipated with Pattern Synonyms. > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 509 bytes Desc: OpenPGP digital signature URL: From jo at durchholz.org Sun Sep 19 09:04:55 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Sun, 19 Sep 2021 11:04:55 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <0AF02494-6710-47FD-A252-3AC5C0032390@gmail.com> References: <20210918080002.GN25255@cloudinit-builder> <22AF45B6-2FF5-42D3-B372-2FBD54532DDB@gmail.com> <34d27e9a-8736-62c6-23ea-8d7a38b4613a@durchholz.org> <0AF02494-6710-47FD-A252-3AC5C0032390@gmail.com> Message-ID: Am 18.09.21 um 14:11 schrieb Branimir Maksimovic: > I don“t see how does that anything to do with Monad ČP > It“s just what you pass as return value. Nitpick: "return" and "is" are one and the same in Haskell; there's no software-detectable difference between an expression and its result in safe Haskell. > Do { > … > ... > } > that’s just syntactic sugar, to look more nicely. The do syntax is syntactic sugar alright. However, it's not just the do block that's a monad, its top-level subexpressions must be monads as well. Regards, Jo From branimir.maksimovic at gmail.com Sun Sep 19 09:20:14 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sun, 19 Sep 2021 11:20:14 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: References: <20210918080002.GN25255@cloudinit-builder> <22AF45B6-2FF5-42D3-B372-2FBD54532DDB@gmail.com> <34d27e9a-8736-62c6-23ea-8d7a38b4613a@durchholz.org> <0AF02494-6710-47FD-A252-3AC5C0032390@gmail.com> Message-ID: <36F01B21-FAC0-45AD-84C5-216885AC62F9@gmail.com> I didn’t thought on return function, on return as word, what you return from function. > On 19.09.2021., at 11:04, Joachim Durchholz wrote: > > Am 18.09.21 um 14:11 schrieb Branimir Maksimovic: >> I don“t see how does that anything to do with Monad ČP >> It“s just what you pass as return value. > > Nitpick: "return" and "is" are one and the same in Haskell; there's no software-detectable difference between an expression and its result in safe Haskell. > >> Do { >> … >> ... >> } >> that’s just syntactic sugar, to look more nicely. > > The do syntax is syntactic sugar alright. > > However, it's not just the do block that's a monad, its top-level subexpressions must be monads as well. > > Regards, > Jo > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. Once Monad always Monad, am I right? Monad is also way to keep state, and monad passes state between functions? IO Monad is just convenient way to describe side effects. I mean IO, when you see That you always think side effect. Greetings, Branimir. From jo at durchholz.org Sun Sep 19 09:30:31 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Sun, 19 Sep 2021 11:30:31 +0200 Subject: [Haskell-cafe] On finding the right exposition... In-Reply-To: References: Message-ID: Am 19.09.21 um 01:20 schrieb Chris Smith: > I don't think it quite makes sense to say that Haskell shares the > evaluation model with lambda calculus, because I don't think it's fair > to say that lambda calculus has any specific evaluation model at all. > Do you mean substitution, for example?  But that's only one way to > implement lambda calculus, and not one that is shared by any widely used > Haskell implementation. Actually substitution *is* the evaluation model of lambda calculus. And the tagless spineless machine did in fact do substitutions - not on text but on a graph-transformed version of the text, and it had optimizations to avoid doing the same substitutions a second time, but yes it was substituting. Of course, today's GHC does not use the STG machine anymore (or not prominently anyway), as more efficient ways to execute Haskell have been implemented. I see that at roughly the same level as C compilers which reorder, rewrite, or eliminate code blocks, deviating pretty far from C's standard sequential execution model. I.e. other execution models are okay as long as they're semantically equivalent to the original - but for explanations to novices, you use "the" standard model, and *maybe* drop a hint or two how they can expect optimizations to happen (some of the typical optimizations are so important that they shape coding style, and knowing these early prevents them from "optimizing" stuff just to find out they just slowed down their code because it became so unidiomatic that GHC does not know how to optimize it properly). > But I do agree there's a point here.  There's a simplicity that the > purely functional fragment of Haskell shares with the lambda calculus, > which I wish were easier to get across to new Haskell programmers.  That > simplicity is precisely what allows the lambda calculus, as well as the > purely functional fragment of Haskell, to have a meaning > /without/ answering the question of how it is evaluated.  (Even in more > complex programming languages, the notion of evaluation that is used to > define the language is often not the same one that's used by > implementations, of course.  But nevertheless these languages must be > defined in terms of some model of evaluation, where the purely > functional fragment of Haskell doesn't.) The good news is: Of course Haskell has an evaluation model, just like the lambda calculus. > I struggle with this.  In some very real ways, I consider it the most > important point of learning Haskell for many programmers.  But it's also > not a prerequisite to using Haskell for practical purposes. That's true. I have seen some disturbingly "imperative" discussions about Haskell's behaviour here. Though it's hard to judge whether that's because the participants didn't grok the language concepts, or because they have internalized the language concepts so well that they can afford a lax terminology without getting misunderstood. (The discussions I saw were mostly about optimizing memory performance, and these aspects are so far ahead of my Haskell knowledge that I couldn't tell.) > New Python programmers don't write > idiomatic or perfect Python, either! Hmm... I think it's not that easy. Unidiomatic Python code still works and has reasonable performance. Unidiomatic Haskell code could have orders-of-magnitude performance hits, as seen in an ICFP contest where the difference between fastest and slowed program was a factor of 10,000. Not that I think that a learner should be expected to perfectly adapt to all idioms. But you need to teach them enough that they don't fall to performance traps. Which means you do have to talk about foldl and foldr, for example - and about the underlying evaluation model, in particular the "avoids evaluating unneeded subexpressions" part, and that foldl and foldr are telling the compiler which side of the overall expression is going to be more likely to be required. One thing I found was a visualisation of the STG (Spineless Tagless G Machine). If this thing has merit, then it might be exactly the tool people have been asking for to "see" (grok) what Haskell's evaluation is about. See https://github.com/quchen/stgi . Regards, Jo From kai.prott at hotmail.de Sun Sep 19 10:55:13 2021 From: kai.prott at hotmail.de (Kai-Oliver Prott) Date: Sun, 19 Sep 2021 12:55:13 +0200 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. In-Reply-To: References: Message-ID: Some comments in-line :) Best, Kai Prott > > > pattern Any2 :: forall . forall a. a -> Some > We're friends here. I think I can share that my reaction was a rather > loud WTF??!!?? Yep, that is quite weird. > And there's not a mention in the docos that this is even a thing. I > feel like dragging whoever's responsible to the headmaster's office. > Ok that seems to work -- in the sense that pattern-matching on it > yields an `x` that's unusable on RHS just as much as the `Any` decl > with implicit `forall`, or with no type signature at all. > What would be useful is to be able to introduce a constraint into the > sig, so I can do something like > > foo (Any2 x) y = x == y > After playing with it, all I'm getting is weird rejections. > > pattern Any2 :: forall . forall a. () => (Eq a) => a -> Some Your first error message seems like a case of bad error messages. Just out of curiosity, I've tried writing the following: pattern Refl :: forall a. forall . () => (Eq a) => Bool -> a pattern Refl a <- (refl -> a) refl :: Eq a => a -> Bool refl a = a == a This should not be accepted. Indeed I get the error message with "fewer arrows", although it seems like the given type signature has exactly the number of arrows it needs. The problem here is the misplaced constraint. GHC checks the arity of `Eq a => Bool -> a`, which it argues has zero arrows (->) at the top of the type. Note that the correct type signature would be pattern Refl :: forall a. (Eq a) => forall . () =>  Bool -> a > > * Pattern synonym `Any2' has one argument >    but its type > signature has 1 fewer arrows > I need to put the constraints inside the scope of the `forall a.`. A > single `(Show a) => a -> Some` complains no instance provided. The problem here is, that `Some` does not carry around any information that its argument has an `Eq` instance. It was not declared with such a constraint. Thus, pattern matching on `Some` cannot bring any `Eq` instance into scope. This is what the second error is trying to tell you. `Some` does not carry around enough information for `Any` to provide an `Eq` constraint when pattern matched. And as a quick note: Even if we do define `Some :: Eq a => a -> Some` your example still does not work, since x  and y are not guaranteed to be of the same type. But we could write: data Some where   Some :: Eq a => a -> Some pattern Any2 :: forall . forall a. (Eq a) => a -> Some pattern Any2 a = Some a foo :: Some -> Bool foo (Any2 x) = x == x > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Sun Sep 19 11:22:24 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sun, 19 Sep 2021 13:22:24 +0200 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. In-Reply-To: References: Message-ID: <31803245-5AA9-44FC-809B-73EACBD23DB3@gmail.com> What is purpose formal, except to make heterogenous lists? I find it not necessary in practice, exept to emulate OO passing through lists, when you need to implement OO like Behavior that is polymorphism. Those things come natural in Haskell wihout forall . Greetings, Branimir. > On 19.09.2021., at 12:55, Kai-Oliver Prott wrote: > > Some comments in-line :) > Best, > Kai Prott > >> >> > pattern Any2 :: forall . forall a. a -> Some >> We're friends here. I think I can share that my reaction was a rather loud WTF??!!?? > Yep, that is quite weird. >> And there's not a mention in the docos that this is even a thing. I feel like dragging whoever's responsible to the headmaster's office. >> Ok that seems to work -- in the sense that pattern-matching on it yields an `x` that's unusable on RHS just as much as the `Any` decl with implicit `forall`, or with no type signature at all. >> What would be useful is to be able to introduce a constraint into the sig, so I can do something like >> > foo (Any2 x) y = x == y >> After playing with it, all I'm getting is weird rejections. >> > pattern Any2 :: forall . forall a. () => (Eq a) => a -> Some > Your first error message seems like a case of bad error messages. > Just out of curiosity, I've tried writing the following: > > pattern Refl :: forall a. forall . () => (Eq a) => Bool -> a > pattern Refl a <- (refl -> a) > > refl :: Eq a => a -> Bool > refl a = a == a > > This should not be accepted. Indeed I get the error message with "fewer arrows", although it seems like the given type signature has exactly the number of arrows it needs. The problem here is the misplaced constraint. > GHC checks the arity of `Eq a => Bool -> a`, which it argues has zero arrows (->) at the top of the type. > Note that the correct type signature would be > > pattern Refl :: forall a. (Eq a) => forall . () => Bool -> a > >> >> > * Pattern synonym `Any2' has one argument >> > but its type signature has 1 fewer arrows >> I need to put the constraints inside the scope of the `forall a.`. A single `(Show a) => a -> Some` complains no instance provided. > The problem here is, that `Some` does not carry around any information that its argument has an `Eq` instance. It was not declared with such a constraint. Thus, pattern matching on `Some` cannot bring any `Eq` instance into scope. This is what the second error is trying to tell you. `Some` does not carry around enough information for `Any` to provide an `Eq` constraint when pattern matched. > > And as a quick note: Even if we do define `Some :: Eq a => a -> Some` your example still does not work, since x and y are not guaranteed to be of the same type. But we could write: > > data Some where > Some :: Eq a => a -> Some > > pattern Any2 :: forall . forall a. (Eq a) => a -> Some > pattern Any2 a = Some a > > foo :: Some -> Bool > foo (Any2 x) = x == x > >> >> >> >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Sun Sep 19 11:58:22 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 19 Sep 2021 07:58:22 -0400 Subject: [Haskell-cafe] Shrink function names In-Reply-To: <67751D5A-5309-4E38-9552-D17F33BD9C8D@dukhovni.org> References: <236921631989669@mail.yandex.com> <253641632029840@mail.yandex.com> <67751D5A-5309-4E38-9552-D17F33BD9C8D@dukhovni.org> Message-ID: I would ask if there's a "deriving Show" involved. On Sun, Sep 19, 2021 at 3:02 AM Viktor Dukhovni wrote: > > On 19 Sep 2021, at 1:39 am, Caeeh wrote: > > > > @Viktor > > Thx. This is working as mentioned. I somehow expected that the shrinking > of functions would have the same effect on the data types. Do you have any > idea how this can be achieved? Is it even possible? > > The best I was able to do, was also add '-dno-typeable-binds', which drops > some unexported type names, but the secret constructor name remained. > > I don't know how to suppress unexported constructor names appearing in the > compiled code, perhaps someone else does, or it might not be possible... > > -- > Viktor. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From dwincort at gmail.com Sun Sep 19 13:52:01 2021 From: dwincort at gmail.com (Daniel Winograd-Cort) Date: Sun, 19 Sep 2021 09:52:01 -0400 Subject: [Haskell-cafe] Cabal v3 public sub-libraries Message-ID: Hi cafe, I remember hearing about public sub-libraries in cabal v3, providing the ability to declare multiple libraries in the same cabal file that can be accessed (individually) by other packages. Does anyone know if this is supported on hackage, and if not, if there is a plan to allow this behavior on hackage? Thanks, Daniel -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Sun Sep 19 14:54:23 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Sun, 19 Sep 2021 10:54:23 -0400 Subject: [Haskell-cafe] Shrink function names In-Reply-To: References: <236921631989669@mail.yandex.com> <253641632029840@mail.yandex.com> <67751D5A-5309-4E38-9552-D17F33BD9C8D@dukhovni.org> Message-ID: On Sun, Sep 19, 2021 at 07:58:22AM -0400, Brandon Allbery wrote: > On Sun, Sep 19, 2021 at 3:02 AM Viktor Dukhovni > wrote: > > > I don't know how to suppress unexported constructor names appearing in the > > compiled code, perhaps someone else does, or it might not be possible... > > I would ask if there's a "deriving Show" involved. My test code does not. $ rm foo.o foo.hi $ ghc -fhide-source-paths -dno-typeable-binds -dsuppress-type-signatures -optl-s -O2 foo.hs [1 of 1] Compiling Main Linking foo ... $ strings -a foo | grep -i secret main:Main.AnotherSecret $ cat foo.hs module Main (main) where import System.Environment import Data.Maybe data SecretName = AnotherSecret String Int secretName :: [String] -> Maybe SecretName secretName = fmap (AnotherSecret <$> id <*> (+ 42) . read) . listToMaybe {-# NOINLINE secretName #-} main :: IO () main = secretName <$> getArgs >>= mapM_ (\ (AnotherSecret a b) -> print (a, b)) With a deriving (Show) instance, I see a second occurence: main:Main.AnotherSecret AnotherSecret -- Viktor. From allbery.b at gmail.com Sun Sep 19 15:23:45 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Sun, 19 Sep 2021 11:23:45 -0400 Subject: [Haskell-cafe] Shrink function names In-Reply-To: References: <236921631989669@mail.yandex.com> <253641632029840@mail.yandex.com> <67751D5A-5309-4E38-9552-D17F33BD9C8D@dukhovni.org> Message-ID: Hm. Then I bet that's the implicit Typeable derivation and there's nothing to be done about it because it's used internally. On Sun, Sep 19, 2021 at 10:58 AM Viktor Dukhovni wrote: > On Sun, Sep 19, 2021 at 07:58:22AM -0400, Brandon Allbery wrote: > > > On Sun, Sep 19, 2021 at 3:02 AM Viktor Dukhovni > > wrote: > > > > > I don't know how to suppress unexported constructor names appearing in > the > > > compiled code, perhaps someone else does, or it might not be > possible... > > > > I would ask if there's a "deriving Show" involved. > > My test code does not. > > $ rm foo.o foo.hi > $ ghc -fhide-source-paths -dno-typeable-binds > -dsuppress-type-signatures -optl-s -O2 foo.hs > [1 of 1] Compiling Main > Linking foo ... > $ strings -a foo | grep -i secret > main:Main.AnotherSecret > > $ cat foo.hs > module Main (main) where > > import System.Environment > import Data.Maybe > > data SecretName = AnotherSecret String Int > > secretName :: [String] -> Maybe SecretName > secretName = fmap (AnotherSecret <$> id <*> (+ 42) . read) . > listToMaybe > {-# NOINLINE secretName #-} > > main :: IO () > main = secretName <$> getArgs >>= mapM_ (\ (AnotherSecret a b) -> > print (a, b)) > > With a deriving (Show) instance, I see a second occurence: > > main:Main.AnotherSecret > AnotherSecret > > -- > Viktor. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Sep 19 15:31:14 2021 From: david.feuer at gmail.com (David Feuer) Date: Sun, 19 Sep 2021 11:31:14 -0400 Subject: [Haskell-cafe] Shrink function names In-Reply-To: References: <236921631989669@mail.yandex.com> <253641632029840@mail.yandex.com> <67751D5A-5309-4E38-9552-D17F33BD9C8D@dukhovni.org> Message-ID: You can still turn off Typeable deriving altogether, I believe. That'll only cause trouble if you're using Typeable. On Sun, Sep 19, 2021, 11:24 AM Brandon Allbery wrote: > Hm. Then I bet that's the implicit Typeable derivation and there's nothing > to be done about it because it's used internally. > > On Sun, Sep 19, 2021 at 10:58 AM Viktor Dukhovni > wrote: > >> On Sun, Sep 19, 2021 at 07:58:22AM -0400, Brandon Allbery wrote: >> >> > On Sun, Sep 19, 2021 at 3:02 AM Viktor Dukhovni > > >> > wrote: >> > >> > > I don't know how to suppress unexported constructor names appearing >> in the >> > > compiled code, perhaps someone else does, or it might not be >> possible... >> > >> > I would ask if there's a "deriving Show" involved. >> >> My test code does not. >> >> $ rm foo.o foo.hi >> $ ghc -fhide-source-paths -dno-typeable-binds >> -dsuppress-type-signatures -optl-s -O2 foo.hs >> [1 of 1] Compiling Main >> Linking foo ... >> $ strings -a foo | grep -i secret >> main:Main.AnotherSecret >> >> $ cat foo.hs >> module Main (main) where >> >> import System.Environment >> import Data.Maybe >> >> data SecretName = AnotherSecret String Int >> >> secretName :: [String] -> Maybe SecretName >> secretName = fmap (AnotherSecret <$> id <*> (+ 42) . read) . >> listToMaybe >> {-# NOINLINE secretName #-} >> >> main :: IO () >> main = secretName <$> getArgs >>= mapM_ (\ (AnotherSecret a b) -> >> print (a, b)) >> >> With a deriving (Show) instance, I see a second occurence: >> >> main:Main.AnotherSecret >> AnotherSecret >> >> -- >> Viktor. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > > -- > brandon s allbery kf8nh > allbery.b at gmail.com > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From spam at scientician.net Sun Sep 19 18:16:50 2021 From: spam at scientician.net (Bardur Arantsson) Date: Sun, 19 Sep 2021 20:16:50 +0200 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 17 In-Reply-To: References: Message-ID: Hi! Could you please stop replying to digests? It kills all semblance of reasonable threading. (If you don't have the individual messages in question, gmane.org is an excellent NNTP gateway which has all the messages and where you can reply using any NNTP client, e.g. Thunderbird.) Regards, From spam at scientician.net Sun Sep 19 18:22:27 2021 From: spam at scientician.net (Bardur Arantsson) Date: Sun, 19 Sep 2021 20:22:27 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: References: Message-ID: On 18/09/2021 04.56, Michael Turner wrote: [--snip--] Just to add: I'm not in education per se, but I've read a bit of research on it, and current research (as of 5-10 years ago) supports the idea that learning is helped most by multiple ways of explaining $THING_TO_BE_LEARNED. (NB: This is *not* Learning Styles, which is not a thing.) I'm guessing the proliferation of monad tutorials is that people think that the last explanation they read was "critical". Research suggests it more that that *happened* to be the one that finally made everything click into place. TL;DR: There is no magic One True Monad Tutorial. People need to learn about Monads (etc.) from multiple angles. Cheers, From kai.prott at hotmail.de Sun Sep 19 20:05:51 2021 From: kai.prott at hotmail.de (Kai Prott) Date: Sun, 19 Sep 2021 22:05:51 +0200 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. In-Reply-To: <31803245-5AA9-44FC-809B-73EACBD23DB3@gmail.com> References: <31803245-5AA9-44FC-809B-73EACBD23DB3@gmail.com> Message-ID: There are many reasons to write explicit foralls: - Documentation - Higher-ranked types - Existential types - ... The last two are not possible in GHC without a few foralls and are often quite useful. Also note that a type signature without explicit quantification like id :: a -> a implicitly means id :: forall a. a -> a Best, Kai On 19/09/2021 13:22, Branimir Maksimovic wrote: > What is purpose formal, except to make heterogenous lists? > I find it not necessary in practice, exept to emulate OO > passing through lists, when you need to implement OO like > Behavior that is polymorphism. Those things come natural > in Haskell wihout forall . > > Greetings, Branimir. > >> On 19.09.2021., at 12:55, Kai-Oliver Prott > > wrote: >> >> Some comments in-line :) >> Best, >> Kai Prott >> >>> >>> > pattern Any2 :: forall . forall a. a -> Some >>> We're friends here. I think I can share that my reaction was a >>> rather loud WTF??!!?? >> Yep, that is quite weird. >>> And there's not a mention in the docos that this is even a thing. I >>> feel like dragging whoever's responsible to the headmaster's office. >>> Ok that seems to work -- in the sense that pattern-matching on it >>> yields an `x` that's unusable on RHS just as much as the `Any` decl >>> with implicit `forall`, or with no type signature at all. >>> What would be useful is to be able to introduce a constraint into >>> the sig, so I can do something like >>> > foo (Any2 x) y = x == y >>> After playing with it, all I'm getting is weird rejections. >>> > pattern Any2 :: forall . forall a. () => (Eq a) => a -> Some >> >> Your first error message seems like a case of bad error messages. >> Just out of curiosity, I've tried writing the following: >> >> pattern Refl :: forall a. forall . () => (Eq a) => Bool -> a >> pattern Refl a <- (refl -> a) >> >> refl :: Eq a => a -> Bool >> refl a = a == a >> >> This should not be accepted. Indeed I get the error message with >> "fewer arrows", although it seems like the given type signature has >> exactly the number of arrows it needs. The problem here is the >> misplaced constraint. >> GHC checks the arity of `Eq a => Bool -> a`, which it argues has zero >> arrows (->) at the top of the type. >> Note that the correct type signature would be >> >> pattern Refl :: forall a. (Eq a) => forall . () => Bool -> a >> >>> > * Pattern synonym `Any2' has one argument >    but its type >>> signature has 1 fewer arrows >>> I need to put the constraints inside the scope of the `forall a.`. A >>> single `(Show a) => a -> Some` complains no instance provided. >> >> The problem here is, that `Some` does not carry around any >> information that its argument has an `Eq` instance. It was not >> declared with such a constraint. Thus, pattern matching on `Some` >> cannot bring any `Eq` instance into scope. This is what the second >> error is trying to tell you. `Some` does not carry around enough >> information for `Any` to provide an `Eq` constraint when pattern >> matched. >> >> And as a quick note: Even if we do define `Some :: Eq a => a -> Some` >> your example still does not work, since x  and y are not guaranteed >> to be of the same type. But we could write: >> >> data Some where >>   Some :: Eq a => a -> Some >> >> pattern Any2 :: forall . forall a. (Eq a) => a -> Some >> pattern Any2 a = Some a >> >> foo :: Some -> Bool >> foo (Any2 x) = x == x >> >>> >>> >>> >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> >> Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at richarde.dev Sun Sep 19 20:49:46 2021 From: lists at richarde.dev (Richard Eisenberg) Date: Sun, 19 Sep 2021 20:49:46 +0000 Subject: [Haskell-cafe] Pattern synonyms and explicit forall. In-Reply-To: References: <31803245-5AA9-44FC-809B-73EACBD23DB3@gmail.com> Message-ID: <010f017bffd27126-9acd062b-610e-429b-bef8-773bef7c96e5-000000@us-east-2.amazonses.com> It sounds like the confusion here has been somewhat resolved. Some of you may know that I'm producing weekly YouTube videos (I aim for 10 minutes apiece, but more often end up around 15 minutes) -- and it happens that this coming week's video is planned for pattern synonym type signatures, and it will cover exactly the material that should illuminate this conversation. I expect it to appear 7am US Eastern time Tuesday morning, but occasional technical glitches may mean it gets delayed until Wednesday. All the videos are posted to Tweag's channel at https://www.youtube.com/c/tweag Richard > On Sep 19, 2021, at 4:05 PM, Kai Prott wrote: > > There are many reasons to write explicit foralls: > > - Documentation > - Higher-ranked types > - Existential types > - ... > > The last two are not possible in GHC without a few foralls and are often quite useful. > > Also note that a type signature without explicit quantification like > > id :: a -> a > > implicitly means > > id :: forall a. a -> a > > Best, > Kai > > On 19/09/2021 13:22, Branimir Maksimovic wrote: >> What is purpose formal, except to make heterogenous lists? >> I find it not necessary in practice, exept to emulate OO >> passing through lists, when you need to implement OO like >> Behavior that is polymorphism. Those things come natural >> in Haskell wihout forall . >> >> Greetings, Branimir. >> >>> On 19.09.2021., at 12:55, Kai-Oliver Prott > wrote: >>> >>> Some comments in-line :) >>> Best, >>> Kai Prott >>> >>>> >>>> > pattern Any2 :: forall . forall a. a -> Some >>>> We're friends here. I think I can share that my reaction was a rather loud WTF??!!?? >>> Yep, that is quite weird. >>>> And there's not a mention in the docos that this is even a thing. I feel like dragging whoever's responsible to the headmaster's office. >>>> Ok that seems to work -- in the sense that pattern-matching on it yields an `x` that's unusable on RHS just as much as the `Any` decl with implicit `forall`, or with no type signature at all. >>>> What would be useful is to be able to introduce a constraint into the sig, so I can do something like >>>> > foo (Any2 x) y = x == y >>>> After playing with it, all I'm getting is weird rejections. >>>> > pattern Any2 :: forall . forall a. () => (Eq a) => a -> Some >>> Your first error message seems like a case of bad error messages. >>> Just out of curiosity, I've tried writing the following: >>> >>> pattern Refl :: forall a. forall . () => (Eq a) => Bool -> a >>> pattern Refl a <- (refl -> a) >>> >>> refl :: Eq a => a -> Bool >>> refl a = a == a >>> >>> This should not be accepted. Indeed I get the error message with "fewer arrows", although it seems like the given type signature has exactly the number of arrows it needs. The problem here is the misplaced constraint. >>> GHC checks the arity of `Eq a => Bool -> a`, which it argues has zero arrows (->) at the top of the type. >>> Note that the correct type signature would be >>> >>> pattern Refl :: forall a. (Eq a) => forall . () => Bool -> a >>> >>>> >>>> > * Pattern synonym `Any2' has one argument >>>> > but its type signature has 1 fewer arrows >>>> I need to put the constraints inside the scope of the `forall a.`. A single `(Show a) => a -> Some` complains no instance provided. >>> The problem here is, that `Some` does not carry around any information that its argument has an `Eq` instance. It was not declared with such a constraint. Thus, pattern matching on `Some` cannot bring any `Eq` instance into scope. This is what the second error is trying to tell you. `Some` does not carry around enough information for `Any` to provide an `Eq` constraint when pattern matched. >>> >>> And as a quick note: Even if we do define `Some :: Eq a => a -> Some` your example still does not work, since x and y are not guaranteed to be of the same type. But we could write: >>> >>> data Some where >>> Some :: Eq a => a -> Some >>> >>> pattern Any2 :: forall . forall a. (Eq a) => a -> Some >>> pattern Any2 a = Some a >>> >>> foo :: Some -> Bool >>> foo (Any2 x) = x == x >>> >>>> >>>> >>>> >>>> >>>> _______________________________________________ >>>> Haskell-Cafe mailing list >>>> To (un)subscribe, modify options or view archives go to: >>>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>>> Only members subscribed via the mailman list are allowed to post. >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at richarde.dev Sun Sep 19 21:04:53 2021 From: lists at richarde.dev (Richard Eisenberg) Date: Sun, 19 Sep 2021 21:04:53 +0000 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <20210918080002.GN25255@cloudinit-builder> References: <20210918080002.GN25255@cloudinit-builder> Message-ID: <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> Other understandings of informal terms will differ, but here is how I see it: * "Workflow" applies equally well to Monad as to Arrow. Both capture the idea of information flowing from one computation to the next. * "Programmable semicolon" seems a better fit for Monad than for Arrow. In C, I can say: > int result = do_some_thing(); > if (result > 10) > big_result(); > else > small_result(); That is, the future flow of my computation can depend on an earlier result. This is possible with Monad but not with Arrow. So, if I had thought that Arrow was a programmable semicolon, I would have felt short-changed a bit when actually learning what Arrow was. Popping up a level: for me, the value in these ideas is not their precision, but rather their familiarity. Give me intuition first, correctness later. Sidenote (please feel free to skip!): In later secondary school and throughout university, I kept learning things that refined earlier knowledge -- indeed suggesting that earlier knowledge was wrong. For example, radians are *much* more convenient to work with than degrees, which are kind of ridiculous. I resolved then that I would teach my kids how to measure angles in radians from the start: why bother with the inferior unit? Now I have a daughter, who is learning degrees. Why? Because degrees are simpler to start with: we can describe a circle or a right angle without any irrational numbers! So, we build intuition with degrees, and then she'll switch to radians when the time comes. Another example: we now know that object do not accelerate parabolically under the influence of gravity, because of general relativity. But general relativity is hard, so we still teach about parabolic curves for objects in freefall. Once a student knows more physics, they can return and refine their knowledge. So can it be with Haskell. We sometimes get so caught up in being "right" and precise, that we forget that it is sometimes useful to paper over some details for the sake of intuition. This means we sometimes have to say "wrong" things. (For example, I have said that "IO Int" is just an Int tagged with a flag that says the function can do I/O and must be written with do-notation.) But if the goal is learning, sometimes the "wrong" thing is the right thing. Richard > On Sep 18, 2021, at 4:00 AM, Tom Ellis wrote: > > On Sat, Sep 18, 2021 at 11:56:37AM +0900, Michael Turner wrote: >> Workflow is a metaphor at one useful level. "Programmable semicolon" >> is a metaphor at another useful level. > [...] >> "Workflow" helped me. And now "programmable semicolon" is helping a >> little, in another way. > > What troubles me about "workflow" and "programmable semicolon" is the > question of whether they also apply to Arrow[1]. > > * If they do, then in what sense can "workflow" and "programmable > semicolon" said to help with understanding of *Monad*? > > * If they don't, then why not? I don't see it. > > One possible answer is that they do, but those descriptions are only > intended to improve understanding about purpose not about technical > details (I think this is what Michael is suggesting). > > Tom > > > > [1] https://www.stackage.org/haddock/lts-17.7/base-4.14.1.0/Control-Arrow.html > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From david.feuer at gmail.com Sun Sep 19 22:31:16 2021 From: david.feuer at gmail.com (David Feuer) Date: Sun, 19 Sep 2021 18:31:16 -0400 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> References: <20210918080002.GN25255@cloudinit-builder> <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> Message-ID: Best of all is to avoid being too wrong in your teaching. No, don't teach children radians, but don't teach them degrees either (except on the side). Teach them *turns*, and later explain that a degree is 1/360th of a turn, and still later that a radian is 1/(2π) turns. On Sun, Sep 19, 2021, 5:07 PM Richard Eisenberg wrote: > Other understandings of informal terms will differ, but here is how I see > it: > > * "Workflow" applies equally well to Monad as to Arrow. Both capture the > idea of information flowing from one computation to the next. > > * "Programmable semicolon" seems a better fit for Monad than for Arrow. In > C, I can say: > > > int result = do_some_thing(); > > if (result > 10) > > big_result(); > > else > > small_result(); > > That is, the future flow of my computation can depend on an earlier > result. This is possible with Monad but not with Arrow. So, if I had > thought that Arrow was a programmable semicolon, I would have felt > short-changed a bit when actually learning what Arrow was. > > Popping up a level: for me, the value in these ideas is not their > precision, but rather their familiarity. Give me intuition first, > correctness later. > > Sidenote (please feel free to skip!): In later secondary school and > throughout university, I kept learning things that refined earlier > knowledge -- indeed suggesting that earlier knowledge was wrong. For > example, radians are *much* more convenient to work with than degrees, > which are kind of ridiculous. I resolved then that I would teach my kids > how to measure angles in radians from the start: why bother with the > inferior unit? Now I have a daughter, who is learning degrees. Why? Because > degrees are simpler to start with: we can describe a circle or a right > angle without any irrational numbers! So, we build intuition with degrees, > and then she'll switch to radians when the time comes. Another example: we > now know that object do not accelerate parabolically under the influence of > gravity, because of general relativity. But general relativity is hard, so > we still teach about parabolic curves for objects in freefall. Once a > student knows more physics, they can return and refine their knowledge. > > So can it be with Haskell. We sometimes get so caught up in being "right" > and precise, that we forget that it is sometimes useful to paper over some > details for the sake of intuition. This means we sometimes have to say > "wrong" things. (For example, I have said that "IO Int" is just an Int > tagged with a flag that says the function can do I/O and must be written > with do-notation.) But if the goal is learning, sometimes the "wrong" thing > is the right thing. > > Richard > > > On Sep 18, 2021, at 4:00 AM, Tom Ellis < > tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote: > > > > On Sat, Sep 18, 2021 at 11:56:37AM +0900, Michael Turner wrote: > >> Workflow is a metaphor at one useful level. "Programmable semicolon" > >> is a metaphor at another useful level. > > [...] > >> "Workflow" helped me. And now "programmable semicolon" is helping a > >> little, in another way. > > > > What troubles me about "workflow" and "programmable semicolon" is the > > question of whether they also apply to Arrow[1]. > > > > * If they do, then in what sense can "workflow" and "programmable > > semicolon" said to help with understanding of *Monad*? > > > > * If they don't, then why not? I don't see it. > > > > One possible answer is that they do, but those descriptions are only > > intended to improve understanding about purpose not about technical > > details (I think this is what Michael is suggesting). > > > > Tom > > > > > > > > [1] > https://www.stackage.org/haddock/lts-17.7/base-4.14.1.0/Control-Arrow.html > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From migmit at gmail.com Sun Sep 19 22:49:59 2021 From: migmit at gmail.com (Mig Mit) Date: Mon, 20 Sep 2021 00:49:59 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: References: Message-ID: Now I'm confused. How are degrees or radians "wrong"? Sent from my iPad > On 2021. Sep 20., at 0:34, David Feuer wrote: >  > Best of all is to avoid being too wrong in your teaching. No, don't teach children radians, but don't teach them degrees either (except on the side). Teach them *turns*, and later explain that a degree is 1/360th of a turn, and still later that a radian is 1/(2π) turns. > > On Sun, Sep 19, 2021, 5:07 PM Richard Eisenberg wrote: >> Other understandings of informal terms will differ, but here is how I see it: >> >> * "Workflow" applies equally well to Monad as to Arrow. Both capture the idea of information flowing from one computation to the next. >> >> * "Programmable semicolon" seems a better fit for Monad than for Arrow. In C, I can say: >> >> > int result = do_some_thing(); >> > if (result > 10) >> > big_result(); >> > else >> > small_result(); >> >> That is, the future flow of my computation can depend on an earlier result. This is possible with Monad but not with Arrow. So, if I had thought that Arrow was a programmable semicolon, I would have felt short-changed a bit when actually learning what Arrow was. >> >> Popping up a level: for me, the value in these ideas is not their precision, but rather their familiarity. Give me intuition first, correctness later. >> >> Sidenote (please feel free to skip!): In later secondary school and throughout university, I kept learning things that refined earlier knowledge -- indeed suggesting that earlier knowledge was wrong. For example, radians are *much* more convenient to work with than degrees, which are kind of ridiculous. I resolved then that I would teach my kids how to measure angles in radians from the start: why bother with the inferior unit? Now I have a daughter, who is learning degrees. Why? Because degrees are simpler to start with: we can describe a circle or a right angle without any irrational numbers! So, we build intuition with degrees, and then she'll switch to radians when the time comes. Another example: we now know that object do not accelerate parabolically under the influence of gravity, because of general relativity. But general relativity is hard, so we still teach about parabolic curves for objects in freefall. Once a student knows more physics, they can return and refine their knowledge. >> >> So can it be with Haskell. We sometimes get so caught up in being "right" and precise, that we forget that it is sometimes useful to paper over some details for the sake of intuition. This means we sometimes have to say "wrong" things. (For example, I have said that "IO Int" is just an Int tagged with a flag that says the function can do I/O and must be written with do-notation.) But if the goal is learning, sometimes the "wrong" thing is the right thing. >> >> Richard >> >> > On Sep 18, 2021, at 4:00 AM, Tom Ellis wrote: >> > >> > On Sat, Sep 18, 2021 at 11:56:37AM +0900, Michael Turner wrote: >> >> Workflow is a metaphor at one useful level. "Programmable semicolon" >> >> is a metaphor at another useful level. >> > [...] >> >> "Workflow" helped me. And now "programmable semicolon" is helping a >> >> little, in another way. >> > >> > What troubles me about "workflow" and "programmable semicolon" is the >> > question of whether they also apply to Arrow[1]. >> > >> > * If they do, then in what sense can "workflow" and "programmable >> > semicolon" said to help with understanding of *Monad*? >> > >> > * If they don't, then why not? I don't see it. >> > >> > One possible answer is that they do, but those descriptions are only >> > intended to improve understanding about purpose not about technical >> > details (I think this is what Michael is suggesting). >> > >> > Tom >> > >> > >> > >> > [1] https://www.stackage.org/haddock/lts-17.7/base-4.14.1.0/Control-Arrow.html >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > To (un)subscribe, modify options or view archives go to: >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> > Only members subscribed via the mailman list are allowed to post. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at richarde.dev Sun Sep 19 23:10:14 2021 From: lists at richarde.dev (Richard Eisenberg) Date: Sun, 19 Sep 2021 23:10:14 +0000 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: References: Message-ID: <010f017c0053094e-b8e99983-e05f-4aaa-9556-fa662eb1babe-000000@us-east-2.amazonses.com> Degrees aren't wrong (though I agree I implied this in my description), but they're not as useful in engineering as radians, nor as useful as turns (as David rightly suggests) in everyday applications. Richard > On Sep 19, 2021, at 6:49 PM, Mig Mit wrote: > > How are degrees or radians "wrong"? -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Sun Sep 19 23:14:33 2021 From: david.feuer at gmail.com (David Feuer) Date: Sun, 19 Sep 2021 19:14:33 -0400 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: References: Message-ID: Neither is really wrong. Degrees are strange, an artifact of the Babylonian system with no real mathematical significance. Radians are perfectly fine, and mathematically preferable, but measurements in radians typically have to be given as multiples of some transcendental number. Traditionally, that number is π. Didactically, it's probably better to use 𝜏 = 2π, which in context can be pronounced "turns". You don't have to tell a child about the "radians" part till they're ready, and don't have to confuse them with 360 anythings. Just teach important angles like 𝜏, ½𝜏, ¼𝜏, ⅛𝜏, ⅙𝜏, and (1/12)𝜏. Bringing this back to the Haskell context, it's nice to find a way to avoid lying without needing to tell all of the truth to someone who's not ready. On Sun, Sep 19, 2021, 6:50 PM Mig Mit wrote: > Now I'm confused. How are degrees or radians "wrong"? > > Sent from my iPad > > On 2021. Sep 20., at 0:34, David Feuer wrote: > >  > Best of all is to avoid being too wrong in your teaching. No, don't teach > children radians, but don't teach them degrees either (except on the side). > Teach them *turns*, and later explain that a degree is 1/360th of a turn, > and still later that a radian is 1/(2π) turns. > > On Sun, Sep 19, 2021, 5:07 PM Richard Eisenberg > wrote: > >> Other understandings of informal terms will differ, but here is how I see >> it: >> >> * "Workflow" applies equally well to Monad as to Arrow. Both capture the >> idea of information flowing from one computation to the next. >> >> * "Programmable semicolon" seems a better fit for Monad than for Arrow. >> In C, I can say: >> >> > int result = do_some_thing(); >> > if (result > 10) >> > big_result(); >> > else >> > small_result(); >> >> That is, the future flow of my computation can depend on an earlier >> result. This is possible with Monad but not with Arrow. So, if I had >> thought that Arrow was a programmable semicolon, I would have felt >> short-changed a bit when actually learning what Arrow was. >> >> Popping up a level: for me, the value in these ideas is not their >> precision, but rather their familiarity. Give me intuition first, >> correctness later. >> >> Sidenote (please feel free to skip!): In later secondary school and >> throughout university, I kept learning things that refined earlier >> knowledge -- indeed suggesting that earlier knowledge was wrong. For >> example, radians are *much* more convenient to work with than degrees, >> which are kind of ridiculous. I resolved then that I would teach my kids >> how to measure angles in radians from the start: why bother with the >> inferior unit? Now I have a daughter, who is learning degrees. Why? Because >> degrees are simpler to start with: we can describe a circle or a right >> angle without any irrational numbers! So, we build intuition with degrees, >> and then she'll switch to radians when the time comes. Another example: we >> now know that object do not accelerate parabolically under the influence of >> gravity, because of general relativity. But general relativity is hard, so >> we still teach about parabolic curves for objects in freefall. Once a >> student knows more physics, they can return and refine their knowledge. >> >> So can it be with Haskell. We sometimes get so caught up in being "right" >> and precise, that we forget that it is sometimes useful to paper over some >> details for the sake of intuition. This means we sometimes have to say >> "wrong" things. (For example, I have said that "IO Int" is just an Int >> tagged with a flag that says the function can do I/O and must be written >> with do-notation.) But if the goal is learning, sometimes the "wrong" thing >> is the right thing. >> >> Richard >> >> > On Sep 18, 2021, at 4:00 AM, Tom Ellis < >> tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote: >> > >> > On Sat, Sep 18, 2021 at 11:56:37AM +0900, Michael Turner wrote: >> >> Workflow is a metaphor at one useful level. "Programmable semicolon" >> >> is a metaphor at another useful level. >> > [...] >> >> "Workflow" helped me. And now "programmable semicolon" is helping a >> >> little, in another way. >> > >> > What troubles me about "workflow" and "programmable semicolon" is the >> > question of whether they also apply to Arrow[1]. >> > >> > * If they do, then in what sense can "workflow" and "programmable >> > semicolon" said to help with understanding of *Monad*? >> > >> > * If they don't, then why not? I don't see it. >> > >> > One possible answer is that they do, but those descriptions are only >> > intended to improve understanding about purpose not about technical >> > details (I think this is what Michael is suggesting). >> > >> > Tom >> > >> > >> > >> > [1] >> https://www.stackage.org/haddock/lts-17.7/base-4.14.1.0/Control-Arrow.html >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > To (un)subscribe, modify options or view archives go to: >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> > Only members subscribed via the mailman list are allowed to post. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From lists at richarde.dev Mon Sep 20 00:24:33 2021 From: lists at richarde.dev (Richard Eisenberg) Date: Mon, 20 Sep 2021 00:24:33 +0000 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: <20210917171106.GI25255@cloudinit-builder> References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> <20210917171106.GI25255@cloudinit-builder> Message-ID: <010f017c00971225-23b9a3d6-2f0b-4780-b069-ca79d379da15-000000@us-east-2.amazonses.com> > On Sep 17, 2021, at 1:11 PM, Tom Ellis wrote: > > On Fri, Sep 17, 2021 at 05:02:09PM +0000, Richard Eisenberg wrote: >> >> For me, coming from a mostly Java background (but with a healthy >> dollop of functional programming thrown in the mix -- but no >> Haskell), the phrase that unlocked monads was "programmable >> semicolon". > > I'm curious what "unlock" means here. It's hard to be sure, as this was ~10 years ago, but I think it was about motivation for me. Specifically: why do we need more than one monad, IO. I understood that Haskell functions were pure, and thus could produce no side effects. So we needed to have *some* way of having a program interact with the world. This way was the set of functions that work in the IO monad. These operations need a way of interacting with pure code (i.e. `return`) and some way of sequencing (i.e. >>=). This was all clear enough. What I didn't understand is why there was a typeclass to capture this or why we needed other monads -- until I associated "monad" with "programmable semicolon". At that point, I realized that the idea is very powerful. Richard > Do you mean you could > understand the definition of the monad class after coming across > "programmable semicolon" but not before? Or do you mean you > understood the *purpose* of monads, but not necessarily how one would > go about implementing them? Or something else? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Mon Sep 20 04:17:26 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Mon, 20 Sep 2021 00:17:26 -0400 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: <010f017c00971225-23b9a3d6-2f0b-4780-b069-ca79d379da15-000000@us-east-2.amazonses.com> References: <20210917075050.GE21030@cloudinit-builder> <010f017bf4b55289-6c3dc165-2bce-446d-90f3-650af01a7e81-000000@us-east-2.amazonses.com> <20210917171106.GI25255@cloudinit-builder> <010f017c00971225-23b9a3d6-2f0b-4780-b069-ca79d379da15-000000@us-east-2.amazonses.com> Message-ID: <834046D5-AC95-4F28-A374-3B10B189765D@dukhovni.org> > On 19 Sep 2021, at 8:24 pm, Richard Eisenberg wrote: > > This was all clear enough. What I didn't understand is why there was a typeclass to capture this or why we needed other monads -- until I associated "monad" with "programmable semicolon". At that point, I realized that the idea is very powerful. Thus, e.g., the Hasql library (and of course also STM before that) leverage the ability to define a specialised Monad in which only specific "impure" actions are available to be able to "retry" a (Postgres Database in the case of Hasql) transaction, without worrying about side-effects persisting from the initial attempt. The Conduit and Streaming ecosystems are also testaments to the effectiveness of the abstraction. And then there's always State, which e.g. makes it possible to define mapAccumL and mapAccumR for all Traversable structures, or more generally thread an evolving through a sequence pure computations. Thus while there's reportedly been a shift lately from multi-layered Monad Transformer stacks to RIO or algebraic effect systems, Monads remain powerful and useful tools. I no longer remember exactly when they "clicked" for me, perhaps there wasn't any "Aha" moment. Just growing familiarity through multiple exposures to the many use-cases. Still haven't used "Cont" at all, so don't have any intuition for whether/when/how I might put it to good use... If someone wrote a good overview for that module, I'd be happy to learn more. -- Viktor. From jo at durchholz.org Mon Sep 20 06:03:18 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Mon, 20 Sep 2021 08:03:18 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> References: <20210918080002.GN25255@cloudinit-builder> <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> Message-ID: <1b3cfb80-3f4d-5eb4-c084-c7819f75a6e4@durchholz.org> Am 19.09.21 um 23:04 schrieb Richard Eisenberg: > Popping up a level: for me, the value in these ideas is not their precision, but rather their familiarity. Give me intuition first, correctness later. > > [...] Another example: we now know that object do not accelerate parabolically under the influence of gravity, because of general relativity. But general relativity is hard, so we still teach about parabolic curves for objects in freefall. Once a student knows more physics, they can return and refine their knowledge. > > So can it be with Haskell. We sometimes get so caught up in being "right" and precise, that we forget that it is sometimes useful to paper over some details for the sake of intuition. I agree that you need to have a first working model initially, with all the details coming later. In the case of monads, I think that the usual initial model (a monad is a pipeline) is insufficient even at the novice level. I'll argue for that from observation, and from reasoning. Observation: Many novices come up with questions about monads. It's the number one stumbling block, and the thing that keeps people turning away as in "that's all too mathematical". Compare this with Java: public static void main(String... args) which floods the user with four advanced concepts (public, static, void results, varargs parameters), yet gives rise more to ridicule than frustration. More importantly, each of these concepts immediately points to something that you can explore and understand separately. Reasoning: Most expositions of monads start with some kind of pipeline concept. The problem with that is that it's misleading without giving people a clue where they're going wrong. E.g. think "pipeline" and hit Maybe and Error. These concepts don't "look like" a pipeline, more like a variation of function composition - but why is it then a monad instead of function composition? List is even more difficult to fit into the pipeline methaphor. Using List's monad properties is mostly interesting for tracing all cases of nondeterministic behaviour, but you very rarely do that in code, so it's not a big deal - but it still is a cognitive dissonance for the student, a sore spot in the mental model. Even before these two, you see IO. You can easily get away with the pipeline model at first when you just do output, but as soon as you have input and decisionmaking (i.e. the output becomes a decision tree, each run of the program following one path from the root to a leaf - actually it's a DAG and nonterminating programs don't necessarily have leaves), the pipeline model is not a good fit anymore. (I very much like David Feuer's idea how to teach angles in terms of "turns". It carefully avoids putting the student at a wrong track. Since radians are taught waaay after division by fractions, even the division by an irrational number that you need to "explain" radians isn't such a big deal - i.e. it also orders concepts in an order where each concept can be explained based on things the student already knows.) Just my 2 cents, and based on more thinking than programming, so it may not be worth much. Regards, Jo From anthony.d.clayden at gmail.com Mon Sep 20 06:15:03 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Mon, 20 Sep 2021 18:15:03 +1200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning Message-ID: > Neither [degrees nor radians] is really wrong. Degrees are strange, ... That sounds like the pot calling the kettle black. 'Irrational' means ... errm ... strange. 'Transcendental' was the word Leibniz reached for when he realised he had something stranger than irrationals. > an artifact of the Babylonian system with no real mathematical significance. Hmm? An artefact of being approximately the number of days in a year (which is as true for us as the Babylonians), and a number which has many factors, so can happily measure quarter-turns, eighth turns (bracing to keep your right-angles upright), whole-number of degrees for internal angles of all the faces needed for the Platonic solids ... I would have thought there's a teachable moment there about prime numbers, factorisation, and for bringing fractions into a coherent continuum. It's not like ignorance of this alleged "mathematical significance" of radians prevented building Hanging Gardens or Pyramids, Stonehenge, the fractals of the Walls of Benin, Machu Picchu trapeziums or aqueducts or anything. (A bit like Category Theory, really.) -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Sep 20 06:17:12 2021 From: david.feuer at gmail.com (David Feuer) Date: Mon, 20 Sep 2021 02:17:12 -0400 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <1b3cfb80-3f4d-5eb4-c084-c7819f75a6e4@durchholz.org> References: <20210918080002.GN25255@cloudinit-builder> <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> <1b3cfb80-3f4d-5eb4-c084-c7819f75a6e4@durchholz.org> Message-ID: FYI, it's not my idea; I just figured I could slot it in. I have no idea what pipelines night mean in this context. Something to do with Unix utility composition? On Mon, Sep 20, 2021, 2:05 AM Joachim Durchholz wrote: > Am 19.09.21 um 23:04 schrieb Richard Eisenberg: > > Popping up a level: for me, the value in these ideas is not their > precision, but rather their familiarity. Give me intuition first, > correctness later. > > > > [...] Another example: we now know that object do not accelerate > parabolically under the influence of gravity, because of general > relativity. But general relativity is hard, so we still teach about > parabolic curves for objects in freefall. Once a student knows more > physics, they can return and refine their knowledge. > > > > So can it be with Haskell. We sometimes get so caught up in being > "right" and precise, that we forget that it is sometimes useful to paper > over some details for the sake of intuition. > > I agree that you need to have a first working model initially, with all > the details coming later. > > In the case of monads, I think that the usual initial model (a monad is > a pipeline) is insufficient even at the novice level. > I'll argue for that from observation, and from reasoning. > > Observation: Many novices come up with questions about monads. It's the > number one stumbling block, and the thing that keeps people turning away > as in "that's all too mathematical". > Compare this with Java: > public static void main(String... args) > which floods the user with four advanced concepts (public, static, void > results, varargs parameters), yet gives rise more to ridicule than > frustration. > More importantly, each of these concepts immediately points to something > that you can explore and understand separately. > > Reasoning: > Most expositions of monads start with some kind of pipeline concept. > The problem with that is that it's misleading without giving people a > clue where they're going wrong. > E.g. think "pipeline" and hit Maybe and Error. These concepts don't > "look like" a pipeline, more like a variation of function composition - > but why is it then a monad instead of function composition? > List is even more difficult to fit into the pipeline methaphor. Using > List's monad properties is mostly interesting for tracing all cases of > nondeterministic behaviour, but you very rarely do that in code, so it's > not a big deal - but it still is a cognitive dissonance for the student, > a sore spot in the mental model. > > Even before these two, you see IO. You can easily get away with the > pipeline model at first when you just do output, but as soon as you have > input and decisionmaking (i.e. the output becomes a decision tree, each > run of the program following one path from the root to a leaf - actually > it's a DAG and nonterminating programs don't necessarily have leaves), > the pipeline model is not a good fit anymore. > (I very much like David Feuer's idea how to teach angles in terms of > "turns". It carefully avoids putting the student at a wrong track. Since > radians are taught waaay after division by fractions, even the division > by an irrational number that you need to "explain" radians isn't such a > big deal - i.e. it also orders concepts in an order where each concept > can be explained based on things the student already knows.) > > > Just my 2 cents, and based on more thinking than programming, so it may > not be worth much. > > Regards, > Jo > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From jo at durchholz.org Mon Sep 20 06:30:54 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Mon, 20 Sep 2021 08:30:54 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: References: <20210918080002.GN25255@cloudinit-builder> <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> <1b3cfb80-3f4d-5eb4-c084-c7819f75a6e4@durchholz.org> Message-ID: <4b1b0254-575d-dc50-6ec4-4794b2714581@durchholz.org> Am 20.09.21 um 08:17 schrieb David Feuer: > FYI, it's not my idea; I just figured I could slot it in. I have no idea > what pipelines night mean in this context. Something to do with Unix > utility composition? The idea is that a monad is a tool to construct a pipeline inside a Haskell program. I think. It isn't my metaphor either, I have seen various people in this thread mention it in passing. Regards, Jo From raoknz at gmail.com Mon Sep 20 07:06:03 2021 From: raoknz at gmail.com (Richard O'Keefe) Date: Mon, 20 Sep 2021 19:06:03 +1200 Subject: [Haskell-cafe] Haskell-Cafe Digest, Vol 217, Issue 16 In-Reply-To: References: Message-ID: Thank you for the link to the paper. It's heading out to the printer now. On a quick skim, it seems closely related to "Categorial Grammar". "Categorial grammar is a family of formalisms in natural language syntax which share the central assumption that syntactic constituents combine as functions and arguments." -- Wikipedia On Fri, 17 Sept 2021 at 16:52, Michael Turner wrote: > > "The seeds of your confusion are very evident from your message". > > The seeds of your unsubstantiated assumptions about me are very > evident from yours. > > "You can't just 'translate' an algorithm from OOP to Haskell" > > Wow, I'm either "trying to translate Haskell to C++" (someone else, > above) or trying to translate C++ to Haskell. > > I'm actually doing neither. I started by trying to understand this: > > https://www.stwing.upenn.edu/~wlovas/hudak/aug.pdf > > (And no, just because Haskell is great for writing little > special-purpose programming languages does not automatically mean it's > up to snuff for handling natural language.) > > I'd originally hoped to fully understand the rather short program in > that paper (full code, in two versions, elsewhere on Paul Jones aca > dite) by getting it to run again, then commenting the code as I began > to understand it. And then, on to more important issues for a fuller > Haskell implementation, issues described here > > https://www.aclweb.org/anthology/C94-2137.pdf > > and here > > http://www.lacus.org/volumes/23/22.sypniewski.pdf > > Both of which are references I dug up and supplied here > > https://en.wikipedia.org/wiki/Applicative_universal_grammar > > as I took the Wikipedia article from stub status to something less > stubby -- it actually started in this state: > > https://en.wikipedia.org/w/index.php?title=Applicative_universal_grammar&diff=prev&oldid=1020447173 > > The ASCII-art diagrams you see there are output from code that I've > gotten working again. > > I learned about lazy evaluation in college, when I got interested in > how Lisp might implement it. I'm very familiar with the arguments for > purity, especially from learning Erlang some years ago (during which I > wrote my share of accumulator-based tail-recursive functions.) I > prefer static typing but hated the way C++ templates extended the > concept, mostly because the syntax error messages were so bad for so > long. My career includes a time in the late 80s when the kind of > computing power we have in our phones now with multicore processors > filled a box of hardware too heavy to lift. This was at a startup > where the founder was substantially inspired by this stream-oriented > single-assignment language: > > https://en.wikipedia.org/wiki/SISAL > > I started programming at 15. It's been a very rare year, even after > leaving the software profession, when I didn't write at least some > code, learning new things in the process. Which means I've been > looking at programming languages and how to implement things at the > most appropriate level of abstraction possible for just a few months > shy of fifty years. > > The arguments here are following a familiar pattern, one I see in > discussions of everything from programming to government policy. > > (1) I disagree with someone > (2) This person instantly assumes I must be ignorant of what they know > (3) They start Mansplaining It All To Me. > > This is particularly irksome when the person is actually considerably > more ignorant of the subject than I am. > > I'm still ignorant of most of Haskell, to be sure. However, I'm not > ignorant when it comes to writing. (Published articles on request.) A > great deal of what's written about Haskell, usually with very good > intentions, has proved useless to me. Have I had a stroke that leaves > me apparently unharmed, but actually no longer able to absorb a > different programming language? Was I always just too dumb to learn > Haskell? Somehow, I think it's more related to the writing. > > To some extent the community seems to recognize there's a problem -- > e.g., the Monad Tutorial Explosion. I finally got (most of?) what > monads really mean for practical programming when none other than > Simon Peyton-Jones said F# called a very similar construct "workflow," > a word he likes. Wow, plain English instead of a mathematical > abstraction that, in the math introductions, looks weirdly clunky to > me, if anything, but, in any case, very hard to relate to writing > better code. > > Lambda calculus? I have vague memories of Eugene Lawler > > https://en.wikipedia.org/wiki/Eugene_Lawler > > covering it when I took computing theory from him. And again, when I > was grading computing theory homework for this required course for > graduate students (for their prelim exams) for Richard Lipton > > https://en.wikipedia.org/wiki/Richard_Lipton > > in the fall term of 1980 at U.C. Berkeley. > > It's not that I'm too stupid to learn lambda calculus. It's that I > seriously doubt that refreshing my memory on the details is going to > add significantly more to my grasp of functional programming in > Haskell. > > I disagree with some people here. They jump to the conclusion that I'm > some ignorant moron. They also keep trying to sell Haskell as > something dramatically, fundamentally -- nay transcendentally! -- > different from anything I've ever known. > > Are you doing that? Stop. Just stop. Haskell's big problem right now > is adoption. And I'm telling you why adoption has been hard for me. > You lecture back, telling me things I already know, making sweeping > assumptions about me. When you do that, you're not part of the > solution to Haskell's biggest problem right now. You're part of the > problem. > > Regards, > Michael Turner > Executive Director > Project Persephone > 1-25-33 Takadanobaba > Shinjuku-ku Tokyo 169-0075 > Mobile: +81 (90) 5203-8682 > turner at projectpersephone.org > > Understand - http://www.projectpersephone.org/ > Join - http://www.facebook.com/groups/ProjectPersephone/ > Donate - http://www.patreon.com/ProjectPersephone > Volunteer - https://github.com/ProjectPersephone > > "Love does not consist in gazing at each other, but in looking outward > together in the same direction." -- Antoine de Saint-Exupéry > > On Fri, Sep 17, 2021 at 4:19 AM wrote: > > > > Send Haskell-Cafe mailing list submissions to > > haskell-cafe at haskell.org > > > > To subscribe or unsubscribe via the World Wide Web, visit > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > or, via email, send a message with subject or body 'help' to > > haskell-cafe-request at haskell.org > > > > You can reach the person managing the list at > > haskell-cafe-owner at haskell.org > > > > When replying, please edit your Subject line so it is more specific > > than "Re: Contents of Haskell-Cafe digest..." > > > > > > Today's Topics: > > > > 1. Re: Haskell's "historical futurism" needs better writing, not > > better tools (Richard Eisenberg) > > 2. Re: Haskell's "historical futurism" needs better writing, not > > better tools (Jeffrey Brown) > > 3. Re: Haskell's "historical futurism" needs better writing, not > > better tools (Gregory Guthrie) > > 4. Re: Bundle patterns with type aliases (Carter Schonwald) > > 5. Re: Bundle patterns with type aliases (David Feuer) > > 6. Re: Bundle patterns with type aliases (David Feuer) > > > > > > ---------------------------------------------------------------------- > > > > Message: 1 > > Date: Thu, 16 Sep 2021 14:05:19 +0000 > > From: Richard Eisenberg > > To: Anthony Clayden > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > > better writing, not better tools > > Message-ID: > > <010f017beeed148e-35512a1d-0412-45c5-b1ac-ca532fa70f72-000000 at us-east-2.amazonses.com> > > > > Content-Type: text/plain; charset="utf-8" > > > > I just want to pipe up and say I'm not comfortable with this response. When I feel this way about writing on a forum, I normally contact the author in private, but I think posting publicly here has its merits. I'm hoping that the long correspondence AntC and I have had -- often with opposing viewpoints but with mutual respect -- with withstand this email. > > > > Michael posted here expressing frustration with his experience learning and using Haskell. In my opinion, he has spent too much time reading older papers, written by experts for experts -- which Michael is not. I do not fault Michael for this: these resources are sometimes what appear when searching, and we as a community have done a poor job marshaling our educational resources. (Michael, I just thought of a resource you might find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource attempting to do that marshaling. I am not vouching for it here, per se, but I know others have found it useful.) > > > > However, Michael very specifically said that "just learn lambda-calculus" was not helpful for him, and so I think it's unhelpful for someone to respond with "just learn lambda-calculus". There are a number of other statements in the email below which could be seen as belittling -- also not helpful. > > > > Instead, I wish that we, as a community, could take posts like Michael's at face value: this is the experience of someone who wants to learn Haskell. While some of the conclusions stated in that post are misunderstandings, it is not the sole fault of the learner for these misunderstandings: instead, we must try to understand what about our community and posted materials induced these misunderstandings, and then seek to improve. Many people in Michael's situation may not have posted at all -- and so this kind of information can be very hard to get. > > > > Michael, I have no silver bullet to offer to you to try to help you here. I do tend to agree with AntC that you have developed some misconceptions that are hindering your continued learning. The terminology actively hurts here. (To be fair, the first Haskell standard pre-dates both Java and C++, and so one could argue who got the terms wrong.) For my part, I am trying to help with this situation both by trying to improve error messages, and though my support of the Haskell Foundation's Haskell School initiative (https://github.com/haskellfoundation/HaskellSchool). These will take time to grow, but my hope is that a future person like you will have an easier route in. > > > > In the meantime, I implore us to take all expressed experiences as exactly that: the experience of the person writing. And if they say they don't want X, please let's not feed them X. :) > > > > Richard > > > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden wrote: > > > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > > > The seeds of your confusion are very evident from your message. How to back you out of whatever deep rabbit-hole you've managed to get your head into? > > > > > > > ... Your average reader (already a programmer) would be better served by a comparative approach: Here's how to say something in a couple of other programming languages, here's how to say something roughly equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way that C++ or C# are different. (I'll leave others to judge how subtly different they are.) > > > > > > Haskell is dramatically and fundamentally different. You can't just 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's many tales of woe on StackOverflow. Just No. > > > > > > I really don't know how you could have got any experience with Haskell and say "subtly". > > > > > > I suggest you unlearn everything you think you know about Haskell, and strike out in an entirely different direction. The best approach would be to spend a few days playing with lambda calculus. (That's what I did before tackling Haskell.) > > > > > > > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") > > > > > > Lambda calculus is an excellent place for beginners to start. What could be easier to learn? It's certainly easier than grokking a Turing machine; and much easier than Haskell: less than a handful of primitives yet can compute anything computable. > > > > > > > And since the concepts are seldom described in concrete enough and time-honored programming language terms (by comparison to other programming languages) > > > > > > I'm guessing that the concepts you're talking of simply don't correspond to anything in time-honoured (procedural) programming. Anybody writing about Haskell (including anybody writing the User Guide) assumes a base level of understanding of Haskell. You've clearly veered off the track and haven't yet reached base. Remember the User Guide builds on top of the Language Report. > > > > > > (On the point of 'time-honoured': lambda calculus is almost exactly the same age as Turing machines. The first well-known programming language using lambda-calculus ideas (LISP 1966) is almost exactly the same age as the first OOP language (Simula 1967). Which is the more time-honoured?) > > > > > > You do have a point that the terminology in Haskell is often mysterious > > > > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", and he felt this was wise. > > > > > > Yes many have yearned for a more warm-and-cuddly term than "monad". But the terminology barrier starts before that. > > > > > > Haskell typeclasses are not 'classes' in any sense recognisable from OOP. There are no objects, no hidden state, no destructive assignment. We might go back to February 1988 when a strawman for what became typeclasses used OVERLOAD/INSTANCE. > > > > > > AntC > > > > > > > > > > > > > > > _______________________________________________ > > > Haskell-Cafe mailing list > > > To (un)subscribe, modify options or view archives go to: > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Only members subscribed via the mailman list are allowed to post. > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: > > > > ------------------------------ > > > > Message: 2 > > Date: Thu, 16 Sep 2021 09:34:09 -0500 > > From: Jeffrey Brown > > To: Richard Eisenberg > > Cc: haskell-cafe , Anthony Clayden > > > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > > better writing, not better tools > > Message-ID: > > > > Content-Type: text/plain; charset="utf-8" > > > > I strongly believe the best study strategy is to be unfaithful to any > > source or subtopic. When I want to learn something, I study whatever aspect > > of it holds my interest, for only slightly longer than it continues to do > > so. If I continue to want to learn a topic, but lose interest in a > > particular source or subtopic, it's important to stop that particular > > avenue. Otherwise I'll lose motivation for the topic as a whole. > > > > The result is that, while I never learn (say) a language completely, I > > generally learn enough to do whatever I was trying to do. (Sometimes I > > learn enough to decide it's too hard -- and for cases in which that's bound > > to happen, the quicker the better.) > > > > Almost nobody learns any language completely anyway, and most of those > > who do could have used their time better. Sacrifice is a superpower. > > > > On Thu, Sep 16, 2021 at 9:09 AM Richard Eisenberg > > wrote: > > > > > I just want to pipe up and say I'm not comfortable with this response. > > > When I feel this way about writing on a forum, I normally contact the > > > author in private, but I think posting publicly here has its merits. I'm > > > hoping that the long correspondence AntC and I have had -- often with > > > opposing viewpoints but with mutual respect -- with withstand this email. > > > > > > Michael posted here expressing frustration with his experience learning > > > and using Haskell. In my opinion, he has spent too much time reading older > > > papers, written by experts for experts -- which Michael is not. I do not > > > fault Michael for this: these resources are sometimes what appear when > > > searching, and we as a community have done a poor job marshaling our > > > educational resources. (Michael, I just thought of a resource you might > > > find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource > > > attempting to do that marshaling. I am not vouching for it here, per se, > > > but I know others have found it useful.) > > > > > > However, Michael very specifically said that "just learn lambda-calculus" > > > was not helpful for him, and so I think it's unhelpful for someone to > > > respond with "just learn lambda-calculus". There are a number of other > > > statements in the email below which could be seen as belittling -- also not > > > helpful. > > > > > > Instead, I wish that we, as a community, could take posts like Michael's > > > at face value: this is the experience of someone who wants to learn > > > Haskell. While some of the conclusions stated in that post are > > > misunderstandings, it is not the sole fault of the learner for these > > > misunderstandings: instead, we must try to understand what about our > > > community and posted materials induced these misunderstandings, and then > > > seek to improve. Many people in Michael's situation may not have posted at > > > all -- and so this kind of information can be very hard to get. > > > > > > Michael, I have no silver bullet to offer to you to try to help you here. > > > I do tend to agree with AntC that you have developed some misconceptions > > > that are hindering your continued learning. The terminology actively hurts > > > here. (To be fair, the first Haskell standard pre-dates both Java and C++, > > > and so one could argue who got the terms wrong.) For my part, I am trying > > > to help with this situation both by trying to improve error messages, and > > > though my support of the Haskell Foundation's Haskell School initiative ( > > > https://github.com/haskellfoundation/HaskellSchool). These will take time > > > to grow, but my hope is that a future person like you will have an easier > > > route in. > > > > > > In the meantime, I implore us to take all expressed experiences as exactly > > > that: the experience of the person writing. And if they say they don't want > > > X, please let's not feed them X. :) > > > > > > Richard > > > > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden > > > wrote: > > > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > > > The seeds of your confusion are very evident from your message. How to > > > back you out of whatever deep rabbit-hole you've managed to get your head > > > into? > > > > > > > ... Your average reader (already a programmer) would be better served > > > by a comparative approach: Here's how to say something in a couple of > > > other programming languages, here's how to say something roughly > > > equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way > > > that C++ or C# are different. (I'll leave others to judge how subtly > > > different they are.) > > > > > > Haskell is dramatically and fundamentally different. You can't just > > > 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's > > > many tales of woe on StackOverflow. Just No. > > > > > > I really don't know how you could have got any experience with Haskell and > > > say "subtly". > > > > > > I suggest you unlearn everything you think you know about Haskell, and > > > strike out in an entirely different direction. The best approach would be > > > to spend a few days playing with lambda calculus. (That's what I did before > > > tackling Haskell.) > > > > > > > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") > > > > > > > > > Lambda calculus is an excellent place for beginners to start. What could > > > be easier to learn? It's certainly easier than grokking a Turing machine; > > > and much easier than Haskell: less than a handful of primitives yet can > > > compute anything computable. > > > > > > > And since the concepts are seldom described in concrete enough and > > > time-honored programming language terms (by comparison to other > > > programming languages) > > > > > > I'm guessing that the concepts you're talking of simply don't correspond > > > to anything in time-honoured (procedural) programming. Anybody writing > > > about Haskell (including anybody writing the User Guide) assumes a base > > > level of understanding of Haskell. You've clearly veered off the track and > > > haven't yet reached base. Remember the User Guide builds on top of the > > > Language Report. > > > > > > (On the point of 'time-honoured': lambda calculus is almost exactly the > > > same age as Turing machines. The first well-known programming language > > > using lambda-calculus ideas (LISP 1966) is almost exactly the same age as > > > the first OOP language (Simula 1967). Which is the more time-honoured?) > > > > > > You do have a point that the terminology in Haskell is often mysterious > > > > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", and > > > he felt this was wise. > > > > > > Yes many have yearned for a more warm-and-cuddly term than "monad". But > > > the terminology barrier starts before that. > > > > > > Haskell typeclasses are not 'classes' in any sense recognisable from OOP. > > > There are no objects, no hidden state, no destructive assignment. We might > > > go back to February 1988 when a strawman for what became typeclasses used > > > OVERLOAD/INSTANCE. > > > > > > AntC > > > > > > > > > > > > > > > _______________________________________________ > > > Haskell-Cafe mailing list > > > To (un)subscribe, modify options or view archives go to: > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Only members subscribed via the mailman list are allowed to post. > > > > > > > > > _______________________________________________ > > > Haskell-Cafe mailing list > > > To (un)subscribe, modify options or view archives go to: > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Only members subscribed via the mailman list are allowed to post. > > > > > > > > -- > > Jeff Brown | Jeffrey Benjamin Brown > > LinkedIn | Github > > | Twitter > > | Facebook > > | very old Website > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: > > > > ------------------------------ > > > > Message: 3 > > Date: Thu, 16 Sep 2021 15:28:16 +0000 > > From: Gregory Guthrie > > To: Richard Eisenberg , Anthony Clayden > > > > Cc: "haskell-cafe at haskell.org" > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs > > better writing, not better tools > > Message-ID: > > > > > > Content-Type: text/plain; charset="utf-8" > > > > Educational research and learning theory shows that learning anything new is more effective and longer retained when it is connected to and builds on prior knowledge. > > > > People may understand anything new if presented as a completely new set of ideas or principles, but that knowledge is not persistent or long remembered. > > > > I personally find Haskell a good example of this. When teaching it one can show incrementally how it is the same in many ways as procedural programming languages. Then how it improves on them with first-class functions, currying, immutability, type abstractions, etc. These are all important ideas that they will also see in other IP languages, just much cleaner and more integrated in Haskell(!). > > > > Basic Haskell programs with these features can then be used as a bisis for both appreciating the language features and design and FP in general, and as a stepping stone to more advanced usages. > > > > Then introducing Functors, Monads, .... Are again an easy and well motivated step for improving on their existing IP experience, and show both nice abstractions and ideas, and a nice implementation and results. > > > > All of this connects to and builds on what they already know. > > > > Moving into all of the fancier type system features and pragmas, one enters into a realm where Haskell programs are no longer simple enough to easily read as they incorporate several levels of new abstractions and syntax. > > > > But at least students have a good basis for further exploration, and an appreciation of FP and Haskell. :-) > > > > > > > > From: Haskell-Cafe On Behalf Of Richard Eisenberg > > Sent: Thursday, September 16, 2021 10:05 AM > > To: Anthony Clayden > > Cc: haskell-cafe at haskell.org > > Subject: Re: [Haskell-cafe] Haskell's "historical futurism" needs better writing, not better tools > > > > I just want to pipe up and say I'm not comfortable with this response. When I feel this way about writing on a forum, I normally contact the author in private, but I think posting publicly here has its merits. I'm hoping that the long correspondence AntC and I have had -- often with opposing viewpoints but with mutual respect -- with withstand this email. > > > > Michael posted here expressing frustration with his experience learning and using Haskell. In my opinion, he has spent too much time reading older papers, written by experts for experts -- which Michael is not. I do not fault Michael for this: these resources are sometimes what appear when searching, and we as a community have done a poor job marshaling our educational resources. (Michael, I just thought of a resource you might find useful: http://dev.stephendiehl.com/hask/ is an oft-linked resource attempting to do that marshaling. I am not vouching for it here, per se, but I know others have found it useful.) > > > > However, Michael very specifically said that "just learn lambda-calculus" was not helpful for him, and so I think it's unhelpful for someone to respond with "just learn lambda-calculus". There are a number of other statements in the email below which could be seen as belittling -- also not helpful. > > > > Instead, I wish that we, as a community, could take posts like Michael's at face value: this is the experience of someone who wants to learn Haskell. While some of the conclusions stated in that post are misunderstandings, it is not the sole fault of the learner for these misunderstandings: instead, we must try to understand what about our community and posted materials induced these misunderstandings, and then seek to improve. Many people in Michael's situation may not have posted at all -- and so this kind of information can be very hard to get. > > > > Michael, I have no silver bullet to offer to you to try to help you here. I do tend to agree with AntC that you have developed some misconceptions that are hindering your continued learning. The terminology actively hurts here. (To be fair, the first Haskell standard pre-dates both Java and C++, and so one could argue who got the terms wrong.) For my part, I am trying to help with this situation both by trying to improve error messages, and though my support of the Haskell Foundation's Haskell School initiative (https://github.com/haskellfoundation/HaskellSchool). These will take time to grow, but my hope is that a future person like you will have an easier route in. > > > > In the meantime, I implore us to take all expressed experiences as exactly that: the experience of the person writing. And if they say they don't want X, please let's not feed them X. :) > > > > Richard > > > > > > On Sep 16, 2021, at 12:53 AM, Anthony Clayden > wrote: > > > > Hi Michael, oh dear, oh dear, oh dear. > > > > The seeds of your confusion are very evident from your message. How to back you out of whatever deep rabbit-hole you've managed to get your head into? > > > > > ... Your average reader (already a programmer) would be better served by a comparative approach: Here's how to say something in a couple of other programming languages, here's how to say something roughly equivalent in Haskell -- BUT, here's how it's subtly different in Haskell. > > > > > > No. Just no. Haskell is not "subtly different" to (say) Java in the way that C++ or C# are different. (I'll leave others to judge how subtly different they are.) > > > > > > Haskell is dramatically and fundamentally different. You can't just 'translate' an algorithm from OOP to Haskell. Many newbies try, and there's many tales of woe on StackOverflow. Just No. > > > > > > I really don't know how you could have got any experience with Haskell and say "subtly". > > > > > > I suggest you unlearn everything you think you know about Haskell, and strike out in an entirely different direction. The best approach would be to spend a few days playing with lambda calculus. (That's what I did before tackling Haskell.) > > > > > > > > > (I've actually been curtly informed on the beginners' list -- yes, the beginner' list! -- that my problems of comprehension can be solved simply: "Learn lambda calculus.") > > > > > > Lambda calculus is an excellent place for beginners to start. What could be easier to learn? It's certainly easier than grokking a Turing machine; and much easier than Haskell: less than a handful of primitives yet can compute anything computable. > > > > > > > And since the concepts are seldom described in concrete enough and time-honored programming language terms (by comparison to other programming languages) > > > > > > I'm guessing that the concepts you're talking of simply don't correspond to anything in time-honoured (procedural) programming. Anybody writing about Haskell (including anybody writing the User Guide) assumes a base level of understanding of Haskell. You've clearly veered off the track and haven't yet reached base. Remember the User Guide builds on top of the Language Report. > > > > > > (On the point of 'time-honoured': lambda calculus is almost exactly the same age as Turing machines. The first well-known programming language using lambda-calculus ideas (LISP 1966) is almost exactly the same age as the first OOP language (Simula 1967). Which is the more time-honoured?) > > > > > > You do have a point that the terminology in Haskell is often mysterious > > > > > > > [SPJ said] F# had settled on the term "workflow" instead of "monad", and he felt this was wise. > > > > > > Yes many have yearned for a more warm-and-cuddly term than "monad". But the terminology barrier starts before that. > > > > > > Haskell typeclasses are not 'classes' in any sense recognisable from OOP. There are no objects, no hidden state, no destructive assignment. We might go back to February 1988 when a strawman for what became typeclasses used OVERLOAD/INSTANCE. > > > > > > AntC > > > > > > > > > > > > > > > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: > > > > ------------------------------ > > > > Message: 4 > > Date: Thu, 16 Sep 2021 14:21:58 -0400 > > From: Carter Schonwald > > To: David Feuer , GHC Users List > > , ghc-devs > > Cc: "haskell-cafe at haskell.org" > > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > > Message-ID: > > > > Content-Type: text/plain; charset="utf-8" > > > > These are great ideas! Could you please create a ghc tracker ticket with a > > tiny examples or two? > > > > There may be specific technical reasons we might not be able to do so for > > type synonyms in ghc, but I don’t see any obvious barriers in the case of > > David’s excellent idea, I’ve def seen lots of great code out there where > > you’d really want either associated pattern synonyms or to bundle pattern > > synonyms with the exported public interface for a type class. > > > > I’m sure there’s some devil in the details but these sound lovely. Step -1 > > is making up 1-2 toy examples and explaining what and why you want it on a > > ghc ticket! > > > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > > > > > I would like that, along with the ability to bundle patterns with classes. > > > > > > On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > > > > > >> Is there currently a way to 'bundle' a pattern with a type alias? And if > > >> not, could that capability be added to the PatternSynonyms GHC extension? > > >> (Is this the right place to ask, or should I be asking a GHC list?) > > >> > > >> --Keith > > >> Sent from my phone with K-9 Mail. > > >> _______________________________________________ > > >> Haskell-Cafe mailing list > > >> To (un)subscribe, modify options or view archives go to: > > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >> Only members subscribed via the mailman list are allowed to post. > > > > > > _______________________________________________ > > > Haskell-Cafe mailing list > > > To (un)subscribe, modify options or view archives go to: > > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > Only members subscribed via the mailman list are allowed to post. > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: > > > > ------------------------------ > > > > Message: 5 > > Date: Thu, 16 Sep 2021 15:08:45 -0400 > > From: David Feuer > > To: Carter Schonwald > > Cc: "haskell-cafe at haskell.org" , GHC Users > > List , ghc-devs > > > > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > > Message-ID: > > > > Content-Type: text/plain; charset="utf-8" > > > > Here's an example: > > > > pattern State :: (s -> (a, s)) -> State s a > > pattern State f <- (coerce . runStateT -> f) where > > State = state > > > > This would be very nice to bundle with the State type synonym. > > > > On Thu, Sep 16, 2021, 2:22 PM Carter Schonwald > > wrote: > > > > > These are great ideas! Could you please create a ghc tracker ticket with a > > > tiny examples or two? > > > > > > There may be specific technical reasons we might not be able to do so for > > > type synonyms in ghc, but I don’t see any obvious barriers in the case of > > > David’s excellent idea, I’ve def seen lots of great code out there where > > > you’d really want either associated pattern synonyms or to bundle pattern > > > synonyms with the exported public interface for a type class. > > > > > > I’m sure there’s some devil in the details but these sound lovely. Step > > > -1 is making up 1-2 toy examples and explaining what and why you want it on > > > a ghc ticket! > > > > > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > > > > > >> I would like that, along with the ability to bundle patterns with classes. > > >> > > >> On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > > >> > > >>> Is there currently a way to 'bundle' a pattern with a type alias? And if > > >>> not, could that capability be added to the PatternSynonyms GHC extension? > > >>> (Is this the right place to ask, or should I be asking a GHC list?) > > >>> > > >>> --Keith > > >>> Sent from my phone with K-9 Mail. > > >>> _______________________________________________ > > >>> Haskell-Cafe mailing list > > >>> To (un)subscribe, modify options or view archives go to: > > >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >>> Only members subscribed via the mailman list are allowed to post. > > >> > > >> _______________________________________________ > > >> Haskell-Cafe mailing list > > >> To (un)subscribe, modify options or view archives go to: > > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >> Only members subscribed via the mailman list are allowed to post. > > > > > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: > > > > ------------------------------ > > > > Message: 6 > > Date: Thu, 16 Sep 2021 15:12:57 -0400 > > From: David Feuer > > To: Carter Schonwald > > Cc: "haskell-cafe at haskell.org" , GHC Users > > List , ghc-devs > > > > Subject: Re: [Haskell-cafe] Bundle patterns with type aliases > > Message-ID: > > > > Content-Type: text/plain; charset="utf-8" > > > > Here's a class example: > > > > class (MFoldable t, Monoid t) => Sequence t where > > singleton :: Elem t -> t > > .... > > > > One might wish to write pattern synonyms for viewing the ends of a > > sequence, like the ones in Data.Sequence, and bundle them with this class. > > > > On Thu, Sep 16, 2021, 2:22 PM Carter Schonwald > > wrote: > > > > > These are great ideas! Could you please create a ghc tracker ticket with a > > > tiny examples or two? > > > > > > There may be specific technical reasons we might not be able to do so for > > > type synonyms in ghc, but I don’t see any obvious barriers in the case of > > > David’s excellent idea, I’ve def seen lots of great code out there where > > > you’d really want either associated pattern synonyms or to bundle pattern > > > synonyms with the exported public interface for a type class. > > > > > > I’m sure there’s some devil in the details but these sound lovely. Step > > > -1 is making up 1-2 toy examples and explaining what and why you want it on > > > a ghc ticket! > > > > > > On Wed, Sep 8, 2021 at 1:25 PM David Feuer wrote: > > > > > >> I would like that, along with the ability to bundle patterns with classes. > > >> > > >> On Wed, Sep 8, 2021, 1:13 PM Keith wrote: > > >> > > >>> Is there currently a way to 'bundle' a pattern with a type alias? And if > > >>> not, could that capability be added to the PatternSynonyms GHC extension? > > >>> (Is this the right place to ask, or should I be asking a GHC list?) > > >>> > > >>> --Keith > > >>> Sent from my phone with K-9 Mail. > > >>> _______________________________________________ > > >>> Haskell-Cafe mailing list > > >>> To (un)subscribe, modify options or view archives go to: > > >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >>> Only members subscribed via the mailman list are allowed to post. > > >> > > >> _______________________________________________ > > >> Haskell-Cafe mailing list > > >> To (un)subscribe, modify options or view archives go to: > > >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > >> Only members subscribed via the mailman list are allowed to post. > > > > > > > > -------------- next part -------------- > > An HTML attachment was scrubbed... > > URL: > > > > ------------------------------ > > > > Subject: Digest Footer > > > > _______________________________________________ > > Haskell-Cafe mailing list > > Haskell-Cafe at haskell.org > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > > > > > ------------------------------ > > > > End of Haskell-Cafe Digest, Vol 217, Issue 16 > > ********************************************* > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From mikolaj at well-typed.com Mon Sep 20 07:10:24 2021 From: mikolaj at well-typed.com (Mikolaj Konarski) Date: Mon, 20 Sep 2021 09:10:24 +0200 Subject: [Haskell-cafe] Cabal v3 public sub-libraries In-Reply-To: References: Message-ID: Hi Daniel, IIRC, the main, or the only remaining problem with public multi-libs is haddocks, and this set of haddock PRs paves the way and offers a manual workaround: https://github.com/haskell/haddock/pull/1419 Contributions and testing very welcome. Kind regards, Mikolaj On Sun, Sep 19, 2021 at 3:53 PM Daniel Winograd-Cort wrote: > > Hi cafe, > > I remember hearing about public sub-libraries in cabal v3, providing the ability to declare multiple libraries in the same cabal file that can be accessed (individually) by other packages. Does anyone know if this is supported on hackage, and if not, if there is a plan to allow this behavior on hackage? > > Thanks, > Daniel > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From david.feuer at gmail.com Mon Sep 20 17:13:43 2021 From: david.feuer at gmail.com (David Feuer) Date: Mon, 20 Sep 2021 13:13:43 -0400 Subject: [Haskell-cafe] Field types Message-ID: Does one field name for one datatype always refer to a field with the same type? Or is there some wacky extension that would allow things like data Foo = Bar { zoom :: Int } | Baz { zoom :: Char } I'm hoping I don't have to worry about the latter possibility.... -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Mon Sep 20 17:17:13 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 20 Sep 2021 13:17:13 -0400 Subject: [Haskell-cafe] Field types In-Reply-To: References: Message-ID: Unless something has changed very recently, the latter is illegal. On Mon, Sep 20, 2021 at 1:14 PM David Feuer wrote: > Does one field name for one datatype always refer to a field with the same > type? Or is there some wacky extension that would allow things like > > data Foo > = Bar { zoom :: Int } > | Baz { zoom :: Char } > > I'm hoping I don't have to worry about the latter possibility.... > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk Mon Sep 20 17:17:31 2021 From: tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk (Tom Ellis) Date: Mon, 20 Sep 2021 18:17:31 +0100 Subject: [Haskell-cafe] Field types In-Reply-To: References: Message-ID: <20210920171731.GW25255@cloudinit-builder> On Mon, Sep 20, 2021 at 01:13:43PM -0400, David Feuer wrote: > Does one field name for one datatype always refer to a field with the same > type? Or is there some wacky extension that would allow things like > > data Foo > = Bar { zoom :: Int } > | Baz { zoom :: Char } > > I'm hoping I don't have to worry about the latter possibility.... Me too! Under such circumstances what would the type of field-as-function be? From david.feuer at gmail.com Mon Sep 20 17:21:06 2021 From: david.feuer at gmail.com (David Feuer) Date: Mon, 20 Sep 2021 13:21:06 -0400 Subject: [Haskell-cafe] Field types In-Reply-To: <20210920171731.GW25255@cloudinit-builder> References: <20210920171731.GW25255@cloudinit-builder> Message-ID: In that hypothetical context, the field name wouldn't be usable as a function—at least without future Dependent Haskell. On Mon, Sep 20, 2021, 1:19 PM Tom Ellis < tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote: > On Mon, Sep 20, 2021 at 01:13:43PM -0400, David Feuer wrote: > > Does one field name for one datatype always refer to a field with the > same > > type? Or is there some wacky extension that would allow things like > > > > data Foo > > = Bar { zoom :: Int } > > | Baz { zoom :: Char } > > > > I'm hoping I don't have to worry about the latter possibility.... > > Me too! Under such circumstances what would the type of > field-as-function be? > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From allbery.b at gmail.com Mon Sep 20 17:42:53 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Mon, 20 Sep 2021 13:42:53 -0400 Subject: [Haskell-cafe] Field types In-Reply-To: References: <20210920171731.GW25255@cloudinit-builder> Message-ID: Well, there is already an extension that turns off selector-as-function, although I don't recall the name off the top of my head. I am not sure there's a way to access such fields as this at all if you use it, since e.g. HasField probably doesn't let you do types by constructor name. On Mon, Sep 20, 2021 at 1:21 PM David Feuer wrote: > In that hypothetical context, the field name wouldn't be usable as a > function—at least without future Dependent Haskell. > > On Mon, Sep 20, 2021, 1:19 PM Tom Ellis < > tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote: > >> On Mon, Sep 20, 2021 at 01:13:43PM -0400, David Feuer wrote: >> > Does one field name for one datatype always refer to a field with the >> same >> > type? Or is there some wacky extension that would allow things like >> > >> > data Foo >> > = Bar { zoom :: Int } >> > | Baz { zoom :: Char } >> > >> > I'm hoping I don't have to worry about the latter possibility.... >> >> Me too! Under such circumstances what would the type of >> field-as-function be? >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From david.feuer at gmail.com Mon Sep 20 17:45:34 2021 From: david.feuer at gmail.com (David Feuer) Date: Mon, 20 Sep 2021 13:45:34 -0400 Subject: [Haskell-cafe] Field types In-Reply-To: References: <20210920171731.GW25255@cloudinit-builder> Message-ID: I was just looking for confirmation. I'm playing around with using generics to make field-based lenses and traversals, and I don't want any unpleasant surprises. On Mon, Sep 20, 2021, 1:43 PM Brandon Allbery wrote: > Well, there is already an extension that turns off selector-as-function, > although I don't recall the name off the top of my head. I am not sure > there's a way to access such fields as this at all if you use it, since > e.g. HasField probably doesn't let you do types by constructor name. > > On Mon, Sep 20, 2021 at 1:21 PM David Feuer wrote: > >> In that hypothetical context, the field name wouldn't be usable as a >> function—at least without future Dependent Haskell. >> >> On Mon, Sep 20, 2021, 1:19 PM Tom Ellis < >> tom-lists-haskell-cafe-2017 at jaguarpaw.co.uk> wrote: >> >>> On Mon, Sep 20, 2021 at 01:13:43PM -0400, David Feuer wrote: >>> > Does one field name for one datatype always refer to a field with the >>> same >>> > type? Or is there some wacky extension that would allow things like >>> > >>> > data Foo >>> > = Bar { zoom :: Int } >>> > | Baz { zoom :: Char } >>> > >>> > I'm hoping I don't have to worry about the latter possibility.... >>> >>> Me too! Under such circumstances what would the type of >>> field-as-function be? >>> _______________________________________________ >>> Haskell-Cafe mailing list >>> To (un)subscribe, modify options or view archives go to: >>> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >>> Only members subscribed via the mailman list are allowed to post. >> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > > > > -- > brandon s allbery kf8nh > allbery.b at gmail.com > -------------- next part -------------- An HTML attachment was scrubbed... URL: From ietf-dane at dukhovni.org Mon Sep 20 17:50:52 2021 From: ietf-dane at dukhovni.org (Viktor Dukhovni) Date: Mon, 20 Sep 2021 13:50:52 -0400 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <4b1b0254-575d-dc50-6ec4-4794b2714581@durchholz.org> References: <20210918080002.GN25255@cloudinit-builder> <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> <1b3cfb80-3f4d-5eb4-c084-c7819f75a6e4@durchholz.org> <4b1b0254-575d-dc50-6ec4-4794b2714581@durchholz.org> Message-ID: <4AF614EB-4CAA-4044-9940-BF8509786509@dukhovni.org> > On 20 Sep 2021, at 2:30 am, Joachim Durchholz wrote: > > The idea is that a monad is a tool to construct a pipeline inside a Haskell program. > I think. It isn't my metaphor either, I have seen various people in this thread mention it in passing. A "pipeline" is not necessarily a *static* pipeline. Even in "bash" we have conditional branching: $ seq 1 99 | while read i; do if (( i % 10 == 1 )); then seq $i | grep 0 | fmt; fi; done 10 10 20 10 20 30 10 20 30 40 10 20 30 40 50 10 20 30 40 50 60 10 20 30 40 50 60 70 10 20 30 40 50 60 70 80 10 20 30 40 50 60 70 80 90 So IO and State and Maybe and Either all fit. As noted a few times in this thread List takes multiple paths. The "non-determinism" (something that not always explained well, since taking all paths is still rather deterministic) extends the simple pipeline model. The computation is still sequenced, it is just that a given stage can invoke its "continuation" multiple times. An intersting minimal model for the list monads is "jq", which is a small functional language for manipulating JSON values. It is basically the List monad for JSON, but both evaluation and function composition are written as simple-looking pipelines: value | function1 | function2 ... But more advanced "jq" users know that a value or function can be a stream (generator) of values: (value1, value2, ...) | function1 | function2 ... $ jq -n '(1,2,3,4) | select(. % 2 == 0) | range(.) | .+100' 100 101 100 101 102 103 So this is isomorphic to Haskell's List monad. And yet, in part because typically there's only one value on the left, and only one output on the right, the naive "pipeline" model is a fairly good fit if, as needed, one also admits "non-determinism". Where pipelines really don't appear to me to be an adequate mental model is "Cont". Reifying continuations feels very different from even a non-deterministic pipeline. Even "programmable semicolon" likely does not yield much intuition about "Cont". But, to first approximation, and without suffering any harm thereby, pipelines have worked well for me (and I expect others). I know that's not the whole/real story, I don't need the model as a crutch, but it works well enough, often enough to remain a useful way of reasoning about the many situations in which it is applicable. -- Viktor. From jo at durchholz.org Mon Sep 20 18:55:01 2021 From: jo at durchholz.org (Joachim Durchholz) Date: Mon, 20 Sep 2021 20:55:01 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning In-Reply-To: <4AF614EB-4CAA-4044-9940-BF8509786509@dukhovni.org> References: <20210918080002.GN25255@cloudinit-builder> <010f017bffe045a4-07464d25-6de3-42a0-a22f-bdaaee77a2f5-000000@us-east-2.amazonses.com> <1b3cfb80-3f4d-5eb4-c084-c7819f75a6e4@durchholz.org> <4b1b0254-575d-dc50-6ec4-4794b2714581@durchholz.org> <4AF614EB-4CAA-4044-9940-BF8509786509@dukhovni.org> Message-ID: <9b3f4465-287f-60bc-354b-08db399b07f3@durchholz.org> Am 20.09.21 um 19:50 schrieb Viktor Dukhovni: >> On 20 Sep 2021, at 2:30 am, Joachim Durchholz wrote: >> >> The idea is that a monad is a tool to construct a pipeline inside a Haskell program. >> I think. It isn't my metaphor either, I have seen various people in this thread mention it in passing. > > A "pipeline" is not necessarily a *static* pipeline. Even in "bash" we > have conditional branching: Sure, but we're talking about imagery in the heads of people. And few see things like conditional pipelines. > So IO and State and Maybe and Either all fit. In a sense, yes. But it requires an additional step - the pipeline itself is active and can be involved in decisionmaking. BTW I don't think that IO is really a pipeline. If you have inputs and decisionmaking, you have a decision tree. I believe the program takes just one path through that tree, but I don't understand IO well enough to validate that assumption. > As noted a few times in this thread List takes multiple paths. The > "non-determinism" (something that not always explained well, since > taking all paths is still rather deterministic) extends the simple > pipeline model. Yeah, actually it's fully deterministic, my wording was a bit too sloppy. > Where pipelines really don't appear to me to be an adequate mental model > is "Cont". Reifying continuations feels very different from even a > non-deterministic pipeline. Even "programmable semicolon" likely does not > yield much intuition about "Cont". > > But, to first approximation, and without suffering any harm thereby, pipelines > have worked well for me (and I expect others). I know that's not the whole/real > story, I don't need the model as a crutch, but it works well enough, often enough > to remain a useful way of reasoning about the many situations in which it is > applicable. Well, I believe that an image should clearly convey the limits of its usefulness, if only with a link to a "fully explanation" article. Very few Monad tutorials do that, which I think is a shame. Also, my model has been pretty easy - it's a variation of associativity. "Variation" because the operands are functions, and the result type of a left operand needs to match the parameter type of a right operand. (That's why it's "pseudo"-associative). Now with these constraints, the most natural thing to do is function composition, possibly with sandwiches default functions. If the operand type is a rich parameterized type, it can do more, to the point that the overall semantics is dominated by the operators instead of what the operands do. I also don't know if there's anything practically useful on that path. And, of course, I may be totally misunderstanding what a monad actually is. All I know is that this variation-of-associativity model seems to fit the monad laws more closely than the pipeline model, so _if_ it is correct I'd find it more useful than the pipeline model, because it tells me what things beyond a pipeline I could do with it. Regards, Jo From anthony.d.clayden at gmail.com Mon Sep 20 22:52:17 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Tue, 21 Sep 2021 10:52:17 +1200 Subject: [Haskell-cafe] Field types Message-ID: Report section 4.2.1 "A `data` declaration may use the same field label in multiple constructors as long as the typing of the field is the same in all cases after type synonym expansion." > In that hypothetical context, the field name wouldn't be usable as a > function—at least without future Dependent Haskell. TRex manages to support same label different field type in different records. The record's type includes the field labels, as a distinct Kind. `#lab` is the syntax to access a field labelled `lab`. > #lab :: a\lab => Rec (lab :: b | a) -> b `(lab :: b | a)` is of Kind Row, means a row with label `lab` at type `b`; `| a` captures any other fields in the record; `Rec( )` is a magic type constructor that makes Rows into Kind `*`. Context `a\lab` means `a` must not include label `lab`. Hugs.Trex> let myTuplePair = (( lab = 5 :: Int, lab2 = True), (lab = 'c', lab3 = Just 7)) > in (#lab $ fst myTuplePair, #lab $ snd myTuplePair) > (5,'c') On Mon, Sep 20, 2021, 1:19 PM Tom Ellis > wrote: >* On Mon, Sep 20, 2021 at 01:13:43PM -0400, David Feuer wrote: *>* > Does one field name for one datatype always refer to a field with the *>* same *>* > type? Or is there some wacky extension that would allow things like *>* > *>* > data Foo *>* > = Bar { zoom :: Int } *>* > | Baz { zoom :: Char } *>* > *>* > I'm hoping I don't have to worry about the latter possibility.... *>>* Me too! Under such circumstances what would the type of *>* field-as-function be?* -------------- next part -------------- An HTML attachment was scrubbed... URL: From b at chreekat.net Tue Sep 21 04:47:19 2021 From: b at chreekat.net (Bryan Richter) Date: Tue, 21 Sep 2021 07:47:19 +0300 Subject: [Haskell-cafe] Radians and degrees In-Reply-To: References: Message-ID: For what it's worth, I just spent some time with professional sailors and merchant marine officers, and they exclusively use degrees for measuring headings, bearings, and position (and speed/distance, if you consider the history of the nautical mile). So I guess they still have some practical use. :) On Mon, 20 Sep 2021, 9.15 Anthony Clayden, wrote: > > Neither [degrees nor radians] is really wrong. Degrees are strange, ... > > That sounds like the pot calling the kettle black. 'Irrational' means ... > errm ... strange. 'Transcendental' was the word Leibniz reached for when he > realised he had something stranger than irrationals. > > > an artifact of the Babylonian system with no real mathematical > significance. > > Hmm? An artefact of being approximately the number of days in a year > (which is as true for us as the Babylonians), and a number which has many > factors, so can happily measure quarter-turns, eighth turns (bracing to > keep your right-angles upright), whole-number of degrees for internal > angles of all the faces needed for the Platonic solids ... > > I would have thought there's a teachable moment there about prime numbers, > factorisation, and for bringing fractions into a coherent continuum. > > It's not like ignorance of this alleged "mathematical significance" of > radians prevented building Hanging Gardens or Pyramids, Stonehenge, the > fractals of the Walls of Benin, Machu Picchu trapeziums or aqueducts or > anything. (A bit like Category Theory, really.) > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From viluon at seznam.cz Tue Sep 21 12:59:20 2021 From: viluon at seznam.cz (Andrew Kvapil) Date: Tue, 21 Sep 2021 14:59:20 +0200 Subject: [Haskell-cafe] Optimising ReadP Message-ID: <17b0db63-4140-15bf-c296-625237ec5512@seznam.cz> Hi, I'm trying to optimise a short Haskell program (inspired by Rust's performance). From simple profiling, I discovered that 90+% of time and allocations is spent in a `ReadP`-based parser. The parser is fairly small, I assumed GHC would inline/optimise most of it. I tried adding some `SPECIALISE` pragmas but found out those don't work: they require `INLINE`/`INLINEABLE` pragmas or compiling with `-O`. I'm confused by the latter requirement as I thought dependencies of the Stack project are compiled with optimisation enabled. I copied the entirety of the `ReadP` module into my project along with what I used from `Text.Read.Lex` to be able to optimise this code locally. I managed to get some speedups by specialising the integer parsers. Cloning the `ReadP` code also helped with more detailed profiling reports, I now know that the majority of time and allocations are spent in `>>=`. That's it for the long-winded intro, here are my questions: - what's the problem with GHC complaining about missing `INLINE(ABLE)` pragmas and/or `-O` in Stack dependencies? - Are these things just never inlined unless library authors specifically mark them as such? - What profiling tools do people usually use in situations like this? - I cannot specialise `>>=` even when I mark it `INLINEABLE` in the `Monad ReadP` instance, apparently, the pragma should be placed at the declaration site (at least that's what the warning says). So I run into the same issue with `INLINE(ABLE)`/`-O` as above. That seems pretty silly, I feel like I should be able to inline/specialise this particular instance and not worry about the global declaration of `>>=`. Is there a workaround for this? - I also used `BangPatterns` in my optimisations, but it's been hit-and-miss. They (surprisingly) helped in small, local definitions marked `INLINE` (I assumed strictness analysis would pick up on those), but in other places, such as `ReadP`'s `>>=`, strictness annotations slightly worsened performance. How do people look for good patterns to annotate as strict? - How do I find out to what extent is laziness slowing things down, or look for places with unintended thunks? As these are general optimisation questions, I'm not looking for parsing alternatives suggestions. I'd like to write high-level code and have it efficiently compose, this is a toy program anyway and I'm wondering how far can I get with such a simple parsing library. I suspect the majority of allocations coming from the parser are short-lived garbage that I should be able to avoid with optimisations and maybe a little bit of refactoring. One thing that's specific to my implementation is that the parser first produces a `[(Int, Int)]` and then converts that to `IntMap (Set Int)` with a `foldl'`. I would like to ensure the list is never built in the first place, is there a way to do that? As to the code itself, it's only 90 lines, but I'm not sure what the consensus is on attachments in this mailing list. I can provide the whole Stack project along with a test case and a reference solution in Rust upon request. (I'd post it on my GitHub, but there's a slight chance a participant in the competition this is a reference solution to may find it there.) Best regards, Andrew From mikolaj at well-typed.com Tue Sep 21 15:10:34 2021 From: mikolaj at well-typed.com (Mikolaj Konarski) Date: Tue, 21 Sep 2021 17:10:34 +0200 Subject: [Haskell-cafe] Cabal v3 public sub-libraries In-Reply-To: References: Message-ID: Hi Daniel, > Should I try a candidate upload to hackage, or is the testing about something in hackage-server or cabal itself? I don't remember if candidates now display haddocks, but if they do, that's probably a good way to test the multilib haddocks. Otherwise, I guess, spin a private Hackage and test there. I looked closer and there is also some related work remaining to do in cabal https://github.com/haskell/cabal/issues/7669 and in haddock (polishing the multilib case and extending to backpack) https://github.com/haskell/haddock/issues/1363 but probably not a lot in hackage-server itself https://github.com/haskell/hackage-server/issues/924 https://github.com/haskell/hackage-server/issues/577 It may be useful to get in touch with the interested parties and comment in these issues or open new ones. Kind regards, Mikolaj On Tue, Sep 21, 2021 at 4:56 PM Daniel Winograd-Cort wrote: > > Hi Mikolaj, > > Thanks for the response! Do you have any tips on how I can go about testing? Should I try a candidate upload to hackage, or is the testing about something in hackage-server or cabal itself? > > Best, > Daniel > > On Mon, Sep 20, 2021 at 3:10 AM Mikolaj Konarski wrote: >> >> Hi Daniel, >> >> IIRC, the main, or the only remaining problem with public multi-libs >> is haddocks, and this set of haddock PRs paves the way and offers a >> manual workaround: https://github.com/haskell/haddock/pull/1419 >> >> Contributions and testing very welcome. >> >> Kind regards, >> Mikolaj >> >> On Sun, Sep 19, 2021 at 3:53 PM Daniel Winograd-Cort wrote: >> > >> > Hi cafe, >> > >> > I remember hearing about public sub-libraries in cabal v3, providing the ability to declare multiple libraries in the same cabal file that can be accessed (individually) by other packages. Does anyone know if this is supported on hackage, and if not, if there is a plan to allow this behavior on hackage? >> > >> > Thanks, >> > Daniel >> > >> > _______________________________________________ >> > Haskell-Cafe mailing list >> > To (un)subscribe, modify options or view archives go to: >> > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> > Only members subscribed via the mailman list are allowed to post. From olf at aatal-apotheke.de Tue Sep 21 19:17:15 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Tue, 21 Sep 2021 21:17:15 +0200 Subject: [Haskell-cafe] Better writing about Haskell through multi-metaphor learning Message-ID: <9e0f57b89be8ab8c1fff9a78cb3d3cc97f2a02a4.camel@aatal-apotheke.de> > As noted a few times in this thread List takes multiple paths. The > "non-determinism" (something that not always explained well, since > taking all paths is still rather deterministic) extends the simple > pipeline model. In principle you could make the different paths race against each other and return the one that finishes (first). That would be proper non- determinism. List, Sequence, Tree and such are set-like monads, which I would put into the non-determinism corner. Years ago I was experimenting with decision-making and sequence alignment in particular. The hypothesis was that if you have a functional program that makes a decision on exact data, then lifting the program through a suitable monad M will give you a decision procedure for M-fuzzy inputs. For example, we managed to implement string matching for the ListT monad transformer, so you can match fuzzy strings against fuzzy strings. Here a full-text index (e.g. suffix tree) is itself a special kind of fuzzy string parametrized by the list monad. Decomposing it into head and tail takes you simultaneously to every position in the indexed text. Set-like monads do not fit the pipeline model well, it seems. By the way, I struggle with the pipeline metaphor. If a monad is a pipeline, what are the connectors? Is (m a) a piece of pipe and (>>) a connector? Or is (a -> m b) a piece of pipe and (>=>) a connector? In my Haskell exposition for mathematicians I chose the monad of formal linear combinations for introduction of monads. In this monad M, (M b) is a vector over basis b, (b1 -> M b2) describes a linear map (matrix) w.r.t. bases b1 and b2, (<=<) is matrix multiplication and (=<<) is matrix-vector multiplication. So if you like matrices, mentally replace (a -> m b) by "linear map" and (m a) by "vector". Olaf From heraldhoi at gmail.com Tue Sep 21 20:47:31 2021 From: heraldhoi at gmail.com (Geraldus) Date: Wed, 22 Sep 2021 01:47:31 +0500 Subject: [Haskell-cafe] Troubles with PostgreSQL, Persistent and Apple M1 Message-ID: Hi, dear Cafe! I'm having trouble compiling an application which uses PostgreSQL on a macbook with an M1 chip. Postgre itself seems to work fine. It is installed via `homebrew` (if I'm not mistaken this is the only way on Mac to get pg_config, which is required for `persistent-postgresql`). The error message is following: ``` persistent-postgresql> : dlopen(/Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib, 5): *Symbol not found: _PQclear* persistent-postgresql> Referenced from: /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib persistent-postgresql> *Expected in: flat namespace* persistent-postgresql> in /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib ``` The minimal setup to reproduce is following: ``` dependencies: - base >= 4.7 && < 5 - persistent >= 2.13.1.2 && < 3 - persistent-postgresql >= 2.13.1.0 && < 3 ``` Digging around gave me just a few clues. It seems that `libpq` I have is compiled some other way it expected, and missing some symbols required `persistent-postgresql` to work. I believe this is not a bug, rather that a local configuration issue. Does anyone know which is right setup to build persistent-postgresql on Macs with M1 chip? Thanks in advance. Sincerely. Arthur. P.S. Please apologize if this is not a right place to ask such questions. Asked already in Yesod Google Groups and Stack Overflow. But didn't received any feedback. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Tue Sep 21 20:55:11 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Tue, 21 Sep 2021 22:55:11 +0200 Subject: [Haskell-cafe] Troubles with PostgreSQL, Persistent and Apple M1 In-Reply-To: References: Message-ID: which version of postgresql you are using? bmaxa at Branimirs-Air ~ % brew search postgres ==> Formulae check_postgres postgresql at 10 postgresql at 12 postgresql at 9.5 postgrest postgis postgresql postgresql at 11 postgresql at 9.4 postgresql at 9.6 qt-postgresql ==> Casks navicat-for-postgresql postgres-unofficial postgrespreferencepane sqlpro-for-postgres ? Greetings, Branimir. > On 21.09.2021., at 22:47, Geraldus wrote: > > Hi, dear Cafe! > > I'm having trouble compiling an application which uses PostgreSQL on a macbook with an M1 chip. > > Postgre itself seems to work fine. It is installed via `homebrew` (if I'm not mistaken this is the only way on Mac to get pg_config, which is required for `persistent-postgresql`). The error message is following: > > ``` > persistent-postgresql> : dlopen(/Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib, 5): Symbol not found: _PQclear > persistent-postgresql> Referenced from: /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib > persistent-postgresql> Expected in: flat namespace > persistent-postgresql> in /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib > ``` > > The minimal setup to reproduce is following: > > ``` > dependencies: > - base >= 4.7 && < 5 > - persistent >= 2.13.1.2 && < 3 > - persistent-postgresql >= 2.13.1.0 && < 3 > ``` > > Digging around gave me just a few clues. It seems that `libpq` I have is compiled some other way it expected, and missing some symbols required `persistent-postgresql` to work. I believe this is not a bug, rather that a local configuration issue. > > Does anyone know which is right setup to build persistent-postgresql on Macs with M1 chip? Thanks in advance. > > Sincerely. > Arthur. > > P.S. Please apologize if this is not a right place to ask such questions. Asked already in Yesod Google Groups and Stack Overflow. But didn't received any feedback. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From heraldhoi at gmail.com Tue Sep 21 20:59:18 2021 From: heraldhoi at gmail.com (Geraldus) Date: Wed, 22 Sep 2021 01:59:18 +0500 Subject: [Haskell-cafe] Troubles with PostgreSQL, Persistent and Apple M1 In-Reply-To: References: Message-ID: Thank you for your response. I use 13.4: ``` arthurfayzrakhmanov at MacBook-Pro-Arthur ~/L/h/pg001> brew search postgres ==> Formulae check_postgres postgresql at 11 postgresql at 9.5 qt-postgresql postgresql ✔ postgresql at 12 postgresql at 9.6 postgis postgresql at 10 postgresql at 9.4 postgrest ==> Casks navicat-for-postgresql postgrespreferencepane postgres-unofficial sqlpro-for-postgres arthurfayzrakhmanov at MacBook-Pro-Arthur ~/L/h/pg001> psql --version psql (PostgreSQL) 13.4 ``` ср, 22 сент. 2021 г. в 01:55, Branimir Maksimovic < branimir.maksimovic at gmail.com>: > which version of postgresql you are using? > bmaxa at Branimirs-Air ~ % brew search postgres > ==> Formulae > check_postgres postgresql at 10 postgresql at 12 > postgresql at 9.5 postgrest postgis > postgresql postgresql at 11 postgresql at 9.4 > postgresql at 9.6 qt-postgresql > ==> Casks > navicat-for-postgresql postgres-unofficial > postgrespreferencepane sqlpro-for-postgres > > ? > > Greetings, Branimir. > > On 21.09.2021., at 22:47, Geraldus wrote: > > Hi, dear Cafe! > > I'm having trouble compiling an application which uses PostgreSQL on a > macbook with an M1 chip. > > Postgre itself seems to work fine. It is installed via `homebrew` (if I'm > not mistaken this is the only way on Mac to get pg_config, which is > required for `persistent-postgresql`). The error message is following: > > ``` > persistent-postgresql> : > dlopen(/Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib, > 5): *Symbol not found: _PQclear* > persistent-postgresql> Referenced from: > /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib > persistent-postgresql> *Expected in: flat namespace* > persistent-postgresql> in > /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib > ``` > > The minimal setup to reproduce is following: > > ``` > dependencies: > - base >= 4.7 && < 5 > - persistent >= 2.13.1.2 && < 3 > - persistent-postgresql >= 2.13.1.0 && < 3 > ``` > > Digging around gave me just a few clues. It seems that `libpq` I have is > compiled some other way it expected, and missing some symbols required > `persistent-postgresql` to work. I believe this is not a bug, rather that > a local configuration issue. > > Does anyone know which is right setup to build persistent-postgresql on > Macs with M1 chip? Thanks in advance. > > Sincerely. > Arthur. > > P.S. Please apologize if this is not a right place to ask such questions. > Asked already in Yesod Google Groups and Stack Overflow. But didn't > received any feedback. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Tue Sep 21 21:47:56 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Tue, 21 Sep 2021 23:47:56 +0200 Subject: [Haskell-cafe] Troubles with PostgreSQL, Persistent and Apple M1 In-Reply-To: References: Message-ID: <86768AEA-64AC-4C32-B34B-E448D95FB5D0@gmail.com> seems you are using ghc for different architecture: bmaxa at Branimirs-Air ~ % brew search ghc ==> Formulae ghc ✔ ghc at 8.6 ghc at 8.8 ghc at 9 gh ghq ghi ghz ghr grc gcc ✔ shc If you meant "ghc" specifically: It was migrated from homebrew/cask to homebrew/core. bmaxa at Branimirs-Air ~ % ghc -v Glasgow Haskell Compiler, Version 8.10.7, stage 2 booted by GHC version 8.10.7 *** initializing package database: Using binary package database: /opt/homebrew/Cellar/ghc/8.10.7/lib/ghc-8.10.7/package.conf.d/package.cache package flags [] loading package database /opt/homebrew/Cellar/ghc/8.10.7/lib/ghc-8.10.7/package.conf.d wired-in package ghc-prim mapped to ghc-prim-0.6.1 wired-in package integer-wired-in mapped to integer-gmp-1.0.3.0 wired-in package base mapped to base-4.14.3.0 wired-in package rts mapped to rts wired-in package template-haskell mapped to template-haskell-2.16.0.0 wired-in package ghc mapped to ghc-8.10.7 !!! initializing package database: finished in 10.92 milliseconds, allocated 8.308 megabytes Greetings, Branimir. > On 21.09.2021., at 22:47, Geraldus wrote: > > Hi, dear Cafe! > > I'm having trouble compiling an application which uses PostgreSQL on a macbook with an M1 chip. > > Postgre itself seems to work fine. It is installed via `homebrew` (if I'm not mistaken this is the only way on Mac to get pg_config, which is required for `persistent-postgresql`). The error message is following: > > ``` > persistent-postgresql> : dlopen(/Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib, 5): Symbol not found: _PQclear > persistent-postgresql> Referenced from: /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib > persistent-postgresql> Expected in: flat namespace > persistent-postgresql> in /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib > ``` > > The minimal setup to reproduce is following: > > ``` > dependencies: > - base >= 4.7 && < 5 > - persistent >= 2.13.1.2 && < 3 > - persistent-postgresql >= 2.13.1.0 && < 3 > ``` > > Digging around gave me just a few clues. It seems that `libpq` I have is compiled some other way it expected, and missing some symbols required `persistent-postgresql` to work. I believe this is not a bug, rather that a local configuration issue. > > Does anyone know which is right setup to build persistent-postgresql on Macs with M1 chip? Thanks in advance. > > Sincerely. > Arthur. > > P.S. Please apologize if this is not a right place to ask such questions. Asked already in Yesod Google Groups and Stack Overflow. But didn't received any feedback. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Tue Sep 21 22:08:33 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Wed, 22 Sep 2021 00:08:33 +0200 Subject: [Haskell-cafe] Troubles with PostgreSQL, Persistent and Apple M1 In-Reply-To: References: Message-ID: Seems builds no problem… To start postgresql: brew services start postgresql Or, if you don't want/need a background service you can just run: /opt/homebrew/opt/postgresql/bin/postgres -D /opt/homebrew/var/postgres bmaxa at Branimirs-Air ~ % cabal install persistent-postgresql Warning: The package list for 'hackage.haskell.org' is 69 days old. Run 'cabal update' to get the latest list of available packages. Warning: The package list for 'hackage.haskell.org' is 69 days old. Run 'cabal update' to get the latest list of available packages. Resolving dependencies... Build profile: -w ghc-8.10.7 -O1 In order, the following will be built (use -v for more details): - Only-0.1 (lib) (requires build) - blaze-builder-0.4.2.1 (lib) (requires download & build) - base-compat-0.11.2 (lib) (requires build) - base-orphans-0.8.4 (lib) (requires build) - base64-bytestring-1.2.0.1 (lib) (requires download & build) - bytestring-builder-0.10.8.2.0 (lib) (requires download & build) - dlist-1.0 (lib) (requires build) - data-default-class-0.1.2.0 (lib:data-default-class) (requires build) - hsc2hs-0.68.7 (exe:hsc2hs) (requires build) - hashable-1.3.2.0 (lib) (requires build) - old-locale-1.0.0.7 (lib) (requires download & build) - lift-type-0.1.0.1 (lib) (requires download & build) - monad-loops-0.4.3 (lib) (requires download & build) - indexed-traversable-0.1.1 (lib) (requires build) - unliftio-core-0.2.0.1 (lib) (requires download & build) - integer-logarithms-1.0.3.1 (lib) (requires build) - unix-compat-0.5.3 (lib) (requires download & build) - primitive-0.7.1.0 (lib) (requires build) - path-pieces-0.2.1 (lib) (requires download & build) - silently-1.2.5.1 (lib) (requires download & build) - split-0.2.3.4 (lib) (requires download & build) - splitmix-0.1.0.3 (lib) (requires build) - stm-chans-3.0.0.4 (lib:stm-chans) (requires download & build) - easy-file-0.2.2 (lib:easy-file) (requires download & build) - auto-update-0.1.6 (lib) (requires download & build) - utf8-string-1.0.2 (lib) (requires download & build) - tagged-0.8.6.1 (lib) (requires build) - th-abstraction-0.4.2.0 (lib) (requires build) - transformers-compat-0.6.6 (lib) (requires build) - zlib-0.6.2.3 (lib) (requires download & build) - blaze-markup-0.8.2.8 (lib) (requires download & build) - base-compat-batteries-0.11.2 (lib) (requires build) - cookie-0.4.5 (lib) (requires download & build) - postgresql-libpq-0.9.4.3 (lib:postgresql-libpq) (requires download & build) - network-3.1.2.2 (lib:network) (requires download & build) - time-compat-1.9.6 (lib) (requires build) - async-2.2.3 (lib) (requires build) - unordered-containers-0.2.14.0 (lib) (requires build) - data-fix-0.3.1 (lib) (requires build) - case-insensitive-1.2.1.0 (lib) (requires download & build) - old-time-1.1.0.3 (lib:old-time) (requires download & build) - vector-0.12.3.0 (lib) (requires build) - scientific-0.3.7.0 (lib) (requires build) - resourcet-1.2.4.2 (lib) (requires download & build) - random-1.2.0 (lib) (requires build) - string-conversions-0.4.0.1 (lib) (requires download & build) - distributive-0.6.2.1 (lib) (requires build) - th-lift-0.8.2 (lib) (requires download & build) - transformers-base-0.4.5.2 (lib) (requires download & build) - blaze-html-0.9.1.2 (lib) (requires download & build) - typed-process-0.2.6.0 (lib) (requires download & build) - unliftio-0.2.18 (lib) (requires download & build) - http-types-0.12.3 (lib) (requires download & build) - unix-time-0.4.7 (lib:unix-time) (requires download & build) - vector-algorithms-0.8.0.4 (lib) (requires build) - attoparsec-0.14.1 (lib) (requires build) - streaming-commons-0.2.2.1 (lib) (requires download & build) - uuid-types-1.0.5 (lib) (requires build) - comonad-5.0.8 (lib) (requires build) - th-lift-instances-0.1.18 (lib) (requires download & build) - monad-control-1.0.2.3 (lib:monad-control) (requires download & build) - fast-logger-3.0.5 (lib) (requires download & build) - mono-traversable-1.0.15.1 (lib) (requires download & build) - attoparsec-iso8601-1.0.2.0 (lib) (requires download & build) - bifunctors-5.5.11 (lib) (requires build) - resource-pool-0.2.3.2 (lib) (requires download & build) - lifted-base-0.2.3.12 (lib) (requires download & build) - conduit-1.3.4.1 (lib) (requires download & build) - http-api-data-0.4.3 (lib) (requires download & build) - assoc-1.0.2 (lib) (requires build) - conduit-extra-1.3.5 (lib) (requires download & build) - these-1.1.1.1 (lib) (requires build) - monad-logger-0.3.36 (lib) (requires download & build) - strict-0.4.0.1 (lib) (requires build) - aeson-1.5.6.0 (lib) (requires build) - postgresql-simple-0.6.4 (lib) (requires download & build) - persistent-2.13.1.1 (lib) (requires download & build) - persistent-postgresql-2.13.0.3 (lib) (requires download & build) Downloading old-locale-1.0.0.7 Starting base-orphans-0.8.4 (lib) Starting data-default-class-0.1.2.0 (all, legacy fallback) Starting dlist-1.0 (lib) Starting Only-0.1 (lib) Starting base-compat-0.11.2 (lib) Building dlist-1.0 (lib) Building data-default-class-0.1.2.0 (all, legacy fallback) Building base-compat-0.11.2 (lib) Building base-orphans-0.8.4 (lib) Building Only-0.1 (lib) Downloaded old-locale-1.0.0.7 Downloading old-time-1.1.0.3 Installing data-default-class-0.1.2.0 (all, legacy fallback) Installing Only-0.1 (lib) Completed data-default-class-0.1.2.0 (all, legacy fallback) Starting hsc2hs-0.68.7 (exe:hsc2hs) Downloaded old-time-1.1.0.3 Downloading monad-loops-0.4.3 Completed Only-0.1 (lib) Starting hashable-1.3.2.0 (lib) Downloaded monad-loops-0.4.3 Downloading split-0.2.3.4 Building hsc2hs-0.68.7 (exe:hsc2hs) Building hashable-1.3.2.0 (lib) Downloaded split-0.2.3.4 Downloading auto-update-0.1.6 Downloaded auto-update-0.1.6 Downloading unliftio-core-0.2.0.1 Downloaded unliftio-core-0.2.0.1 Downloading base64-bytestring-1.2.0.1 Installing dlist-1.0 (lib) Completed dlist-1.0 (lib) Starting old-locale-1.0.0.7 (lib) Downloaded base64-bytestring-1.2.0.1 Downloading utf8-string-1.0.2 Starting base64-bytestring-1.2.0.1 (lib) Building old-locale-1.0.0.7 (lib) Downloaded utf8-string-1.0.2 Downloading zlib-0.6.2.3 Building base64-bytestring-1.2.0.1 (lib) Installing base-orphans-0.8.4 (lib) Downloaded zlib-0.6.2.3 Downloading bytestring-builder-0.10.8.2.0 Completed base-orphans-0.8.4 (lib) Installing old-locale-1.0.0.7 (lib) Downloaded bytestring-builder-0.10.8.2.0 Downloading lift-type-0.1.0.1 Starting bytestring-builder-0.10.8.2.0 (lib) Installing hashable-1.3.2.0 (lib) Completed old-locale-1.0.0.7 (lib) Starting monad-loops-0.4.3 (lib) Completed hashable-1.3.2.0 (lib) Starting indexed-traversable-0.1.1 (lib) Downloaded lift-type-0.1.0.1 Downloading th-lift-0.8.2 Building bytestring-builder-0.10.8.2.0 (lib) Starting lift-type-0.1.0.1 (lib) Installing bytestring-builder-0.10.8.2.0 (lib) Building monad-loops-0.4.3 (lib) Completed bytestring-builder-0.10.8.2.0 (lib) Starting unliftio-core-0.2.0.1 (lib) Building indexed-traversable-0.1.1 (lib) Downloaded th-lift-0.8.2 Downloading silently-1.2.5.1 Building lift-type-0.1.0.1 (lib) Installing base64-bytestring-1.2.0.1 (lib) Building unliftio-core-0.2.0.1 (lib) Completed base64-bytestring-1.2.0.1 (lib) Starting integer-logarithms-1.0.3.1 (lib) Downloaded silently-1.2.5.1 Downloading unix-compat-0.5.3 Installing lift-type-0.1.0.1 (lib) Completed lift-type-0.1.0.1 (lib) Downloaded unix-compat-0.5.3 Downloading network-3.1.2.2 Building integer-logarithms-1.0.3.1 (lib) Starting unix-compat-0.5.3 (lib) Installing unliftio-core-0.2.0.1 (lib) Completed unliftio-core-0.2.0.1 (lib) Starting primitive-0.7.1.0 (lib) Downloaded network-3.1.2.2 Downloading unix-time-0.4.7 Building unix-compat-0.5.3 (lib) Installing monad-loops-0.4.3 (lib) Completed monad-loops-0.4.3 (lib) Building primitive-0.7.1.0 (lib) Downloaded unix-time-0.4.7 Downloading easy-file-0.2.2 Downloaded easy-file-0.2.2 Downloading resourcet-1.2.4.2 Downloaded resourcet-1.2.4.2 Downloading transformers-base-0.4.5.2 Installing integer-logarithms-1.0.3.1 (lib) Completed integer-logarithms-1.0.3.1 (lib) Starting silently-1.2.5.1 (lib) Downloaded transformers-base-0.4.5.2 Downloading monad-control-1.0.2.3 Installing unix-compat-0.5.3 (lib) Building silently-1.2.5.1 (lib) Completed unix-compat-0.5.3 (lib) Starting split-0.2.3.4 (lib) Downloaded monad-control-1.0.2.3 Downloading lifted-base-0.2.3.12 Downloaded lifted-base-0.2.3.12 Downloading blaze-builder-0.4.2.1 Installing silently-1.2.5.1 (lib) Building split-0.2.3.4 (lib) Completed silently-1.2.5.1 (lib) Starting splitmix-0.1.0.3 (lib) Installing hsc2hs-0.68.7 (exe:hsc2hs) Downloaded blaze-builder-0.4.2.1 Downloading blaze-markup-0.8.2.8 Completed hsc2hs-0.68.7 (exe:hsc2hs) Starting blaze-builder-0.4.2.1 (lib) Building splitmix-0.1.0.3 (lib) Downloaded blaze-markup-0.8.2.8 Downloading blaze-html-0.9.1.2 Installing indexed-traversable-0.1.1 (lib) Building blaze-builder-0.4.2.1 (lib) Completed indexed-traversable-0.1.1 (lib) Starting easy-file-0.2.2 (all, legacy fallback) Downloaded blaze-html-0.9.1.2 Downloading cookie-0.4.5 Installing split-0.2.3.4 (lib) Completed split-0.2.3.4 (lib) Starting auto-update-0.1.6 (lib) Building easy-file-0.2.2 (all, legacy fallback) Downloaded cookie-0.4.5 Downloading fast-logger-3.0.5 Building auto-update-0.1.6 (lib) Downloaded fast-logger-3.0.5 Downloading case-insensitive-1.2.1.0 Downloaded case-insensitive-1.2.1.0 Downloading resource-pool-0.2.3.2 Installing splitmix-0.1.0.3 (lib) Installing base-compat-0.11.2 (lib) Completed splitmix-0.1.0.3 (lib) Starting utf8-string-1.0.2 (lib) Completed base-compat-0.11.2 (lib) Starting tagged-0.8.6.1 (lib) Installing easy-file-0.2.2 (all, legacy fallback) Downloaded resource-pool-0.2.3.2 Downloading unliftio-0.2.18 Completed easy-file-0.2.2 (all, legacy fallback) Starting th-abstraction-0.4.2.0 (lib) Installing auto-update-0.1.6 (lib) Building utf8-string-1.0.2 (lib) Completed auto-update-0.1.6 (lib) Starting transformers-compat-0.6.6 (lib) Building tagged-0.8.6.1 (lib) Downloaded unliftio-0.2.18 Downloading typed-process-0.2.6.0 Building th-abstraction-0.4.2.0 (lib) Downloaded typed-process-0.2.6.0 Downloading http-types-0.12.3 Building transformers-compat-0.6.6 (lib) Downloaded http-types-0.12.3 Downloading mono-traversable-1.0.15.1 Downloaded mono-traversable-1.0.15.1 Downloading conduit-1.3.4.1 Downloaded conduit-1.3.4.1 Downloading path-pieces-0.2.1 Downloaded path-pieces-0.2.1 Downloading streaming-commons-0.2.2.1 Starting path-pieces-0.2.1 (lib) Installing blaze-builder-0.4.2.1 (lib) Downloaded streaming-commons-0.2.2.1 Downloading string-conversions-0.4.0.1 Completed blaze-builder-0.4.2.1 (lib) Installing tagged-0.8.6.1 (lib) Starting zlib-0.6.2.3 (lib) Completed tagged-0.8.6.1 (lib) Starting cookie-0.4.5 (lib) Building path-pieces-0.2.1 (lib) Downloaded string-conversions-0.4.0.1 Downloading th-lift-instances-0.1.18 Downloaded th-lift-instances-0.1.18 Downloading conduit-extra-1.3.5 Building zlib-0.6.2.3 (lib) Building cookie-0.4.5 (lib) Installing transformers-compat-0.6.6 (lib) Downloaded conduit-extra-1.3.5 Downloading attoparsec-iso8601-1.0.2.0 Completed transformers-compat-0.6.6 (lib) Starting old-time-1.1.0.3 (all, legacy fallback) Downloaded attoparsec-iso8601-1.0.2.0 Downloading http-api-data-0.4.3 Downloaded http-api-data-0.4.3 Downloading postgresql-libpq-0.9.4.3 Downloaded postgresql-libpq-0.9.4.3 Downloading postgresql-simple-0.6.4 Installing path-pieces-0.2.1 (lib) Completed path-pieces-0.2.1 (lib) Starting time-compat-1.9.6 (lib) Downloaded postgresql-simple-0.6.4 Downloading stm-chans-3.0.0.4 Installing cookie-0.4.5 (lib) Downloaded stm-chans-3.0.0.4 Downloading monad-logger-0.3.36 Starting stm-chans-3.0.0.4 (all, legacy fallback) Installing utf8-string-1.0.2 (lib) Completed cookie-0.4.5 (lib) Starting async-2.2.3 (lib) Building time-compat-1.9.6 (lib) Completed utf8-string-1.0.2 (lib) Starting unordered-containers-0.2.14.0 (lib) Downloaded monad-logger-0.3.36 Downloading persistent-2.13.1.1 Downloaded persistent-2.13.1.1 Downloading persistent-postgresql-2.13.0.3 Building async-2.2.3 (lib) Building unordered-containers-0.2.14.0 (lib) Downloaded persistent-postgresql-2.13.0.3 Building old-time-1.1.0.3 (all, legacy fallback) Installing async-2.2.3 (lib) Installing primitive-0.7.1.0 (lib) Completed async-2.2.3 (lib) Starting data-fix-0.3.1 (lib) Completed primitive-0.7.1.0 (lib) Starting case-insensitive-1.2.1.0 (lib) Building data-fix-0.3.1 (lib) Building case-insensitive-1.2.1.0 (lib) Building stm-chans-3.0.0.4 (all, legacy fallback) Installing th-abstraction-0.4.2.0 (lib) Completed th-abstraction-0.4.2.0 (lib) Starting postgresql-libpq-0.9.4.3 (all, legacy fallback) Installing case-insensitive-1.2.1.0 (lib) Installing data-fix-0.3.1 (lib) Completed case-insensitive-1.2.1.0 (lib) Starting network-3.1.2.2 (all, legacy fallback) Completed data-fix-0.3.1 (lib) Starting random-1.2.0 (lib) Installing zlib-0.6.2.3 (lib) Completed zlib-0.6.2.3 (lib) Starting base-compat-batteries-0.11.2 (lib) Building random-1.2.0 (lib) Building base-compat-batteries-0.11.2 (lib) Installing old-time-1.1.0.3 (all, legacy fallback) Installing time-compat-1.9.6 (lib) Installing stm-chans-3.0.0.4 (all, legacy fallback) Completed old-time-1.1.0.3 (all, legacy fallback) Starting blaze-markup-0.8.2.8 (lib) Completed time-compat-1.9.6 (lib) Starting distributive-0.6.2.1 (lib) Completed stm-chans-3.0.0.4 (all, legacy fallback) Building blaze-markup-0.8.2.8 (lib) Starting transformers-base-0.4.5.2 (lib) Building distributive-0.6.2.1 (lib) Building transformers-base-0.4.5.2 (lib) Building postgresql-libpq-0.9.4.3 (all, legacy fallback) Installing distributive-0.6.2.1 (lib) Installing transformers-base-0.4.5.2 (lib) Building network-3.1.2.2 (all, legacy fallback) Completed distributive-0.6.2.1 (lib) Starting string-conversions-0.4.0.1 (lib) Completed transformers-base-0.4.5.2 (lib) Starting typed-process-0.2.6.0 (lib) Building string-conversions-0.4.0.1 (lib) Building typed-process-0.2.6.0 (lib) Installing string-conversions-0.4.0.1 (lib) Completed string-conversions-0.4.0.1 (lib) Starting unliftio-0.2.18 (lib) Building unliftio-0.2.18 (lib) Installing typed-process-0.2.6.0 (lib) Completed typed-process-0.2.6.0 (lib) Starting vector-0.12.3.0 (lib) Building vector-0.12.3.0 (lib) Installing postgresql-libpq-0.9.4.3 (all, legacy fallback) Completed postgresql-libpq-0.9.4.3 (all, legacy fallback) Starting scientific-0.3.7.0 (lib) Building scientific-0.3.7.0 (lib) Installing blaze-markup-0.8.2.8 (lib) Completed blaze-markup-0.8.2.8 (lib) Starting resourcet-1.2.4.2 (lib) Installing random-1.2.0 (lib) Building resourcet-1.2.4.2 (lib) Completed random-1.2.0 (lib) Starting th-lift-0.8.2 (lib) Building th-lift-0.8.2 (lib) Installing unordered-containers-0.2.14.0 (lib) Completed unordered-containers-0.2.14.0 (lib) Starting http-types-0.12.3 (lib) Building http-types-0.12.3 (lib) Installing th-lift-0.8.2 (lib) Completed th-lift-0.8.2 (lib) Starting unix-time-0.4.7 (all, legacy fallback) Installing base-compat-batteries-0.11.2 (lib) Installing resourcet-1.2.4.2 (lib) Completed base-compat-batteries-0.11.2 (lib) Starting comonad-5.0.8 (lib) Completed resourcet-1.2.4.2 (lib) Starting monad-control-1.0.2.3 (all, legacy fallback) Building comonad-5.0.8 (lib) Building monad-control-1.0.2.3 (all, legacy fallback) Installing unliftio-0.2.18 (lib) Installing monad-control-1.0.2.3 (all, legacy fallback) Completed unliftio-0.2.18 (lib) Starting blaze-html-0.9.1.2 (lib) Building unix-time-0.4.7 (all, legacy fallback) Completed monad-control-1.0.2.3 (all, legacy fallback) Starting uuid-types-1.0.5 (lib) Building blaze-html-0.9.1.2 (lib) Building uuid-types-1.0.5 (lib) Installing scientific-0.3.7.0 (lib) Completed scientific-0.3.7.0 (lib) Starting lifted-base-0.2.3.12 (lib) Building lifted-base-0.2.3.12 (lib) Installing network-3.1.2.2 (all, legacy fallback) Completed network-3.1.2.2 (all, legacy fallback) Installing http-types-0.12.3 (lib) Installing unix-time-0.4.7 (all, legacy fallback) Starting attoparsec-0.14.1 (lib) Completed http-types-0.12.3 (lib) Starting streaming-commons-0.2.2.1 (lib) Completed unix-time-0.4.7 (all, legacy fallback) Starting fast-logger-3.0.5 (lib) Building attoparsec-0.14.1 (lib) Building streaming-commons-0.2.2.1 (lib) Building fast-logger-3.0.5 (lib) Installing comonad-5.0.8 (lib) Completed comonad-5.0.8 (lib) Starting bifunctors-5.5.11 (lib) Installing lifted-base-0.2.3.12 (lib) Completed lifted-base-0.2.3.12 (lib) Installing uuid-types-1.0.5 (lib) Completed uuid-types-1.0.5 (lib) Building bifunctors-5.5.11 (lib) Installing fast-logger-3.0.5 (lib) Completed fast-logger-3.0.5 (lib) Installing streaming-commons-0.2.2.1 (lib) Completed streaming-commons-0.2.2.1 (lib) Installing bifunctors-5.5.11 (lib) Completed bifunctors-5.5.11 (lib) Starting assoc-1.0.2 (lib) Building assoc-1.0.2 (lib) Installing assoc-1.0.2 (lib) Completed assoc-1.0.2 (lib) Starting these-1.1.1.1 (lib) Building these-1.1.1.1 (lib) Installing these-1.1.1.1 (lib) Completed these-1.1.1.1 (lib) Starting strict-0.4.0.1 (lib) Building strict-0.4.0.1 (lib) Installing blaze-html-0.9.1.2 (lib) Completed blaze-html-0.9.1.2 (lib) Installing strict-0.4.0.1 (lib) Completed strict-0.4.0.1 (lib) Installing attoparsec-0.14.1 (lib) Completed attoparsec-0.14.1 (lib) Starting attoparsec-iso8601-1.0.2.0 (lib) Building attoparsec-iso8601-1.0.2.0 (lib) Installing attoparsec-iso8601-1.0.2.0 (lib) Completed attoparsec-iso8601-1.0.2.0 (lib) Starting http-api-data-0.4.3 (lib) Building http-api-data-0.4.3 (lib) Installing http-api-data-0.4.3 (lib) Completed http-api-data-0.4.3 (lib) Installing vector-0.12.3.0 (lib) Completed vector-0.12.3.0 (lib) Starting th-lift-instances-0.1.18 (lib) Starting resource-pool-0.2.3.2 (lib) Starting vector-algorithms-0.8.0.4 (lib) Starting aeson-1.5.6.0 (lib) Building vector-algorithms-0.8.0.4 (lib) Building resource-pool-0.2.3.2 (lib) Building th-lift-instances-0.1.18 (lib) Building aeson-1.5.6.0 (lib) Installing th-lift-instances-0.1.18 (lib) Completed th-lift-instances-0.1.18 (lib) Installing resource-pool-0.2.3.2 (lib) Completed resource-pool-0.2.3.2 (lib) Installing vector-algorithms-0.8.0.4 (lib) Completed vector-algorithms-0.8.0.4 (lib) Starting mono-traversable-1.0.15.1 (lib) Building mono-traversable-1.0.15.1 (lib) Installing mono-traversable-1.0.15.1 (lib) Completed mono-traversable-1.0.15.1 (lib) Starting conduit-1.3.4.1 (lib) Building conduit-1.3.4.1 (lib) Installing conduit-1.3.4.1 (lib) Completed conduit-1.3.4.1 (lib) Starting conduit-extra-1.3.5 (lib) Building conduit-extra-1.3.5 (lib) Installing conduit-extra-1.3.5 (lib) Completed conduit-extra-1.3.5 (lib) Starting monad-logger-0.3.36 (lib) Building monad-logger-0.3.36 (lib) Installing monad-logger-0.3.36 (lib) Completed monad-logger-0.3.36 (lib) Installing aeson-1.5.6.0 (lib) Completed aeson-1.5.6.0 (lib) Starting postgresql-simple-0.6.4 (lib) Starting persistent-2.13.1.1 (lib) Building persistent-2.13.1.1 (lib) Building postgresql-simple-0.6.4 (lib) Installing postgresql-simple-0.6.4 (lib) Completed postgresql-simple-0.6.4 (lib) Installing persistent-2.13.1.1 (lib) Completed persistent-2.13.1.1 (lib) Starting persistent-postgresql-2.13.0.3 (lib) Building persistent-postgresql-2.13.0.3 (lib) Installing persistent-postgresql-2.13.0.3 (lib) Completed persistent-postgresql-2.13.0.3 (lib) Warning: @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ WARNING: Installation might not be completed as desired! @ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ The command "cabal install [TARGETS]" doesn't expose libraries. * You might have wanted to add them as dependencies to your package. In this case add "persistent-postgresql" to the build-depends field(s) of your package's .cabal file. * You might have wanted to add them to a GHC environment. In this case use "cabal install --lib persistent-postgresql". The "--lib" flag is provisional: see https://github.com/haskell/cabal/issues/6481 for more information. bmaxa at Branimirs-Air ~ % cabal install --lib persistent-postgresql Warning: The package list for 'hackage.haskell.org' is 69 days old. Run 'cabal update' to get the latest list of available packages. Warning: The package list for 'hackage.haskell.org' is 69 days old. Run 'cabal update' to get the latest list of available packages. Resolving dependencies... Up to date bmaxa at Branimirs-Air ~ % Greetings, Branimir. > On 21.09.2021., at 22:59, Geraldus wrote: > > Thank you for your response. > > I use 13.4: > > ``` > arthurfayzrakhmanov at MacBook-Pro-Arthur ~/L/h/pg001> brew search postgres > ==> Formulae > check_postgres postgresql at 11 postgresql at 9.5 qt-postgresql > postgresql ✔ postgresql at 12 postgresql at 9.6 postgis > postgresql at 10 postgresql at 9.4 postgrest > ==> Casks > navicat-for-postgresql postgrespreferencepane > postgres-unofficial sqlpro-for-postgres > arthurfayzrakhmanov at MacBook-Pro-Arthur ~/L/h/pg001> psql --version > psql (PostgreSQL) 13.4 > ``` > > ср, 22 сент. 2021 г. в 01:55, Branimir Maksimovic >: > which version of postgresql you are using? > bmaxa at Branimirs-Air ~ % brew search postgres > ==> Formulae > check_postgres postgresql at 10 postgresql at 12 postgresql at 9.5 postgrest postgis > postgresql postgresql at 11 postgresql at 9.4 postgresql at 9.6 qt-postgresql > ==> Casks > navicat-for-postgresql postgres-unofficial postgrespreferencepane sqlpro-for-postgres > > ? > > Greetings, Branimir. > >> On 21.09.2021., at 22:47, Geraldus > wrote: >> >> Hi, dear Cafe! >> >> I'm having trouble compiling an application which uses PostgreSQL on a macbook with an M1 chip. >> >> Postgre itself seems to work fine. It is installed via `homebrew` (if I'm not mistaken this is the only way on Mac to get pg_config, which is required for `persistent-postgresql`). The error message is following: >> >> ``` >> persistent-postgresql> : dlopen(/Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib, 5): Symbol not found: _PQclear >> persistent-postgresql> Referenced from: /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib >> persistent-postgresql> Expected in: flat namespace >> persistent-postgresql> in /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib >> ``` >> >> The minimal setup to reproduce is following: >> >> ``` >> dependencies: >> - base >= 4.7 && < 5 >> - persistent >= 2.13.1.2 && < 3 >> - persistent-postgresql >= 2.13.1.0 && < 3 >> ``` >> >> Digging around gave me just a few clues. It seems that `libpq` I have is compiled some other way it expected, and missing some symbols required `persistent-postgresql` to work. I believe this is not a bug, rather that a local configuration issue. >> >> Does anyone know which is right setup to build persistent-postgresql on Macs with M1 chip? Thanks in advance. >> >> Sincerely. >> Arthur. >> >> P.S. Please apologize if this is not a right place to ask such questions. Asked already in Yesod Google Groups and Stack Overflow. But didn't received any feedback. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From heraldhoi at gmail.com Tue Sep 21 22:12:14 2021 From: heraldhoi at gmail.com (Geraldus) Date: Wed, 22 Sep 2021 03:12:14 +0500 Subject: [Haskell-cafe] Troubles with PostgreSQL, Persistent and Apple M1 In-Reply-To: References: Message-ID: Awesome, thanks! I got used to relying on stack and not installing system-wide GHC. Is it possible to achieve the same with `stack`? ср, 22 сент. 2021 г. в 03:08, Branimir Maksimovic < branimir.maksimovic at gmail.com>: > Seems builds no problem… > To start postgresql: > brew services start postgresql > Or, if you don't want/need a background service you can just run: > /opt/homebrew/opt/postgresql/bin/postgres -D /opt/homebrew/var/postgres > bmaxa at Branimirs-Air ~ % cabal install persistent-postgresql > Warning: The package list for 'hackage.haskell.org' is 69 days old. > Run 'cabal update' to get the latest list of available packages. > Warning: The package list for 'hackage.haskell.org' is 69 days old. > Run 'cabal update' to get the latest list of available packages. > Resolving dependencies... > Build profile: -w ghc-8.10.7 -O1 > In order, the following will be built (use -v for more details): > - Only-0.1 (lib) (requires build) > - blaze-builder-0.4.2.1 (lib) (requires download & build) > - base-compat-0.11.2 (lib) (requires build) > - base-orphans-0.8.4 (lib) (requires build) > - base64-bytestring-1.2.0.1 (lib) (requires download & build) > - bytestring-builder-0.10.8.2.0 (lib) (requires download & build) > - dlist-1.0 (lib) (requires build) > - data-default-class-0.1.2.0 (lib:data-default-class) (requires build) > - hsc2hs-0.68.7 (exe:hsc2hs) (requires build) > - hashable-1.3.2.0 (lib) (requires build) > - old-locale-1.0.0.7 (lib) (requires download & build) > - lift-type-0.1.0.1 (lib) (requires download & build) > - monad-loops-0.4.3 (lib) (requires download & build) > - indexed-traversable-0.1.1 (lib) (requires build) > - unliftio-core-0.2.0.1 (lib) (requires download & build) > - integer-logarithms-1.0.3.1 (lib) (requires build) > - unix-compat-0.5.3 (lib) (requires download & build) > - primitive-0.7.1.0 (lib) (requires build) > - path-pieces-0.2.1 (lib) (requires download & build) > - silently-1.2.5.1 (lib) (requires download & build) > - split-0.2.3.4 (lib) (requires download & build) > - splitmix-0.1.0.3 (lib) (requires build) > - stm-chans-3.0.0.4 (lib:stm-chans) (requires download & build) > - easy-file-0.2.2 (lib:easy-file) (requires download & build) > - auto-update-0.1.6 (lib) (requires download & build) > - utf8-string-1.0.2 (lib) (requires download & build) > - tagged-0.8.6.1 (lib) (requires build) > - th-abstraction-0.4.2.0 (lib) (requires build) > - transformers-compat-0.6.6 (lib) (requires build) > - zlib-0.6.2.3 (lib) (requires download & build) > - blaze-markup-0.8.2.8 (lib) (requires download & build) > - base-compat-batteries-0.11.2 (lib) (requires build) > - cookie-0.4.5 (lib) (requires download & build) > - postgresql-libpq-0.9.4.3 (lib:postgresql-libpq) (requires download & > build) > - network-3.1.2.2 (lib:network) (requires download & build) > - time-compat-1.9.6 (lib) (requires build) > - async-2.2.3 (lib) (requires build) > - unordered-containers-0.2.14.0 (lib) (requires build) > - data-fix-0.3.1 (lib) (requires build) > - case-insensitive-1.2.1.0 (lib) (requires download & build) > - old-time-1.1.0.3 (lib:old-time) (requires download & build) > - vector-0.12.3.0 (lib) (requires build) > - scientific-0.3.7.0 (lib) (requires build) > - resourcet-1.2.4.2 (lib) (requires download & build) > - random-1.2.0 (lib) (requires build) > - string-conversions-0.4.0.1 (lib) (requires download & build) > - distributive-0.6.2.1 (lib) (requires build) > - th-lift-0.8.2 (lib) (requires download & build) > - transformers-base-0.4.5.2 (lib) (requires download & build) > - blaze-html-0.9.1.2 (lib) (requires download & build) > - typed-process-0.2.6.0 (lib) (requires download & build) > - unliftio-0.2.18 (lib) (requires download & build) > - http-types-0.12.3 (lib) (requires download & build) > - unix-time-0.4.7 (lib:unix-time) (requires download & build) > - vector-algorithms-0.8.0.4 (lib) (requires build) > - attoparsec-0.14.1 (lib) (requires build) > - streaming-commons-0.2.2.1 (lib) (requires download & build) > - uuid-types-1.0.5 (lib) (requires build) > - comonad-5.0.8 (lib) (requires build) > - th-lift-instances-0.1.18 (lib) (requires download & build) > - monad-control-1.0.2.3 (lib:monad-control) (requires download & build) > - fast-logger-3.0.5 (lib) (requires download & build) > - mono-traversable-1.0.15.1 (lib) (requires download & build) > - attoparsec-iso8601-1.0.2.0 (lib) (requires download & build) > - bifunctors-5.5.11 (lib) (requires build) > - resource-pool-0.2.3.2 (lib) (requires download & build) > - lifted-base-0.2.3.12 (lib) (requires download & build) > - conduit-1.3.4.1 (lib) (requires download & build) > - http-api-data-0.4.3 (lib) (requires download & build) > - assoc-1.0.2 (lib) (requires build) > - conduit-extra-1.3.5 (lib) (requires download & build) > - these-1.1.1.1 (lib) (requires build) > - monad-logger-0.3.36 (lib) (requires download & build) > - strict-0.4.0.1 (lib) (requires build) > - aeson-1.5.6.0 (lib) (requires build) > - postgresql-simple-0.6.4 (lib) (requires download & build) > - persistent-2.13.1.1 (lib) (requires download & build) > - persistent-postgresql-2.13.0.3 (lib) (requires download & build) > Downloading old-locale-1.0.0.7 > Starting base-orphans-0.8.4 (lib) > Starting data-default-class-0.1.2.0 (all, legacy fallback) > Starting dlist-1.0 (lib) > Starting Only-0.1 (lib) > Starting base-compat-0.11.2 (lib) > Building dlist-1.0 (lib) > Building data-default-class-0.1.2.0 (all, legacy fallback) > Building base-compat-0.11.2 (lib) > Building base-orphans-0.8.4 (lib) > Building Only-0.1 (lib) > Downloaded old-locale-1.0.0.7 > Downloading old-time-1.1.0.3 > Installing data-default-class-0.1.2.0 (all, legacy fallback) > Installing Only-0.1 (lib) > Completed data-default-class-0.1.2.0 (all, legacy fallback) > Starting hsc2hs-0.68.7 (exe:hsc2hs) > Downloaded old-time-1.1.0.3 > Downloading monad-loops-0.4.3 > Completed Only-0.1 (lib) > Starting hashable-1.3.2.0 (lib) > Downloaded monad-loops-0.4.3 > Downloading split-0.2.3.4 > Building hsc2hs-0.68.7 (exe:hsc2hs) > Building hashable-1.3.2.0 (lib) > Downloaded split-0.2.3.4 > Downloading auto-update-0.1.6 > Downloaded auto-update-0.1.6 > Downloading unliftio-core-0.2.0.1 > Downloaded unliftio-core-0.2.0.1 > Downloading base64-bytestring-1.2.0.1 > Installing dlist-1.0 (lib) > Completed dlist-1.0 (lib) > Starting old-locale-1.0.0.7 (lib) > Downloaded base64-bytestring-1.2.0.1 > Downloading utf8-string-1.0.2 > Starting base64-bytestring-1.2.0.1 (lib) > Building old-locale-1.0.0.7 (lib) > Downloaded utf8-string-1.0.2 > Downloading zlib-0.6.2.3 > Building base64-bytestring-1.2.0.1 (lib) > Installing base-orphans-0.8.4 (lib) > Downloaded zlib-0.6.2.3 > Downloading bytestring-builder-0.10.8.2.0 > Completed base-orphans-0.8.4 (lib) > Installing old-locale-1.0.0.7 (lib) > Downloaded bytestring-builder-0.10.8.2.0 > Downloading lift-type-0.1.0.1 > Starting bytestring-builder-0.10.8.2.0 (lib) > Installing hashable-1.3.2.0 (lib) > Completed old-locale-1.0.0.7 (lib) > Starting monad-loops-0.4.3 (lib) > Completed hashable-1.3.2.0 (lib) > Starting indexed-traversable-0.1.1 (lib) > Downloaded lift-type-0.1.0.1 > Downloading th-lift-0.8.2 > Building bytestring-builder-0.10.8.2.0 (lib) > Starting lift-type-0.1.0.1 (lib) > Installing bytestring-builder-0.10.8.2.0 (lib) > Building monad-loops-0.4.3 (lib) > Completed bytestring-builder-0.10.8.2.0 (lib) > Starting unliftio-core-0.2.0.1 (lib) > Building indexed-traversable-0.1.1 (lib) > Downloaded th-lift-0.8.2 > Downloading silently-1.2.5.1 > Building lift-type-0.1.0.1 (lib) > Installing base64-bytestring-1.2.0.1 (lib) > Building unliftio-core-0.2.0.1 (lib) > Completed base64-bytestring-1.2.0.1 (lib) > Starting integer-logarithms-1.0.3.1 (lib) > Downloaded silently-1.2.5.1 > Downloading unix-compat-0.5.3 > Installing lift-type-0.1.0.1 (lib) > Completed lift-type-0.1.0.1 (lib) > Downloaded unix-compat-0.5.3 > Downloading network-3.1.2.2 > Building integer-logarithms-1.0.3.1 (lib) > Starting unix-compat-0.5.3 (lib) > Installing unliftio-core-0.2.0.1 (lib) > Completed unliftio-core-0.2.0.1 (lib) > Starting primitive-0.7.1.0 (lib) > Downloaded network-3.1.2.2 > Downloading unix-time-0.4.7 > Building unix-compat-0.5.3 (lib) > Installing monad-loops-0.4.3 (lib) > Completed monad-loops-0.4.3 (lib) > Building primitive-0.7.1.0 (lib) > Downloaded unix-time-0.4.7 > Downloading easy-file-0.2.2 > Downloaded easy-file-0.2.2 > Downloading resourcet-1.2.4.2 > Downloaded resourcet-1.2.4.2 > Downloading transformers-base-0.4.5.2 > Installing integer-logarithms-1.0.3.1 (lib) > Completed integer-logarithms-1.0.3.1 (lib) > Starting silently-1.2.5.1 (lib) > Downloaded transformers-base-0.4.5.2 > Downloading monad-control-1.0.2.3 > Installing unix-compat-0.5.3 (lib) > Building silently-1.2.5.1 (lib) > Completed unix-compat-0.5.3 (lib) > Starting split-0.2.3.4 (lib) > Downloaded monad-control-1.0.2.3 > Downloading lifted-base-0.2.3.12 > Downloaded lifted-base-0.2.3.12 > Downloading blaze-builder-0.4.2.1 > Installing silently-1.2.5.1 (lib) > Building split-0.2.3.4 (lib) > Completed silently-1.2.5.1 (lib) > Starting splitmix-0.1.0.3 (lib) > Installing hsc2hs-0.68.7 (exe:hsc2hs) > Downloaded blaze-builder-0.4.2.1 > Downloading blaze-markup-0.8.2.8 > Completed hsc2hs-0.68.7 (exe:hsc2hs) > Starting blaze-builder-0.4.2.1 (lib) > Building splitmix-0.1.0.3 (lib) > Downloaded blaze-markup-0.8.2.8 > Downloading blaze-html-0.9.1.2 > Installing indexed-traversable-0.1.1 (lib) > Building blaze-builder-0.4.2.1 (lib) > Completed indexed-traversable-0.1.1 (lib) > Starting easy-file-0.2.2 (all, legacy fallback) > Downloaded blaze-html-0.9.1.2 > Downloading cookie-0.4.5 > Installing split-0.2.3.4 (lib) > Completed split-0.2.3.4 (lib) > Starting auto-update-0.1.6 (lib) > Building easy-file-0.2.2 (all, legacy fallback) > Downloaded cookie-0.4.5 > Downloading fast-logger-3.0.5 > Building auto-update-0.1.6 (lib) > Downloaded fast-logger-3.0.5 > Downloading case-insensitive-1.2.1.0 > Downloaded case-insensitive-1.2.1.0 > Downloading resource-pool-0.2.3.2 > Installing splitmix-0.1.0.3 (lib) > Installing base-compat-0.11.2 (lib) > Completed splitmix-0.1.0.3 (lib) > Starting utf8-string-1.0.2 (lib) > Completed base-compat-0.11.2 (lib) > Starting tagged-0.8.6.1 (lib) > Installing easy-file-0.2.2 (all, legacy fallback) > Downloaded resource-pool-0.2.3.2 > Downloading unliftio-0.2.18 > Completed easy-file-0.2.2 (all, legacy fallback) > Starting th-abstraction-0.4.2.0 (lib) > Installing auto-update-0.1.6 (lib) > Building utf8-string-1.0.2 (lib) > Completed auto-update-0.1.6 (lib) > Starting transformers-compat-0.6.6 (lib) > Building tagged-0.8.6.1 (lib) > Downloaded unliftio-0.2.18 > Downloading typed-process-0.2.6.0 > Building th-abstraction-0.4.2.0 (lib) > Downloaded typed-process-0.2.6.0 > Downloading http-types-0.12.3 > Building transformers-compat-0.6.6 (lib) > Downloaded http-types-0.12.3 > Downloading mono-traversable-1.0.15.1 > Downloaded mono-traversable-1.0.15.1 > Downloading conduit-1.3.4.1 > Downloaded conduit-1.3.4.1 > Downloading path-pieces-0.2.1 > Downloaded path-pieces-0.2.1 > Downloading streaming-commons-0.2.2.1 > Starting path-pieces-0.2.1 (lib) > Installing blaze-builder-0.4.2.1 (lib) > Downloaded streaming-commons-0.2.2.1 > Downloading string-conversions-0.4.0.1 > Completed blaze-builder-0.4.2.1 (lib) > Installing tagged-0.8.6.1 (lib) > Starting zlib-0.6.2.3 (lib) > Completed tagged-0.8.6.1 (lib) > Starting cookie-0.4.5 (lib) > Building path-pieces-0.2.1 (lib) > Downloaded string-conversions-0.4.0.1 > Downloading th-lift-instances-0.1.18 > Downloaded th-lift-instances-0.1.18 > Downloading conduit-extra-1.3.5 > Building zlib-0.6.2.3 (lib) > Building cookie-0.4.5 (lib) > Installing transformers-compat-0.6.6 (lib) > Downloaded conduit-extra-1.3.5 > Downloading attoparsec-iso8601-1.0.2.0 > Completed transformers-compat-0.6.6 (lib) > Starting old-time-1.1.0.3 (all, legacy fallback) > Downloaded attoparsec-iso8601-1.0.2.0 > Downloading http-api-data-0.4.3 > Downloaded http-api-data-0.4.3 > Downloading postgresql-libpq-0.9.4.3 > Downloaded postgresql-libpq-0.9.4.3 > Downloading postgresql-simple-0.6.4 > Installing path-pieces-0.2.1 (lib) > Completed path-pieces-0.2.1 (lib) > Starting time-compat-1.9.6 (lib) > Downloaded postgresql-simple-0.6.4 > Downloading stm-chans-3.0.0.4 > Installing cookie-0.4.5 (lib) > Downloaded stm-chans-3.0.0.4 > Downloading monad-logger-0.3.36 > Starting stm-chans-3.0.0.4 (all, legacy fallback) > Installing utf8-string-1.0.2 (lib) > Completed cookie-0.4.5 (lib) > Starting async-2.2.3 (lib) > Building time-compat-1.9.6 (lib) > Completed utf8-string-1.0.2 (lib) > Starting unordered-containers-0.2.14.0 (lib) > Downloaded monad-logger-0.3.36 > Downloading persistent-2.13.1.1 > Downloaded persistent-2.13.1.1 > Downloading persistent-postgresql-2.13.0.3 > Building async-2.2.3 (lib) > Building unordered-containers-0.2.14.0 (lib) > Downloaded persistent-postgresql-2.13.0.3 > Building old-time-1.1.0.3 (all, legacy fallback) > Installing async-2.2.3 (lib) > Installing primitive-0.7.1.0 (lib) > Completed async-2.2.3 (lib) > Starting data-fix-0.3.1 (lib) > Completed primitive-0.7.1.0 (lib) > Starting case-insensitive-1.2.1.0 (lib) > Building data-fix-0.3.1 (lib) > Building case-insensitive-1.2.1.0 (lib) > Building stm-chans-3.0.0.4 (all, legacy fallback) > Installing th-abstraction-0.4.2.0 (lib) > Completed th-abstraction-0.4.2.0 (lib) > Starting postgresql-libpq-0.9.4.3 (all, legacy fallback) > Installing case-insensitive-1.2.1.0 (lib) > Installing data-fix-0.3.1 (lib) > Completed case-insensitive-1.2.1.0 (lib) > Starting network-3.1.2.2 (all, legacy fallback) > Completed data-fix-0.3.1 (lib) > Starting random-1.2.0 (lib) > Installing zlib-0.6.2.3 (lib) > Completed zlib-0.6.2.3 (lib) > Starting base-compat-batteries-0.11.2 (lib) > Building random-1.2.0 (lib) > Building base-compat-batteries-0.11.2 (lib) > Installing old-time-1.1.0.3 (all, legacy fallback) > Installing time-compat-1.9.6 (lib) > Installing stm-chans-3.0.0.4 (all, legacy fallback) > Completed old-time-1.1.0.3 (all, legacy fallback) > Starting blaze-markup-0.8.2.8 (lib) > Completed time-compat-1.9.6 (lib) > Starting distributive-0.6.2.1 (lib) > Completed stm-chans-3.0.0.4 (all, legacy fallback) > Building blaze-markup-0.8.2.8 (lib) > Starting transformers-base-0.4.5.2 (lib) > Building distributive-0.6.2.1 (lib) > Building transformers-base-0.4.5.2 (lib) > Building postgresql-libpq-0.9.4.3 (all, legacy fallback) > Installing distributive-0.6.2.1 (lib) > Installing transformers-base-0.4.5.2 (lib) > Building network-3.1.2.2 (all, legacy fallback) > Completed distributive-0.6.2.1 (lib) > Starting string-conversions-0.4.0.1 (lib) > Completed transformers-base-0.4.5.2 (lib) > Starting typed-process-0.2.6.0 (lib) > Building string-conversions-0.4.0.1 (lib) > Building typed-process-0.2.6.0 (lib) > Installing string-conversions-0.4.0.1 (lib) > Completed string-conversions-0.4.0.1 (lib) > Starting unliftio-0.2.18 (lib) > Building unliftio-0.2.18 (lib) > Installing typed-process-0.2.6.0 (lib) > Completed typed-process-0.2.6.0 (lib) > Starting vector-0.12.3.0 (lib) > Building vector-0.12.3.0 (lib) > Installing postgresql-libpq-0.9.4.3 (all, legacy fallback) > Completed postgresql-libpq-0.9.4.3 (all, legacy fallback) > Starting scientific-0.3.7.0 (lib) > Building scientific-0.3.7.0 (lib) > Installing blaze-markup-0.8.2.8 (lib) > Completed blaze-markup-0.8.2.8 (lib) > Starting resourcet-1.2.4.2 (lib) > Installing random-1.2.0 (lib) > Building resourcet-1.2.4.2 (lib) > Completed random-1.2.0 (lib) > Starting th-lift-0.8.2 (lib) > Building th-lift-0.8.2 (lib) > Installing unordered-containers-0.2.14.0 (lib) > Completed unordered-containers-0.2.14.0 (lib) > Starting http-types-0.12.3 (lib) > Building http-types-0.12.3 (lib) > Installing th-lift-0.8.2 (lib) > Completed th-lift-0.8.2 (lib) > Starting unix-time-0.4.7 (all, legacy fallback) > Installing base-compat-batteries-0.11.2 (lib) > Installing resourcet-1.2.4.2 (lib) > Completed base-compat-batteries-0.11.2 (lib) > Starting comonad-5.0.8 (lib) > Completed resourcet-1.2.4.2 (lib) > Starting monad-control-1.0.2.3 (all, legacy fallback) > Building comonad-5.0.8 (lib) > Building monad-control-1.0.2.3 (all, legacy fallback) > Installing unliftio-0.2.18 (lib) > Installing monad-control-1.0.2.3 (all, legacy fallback) > Completed unliftio-0.2.18 (lib) > Starting blaze-html-0.9.1.2 (lib) > Building unix-time-0.4.7 (all, legacy fallback) > Completed monad-control-1.0.2.3 (all, legacy fallback) > Starting uuid-types-1.0.5 (lib) > Building blaze-html-0.9.1.2 (lib) > Building uuid-types-1.0.5 (lib) > Installing scientific-0.3.7.0 (lib) > Completed scientific-0.3.7.0 (lib) > Starting lifted-base-0.2.3.12 (lib) > Building lifted-base-0.2.3.12 (lib) > Installing network-3.1.2.2 (all, legacy fallback) > Completed network-3.1.2.2 (all, legacy fallback) > Installing http-types-0.12.3 (lib) > Installing unix-time-0.4.7 (all, legacy fallback) > Starting attoparsec-0.14.1 (lib) > Completed http-types-0.12.3 (lib) > Starting streaming-commons-0.2.2.1 (lib) > Completed unix-time-0.4.7 (all, legacy fallback) > Starting fast-logger-3.0.5 (lib) > Building attoparsec-0.14.1 (lib) > Building streaming-commons-0.2.2.1 (lib) > Building fast-logger-3.0.5 (lib) > Installing comonad-5.0.8 (lib) > Completed comonad-5.0.8 (lib) > Starting bifunctors-5.5.11 (lib) > Installing lifted-base-0.2.3.12 (lib) > Completed lifted-base-0.2.3.12 (lib) > Installing uuid-types-1.0.5 (lib) > Completed uuid-types-1.0.5 (lib) > Building bifunctors-5.5.11 (lib) > Installing fast-logger-3.0.5 (lib) > Completed fast-logger-3.0.5 (lib) > Installing streaming-commons-0.2.2.1 (lib) > Completed streaming-commons-0.2.2.1 (lib) > Installing bifunctors-5.5.11 (lib) > Completed bifunctors-5.5.11 (lib) > Starting assoc-1.0.2 (lib) > Building assoc-1.0.2 (lib) > Installing assoc-1.0.2 (lib) > Completed assoc-1.0.2 (lib) > Starting these-1.1.1.1 (lib) > Building these-1.1.1.1 (lib) > Installing these-1.1.1.1 (lib) > Completed these-1.1.1.1 (lib) > Starting strict-0.4.0.1 (lib) > Building strict-0.4.0.1 (lib) > Installing blaze-html-0.9.1.2 (lib) > Completed blaze-html-0.9.1.2 (lib) > Installing strict-0.4.0.1 (lib) > Completed strict-0.4.0.1 (lib) > Installing attoparsec-0.14.1 (lib) > Completed attoparsec-0.14.1 (lib) > Starting attoparsec-iso8601-1.0.2.0 (lib) > Building attoparsec-iso8601-1.0.2.0 (lib) > Installing attoparsec-iso8601-1.0.2.0 (lib) > Completed attoparsec-iso8601-1.0.2.0 (lib) > Starting http-api-data-0.4.3 (lib) > Building http-api-data-0.4.3 (lib) > Installing http-api-data-0.4.3 (lib) > Completed http-api-data-0.4.3 (lib) > Installing vector-0.12.3.0 (lib) > Completed vector-0.12.3.0 (lib) > Starting th-lift-instances-0.1.18 (lib) > Starting resource-pool-0.2.3.2 (lib) > Starting vector-algorithms-0.8.0.4 (lib) > Starting aeson-1.5.6.0 (lib) > Building vector-algorithms-0.8.0.4 (lib) > Building resource-pool-0.2.3.2 (lib) > Building th-lift-instances-0.1.18 (lib) > Building aeson-1.5.6.0 (lib) > Installing th-lift-instances-0.1.18 (lib) > Completed th-lift-instances-0.1.18 (lib) > Installing resource-pool-0.2.3.2 (lib) > Completed resource-pool-0.2.3.2 (lib) > Installing vector-algorithms-0.8.0.4 (lib) > Completed vector-algorithms-0.8.0.4 (lib) > Starting mono-traversable-1.0.15.1 (lib) > Building mono-traversable-1.0.15.1 (lib) > Installing mono-traversable-1.0.15.1 (lib) > Completed mono-traversable-1.0.15.1 (lib) > Starting conduit-1.3.4.1 (lib) > Building conduit-1.3.4.1 (lib) > Installing conduit-1.3.4.1 (lib) > Completed conduit-1.3.4.1 (lib) > Starting conduit-extra-1.3.5 (lib) > Building conduit-extra-1.3.5 (lib) > Installing conduit-extra-1.3.5 (lib) > Completed conduit-extra-1.3.5 (lib) > Starting monad-logger-0.3.36 (lib) > Building monad-logger-0.3.36 (lib) > Installing monad-logger-0.3.36 (lib) > Completed monad-logger-0.3.36 (lib) > Installing aeson-1.5.6.0 (lib) > Completed aeson-1.5.6.0 (lib) > Starting postgresql-simple-0.6.4 (lib) > Starting persistent-2.13.1.1 (lib) > Building persistent-2.13.1.1 (lib) > Building postgresql-simple-0.6.4 (lib) > Installing postgresql-simple-0.6.4 (lib) > Completed postgresql-simple-0.6.4 (lib) > Installing persistent-2.13.1.1 (lib) > Completed persistent-2.13.1.1 (lib) > Starting persistent-postgresql-2.13.0.3 (lib) > Building persistent-postgresql-2.13.0.3 (lib) > Installing persistent-postgresql-2.13.0.3 (lib) > Completed persistent-postgresql-2.13.0.3 (lib) > Warning: > @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ > @ WARNING: Installation might not be completed as desired! @ > @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ > The command "cabal install [TARGETS]" doesn't expose libraries. > * You might have wanted to add them as dependencies to your package. In > this > case add "persistent-postgresql" to the build-depends field(s) of your > package's .cabal file. > * You might have wanted to add them to a GHC environment. In this case use > "cabal install --lib persistent-postgresql". The "--lib" flag is > provisional: > see https://github.com/haskell/cabal/issues/6481 for more information. > bmaxa at Branimirs-Air ~ % cabal install --lib persistent-postgresql > Warning: The package list for 'hackage.haskell.org' is 69 days old. > Run 'cabal update' to get the latest list of available packages. > Warning: The package list for 'hackage.haskell.org' is 69 days old. > Run 'cabal update' to get the latest list of available packages. > Resolving dependencies... > Up to date > bmaxa at Branimirs-Air ~ % > > Greetings, Branimir. > > On 21.09.2021., at 22:59, Geraldus wrote: > > Thank you for your response. > > I use 13.4: > > ``` > arthurfayzrakhmanov at MacBook-Pro-Arthur ~/L/h/pg001> brew search postgres > ==> Formulae > check_postgres postgresql at 11 postgresql at 9.5 qt-postgresql > postgresql ✔ postgresql at 12 postgresql at 9.6 postgis > postgresql at 10 postgresql at 9.4 postgrest > ==> Casks > navicat-for-postgresql postgrespreferencepane > postgres-unofficial sqlpro-for-postgres > arthurfayzrakhmanov at MacBook-Pro-Arthur ~/L/h/pg001> psql --version > psql (PostgreSQL) 13.4 > ``` > > ср, 22 сент. 2021 г. в 01:55, Branimir Maksimovic < > branimir.maksimovic at gmail.com>: > >> which version of postgresql you are using? >> bmaxa at Branimirs-Air ~ % brew search postgres >> ==> Formulae >> check_postgres postgresql at 10 postgresql at 12 >> postgresql at 9.5 postgrest >> postgis >> postgresql postgresql at 11 postgresql at 9.4 >> postgresql at 9.6 qt-postgresql >> ==> Casks >> navicat-for-postgresql postgres-unofficial >> postgrespreferencepane sqlpro-for-postgres >> >> ? >> >> Greetings, Branimir. >> >> On 21.09.2021., at 22:47, Geraldus wrote: >> >> Hi, dear Cafe! >> >> I'm having trouble compiling an application which uses PostgreSQL on a >> macbook with an M1 chip. >> >> Postgre itself seems to work fine. It is installed via `homebrew` (if >> I'm not mistaken this is the only way on Mac to get pg_config, which is >> required for `persistent-postgresql`). The error message is following: >> >> ``` >> persistent-postgresql> : >> dlopen(/Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib, >> 5): *Symbol not found: _PQclear* >> persistent-postgresql> Referenced from: >> /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib >> persistent-postgresql> *Expected in: flat namespace* >> persistent-postgresql> in >> /Users/arthurfayzrakhmanov/.stack/snapshots/x86_64-osx/36432054bd8d13c1da6134758733286b536c65d34222dcf10ecb29bd437c8117/8.10.7/lib/x86_64-osx-ghc-8.10.7/libHSpostgresql-libpq-0.9.4.3-GrxZELytXmSAOH6lAioiw9-ghc8.10.7.dylib >> ``` >> >> The minimal setup to reproduce is following: >> >> ``` >> dependencies: >> - base >= 4.7 && < 5 >> - persistent >= 2.13.1.2 && < 3 >> - persistent-postgresql >= 2.13.1.0 && < 3 >> ``` >> >> Digging around gave me just a few clues. It seems that `libpq` I have is >> compiled some other way it expected, and missing some symbols required >> `persistent-postgresql` to work. I believe this is not a bug, rather that >> a local configuration issue. >> >> Does anyone know which is right setup to build persistent-postgresql on >> Macs with M1 chip? Thanks in advance. >> >> Sincerely. >> Arthur. >> >> P.S. Please apologize if this is not a right place to ask such >> questions. Asked already in Yesod Google Groups and Stack Overflow. But >> didn't received any feedback. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. >> >> >> > -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Tue Sep 21 22:14:52 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Wed, 22 Sep 2021 00:14:52 +0200 Subject: [Haskell-cafe] Troubles with PostgreSQL, Persistent and Apple M1 In-Reply-To: References: Message-ID: Dunno, don’t know what is ’stack’ ? I am old school, don’t need crutches :P Greetings, Branimir. > On 22.09.2021., at 00:12, Geraldus wrote: > > Awesome, thanks! > > I got used to relying on stack and not installing system-wide GHC. Is it possible to achieve the same with `stack`? > From branimir.maksimovic at gmail.com Tue Sep 21 23:36:41 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Wed, 22 Sep 2021 01:36:41 +0200 Subject: [Haskell-cafe] I wish to share IRC bot C++ code and lib as needed, if interrested Message-ID: Collected hangman game and some from internet… Greetings, Branimir. -------- {-# Language ScopedTypeVariables,BangPatterns #-} import Sockets import Foreign.C.String import Data.List import Data.Char import Data.IORef import System.Random import Data.Time.Clock.POSIX import Control.Applicative ((<$>), (<*>)) import Text.Read import Text.Printf import Control.Monad (when) import Data.Char (toLower) import Data.List (transpose) import System.Random (randomIO) import System.IO.Unsafe import System.Mem import System.Process main = do pt <- getPOSIXTime let tm = round pt :: Int stdgen <- newIORef $ mkStdGen tm ref <- newIORef "" gen <-readIORef stdgen gsref <- newIORef $ fst $ newGame gen tm <- newIORef pt let myCallbacks = defaultCallbacks { done_connected = binded, done_reading = response_get tm ref stdgen gsref, done_writing = response_written, done_closed = \pl s -> do putStrLn "peer closed, reconnecting" s <- socket myCallbacks connect pl s "170.178.184.36:6667" return 1, handle_error = \pl s buf len-> do str <- peekCStringLen (buf,fromIntegral len) putStrLn $ "error "++str++", reconnecting" s <- socket myCallbacks connect pl s "170.178.184.36:6667" return 1, tick = binded_tick tm } s <- socket myCallbacks pl <- epoll 1000 connect pl s "170.178.184.36:6667" run_loop pl (-1) nick :: [StdGen] -> (String,[StdGen]) nick [gen] = let (s,gen') = randomR(0::Int,100) gen in ("zeka_bot_"++ show s,[gen']) nick [] = ("zeka_bot",[]) binded pl s = do let (s',_) = nick [] write pl s $ "NICK "++s'++"\r\n" return 0 binded_tick tm s = do t <- readIORef tm t' <- getPOSIXTime if (t'-t) > 900 then return 1 else return 0 list_zeka = [ "PRIVMSG #hr.soc.politika :OS ME TRTIS?\r\n", "PRIVMSG #hr.soc.politika :LJUCKA BEDA\r\n", "PRIVMSG #hr.soc.politika :OS?\r\n", "PRIVMSG #hr.soc.politika :NOMEN EST OMEN\r\n", "PRIVMSG #hr.soc.politika :DECAK MURAT\r\n", "PRIVMSG #hr.soc.politika :KULT JARCA\r\n", "PRIVMSG #hr.soc.politika :DAJ ME TRTI\r\n", "PRIVMSG #hr.soc.politika :KULT VAGINE\r\n", "PRIVMSG #hr.soc.politika :KULT PENISA\r\n", "PRIVMSG #hr.soc.politika :subice mi se moraju smesta podati!!!!!!!!!!!!\r\n", "PRIVMSG #hr.soc.politika :OS ME?\r\n", "PRIVMSG #hr.soc.politika :Zeka kakio, pa pasulj fini ždere a vešmašina veš lepo pere, yeeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :PRKNO\r\n", "PRIVMSG #hr.soc.politika :DAJ MENI\r\n", "PRIVMSG #hr.soc.politika :CELOVJEK DLAKUS\r\n", "PRIVMSG #hr.soc.politika :KAKIO SAM\r\n", "PRIVMSG #hr.soc.politika :GADE!!!\r\n", "PRIVMSG #hr.soc.politika :DAJ ME NABIJAJ JEBATE\r\n", "PRIVMSG #hr.soc.politika :DAJ ME JEBI\r\n", "PRIVMSG #hr.soc.politika :ZELIS ME GOLOG?\r\n", "PRIVMSG #hr.soc.politika :A sad opet pod deku....\r\n", "PRIVMSG #hr.soc.politika :Gentleman Dominant, to je moja titula, tako i izgledam, tako se i oblačim\r\n", "PRIVMSG #hr.soc.politika :Ja obožavam DREK\r\n", "PRIVMSG #hr.soc.politika :Konačno precima na grobu!!\r\n", "PRIVMSG #hr.soc.politika :Zeka sa drugarom prošo celi Mirogoj, yeeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :Lepo bi bilo da odem do Beograda za 10 dana\r\n", "PRIVMSG #hr.soc.politika :da pojebem srpske subice\r\n", "PRIVMSG #hr.soc.politika :Neka mi daju i dobru ženicu subicu, da mi rodi dečicu, yeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :zahvalio sam im na grobu\r\n", "PRIVMSG #hr.soc.politika :Jeste, duhovi predaka mi donose oporavak ovih dana\r\n", "PRIVMSG #hr.soc.politika :Ja usamljen? 5 sati sam danas šetao i pričao sa drugarom\r\n", "PRIVMSG #hr.soc.politika :1 + 4,5 = 5,5 sati sna\r\n", "PRIVMSG #hr.soc.politika :Zeka je bolje, pomogo xanax, ne kolje mi se više\r\n", "PRIVMSG #hr.soc.politika :Naručio pizzu da se počastim :-)\r\n", "PRIVMSG #hr.soc.politika :uvek istu vrstu pizze već godinama\r\n", "PRIVMSG #hr.soc.politika :Tako sam dobar, duša od čoveka\r\n", "PRIVMSG #hr.soc.politika :Volim ja kurve ali NEĆU da plaćam više\r\n", "PRIVMSG #hr.soc.politika :BDSM subice............ žude da se podaju Dominantu.......\r\n", "PRIVMSG #hr.soc.politika :Točno, ja sada hoću isključivo subice slatkice :-))\r\n", "PRIVMSG #hr.soc.politika :Došao eka sa tuluma Filozofskog fakulteta, yeeeeeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :Treba slejvicu povesti u Maksimir i pojebati je ispred kaveza s majmunima\r\n", "PRIVMSG #hr.soc.politika :Nazivaš me smrdom a ja mirišem po prekrasnom parfemu\r\n", "PRIVMSG #hr.soc.politika :Pičke mene ne zanimaju nego prkna\r\n", "PRIVMSG #hr.soc.politika :Zeka se vasceo dan odmarao i spavao\r\n", "PRIVMSG #hr.soc.politika :Kaže ta Zadranka 'imam malo drukčiji ukus što se tiče osobnosti muškaraca'\r\n", "PRIVMSG #hr.soc.politika :a ja samo odgovorio 'OK, o ukusima se ne raspravlja' :-)\r\n", "PRIVMSG #hr.soc.politika :oduvek sam hteo da vladam, a vremenom sam se naučio i da upravljam ljudskim životima\r\n", "PRIVMSG #hr.soc.politika :Reci im kume\r\n", "PRIVMSG #hr.soc.politika :oy drug\r\n", "PRIVMSG #hr.soc.politika :Danas ću poslati Dadeku stvari za Novi Sad :-)\r\n", "PRIVMSG #hr.soc.politika :Sanjam Dadeka kako se \"kreše\" s drugima.... yaoy\r\n", "PRIVMSG #hr.soc.politika :OLOSU!\r\n", "PRIVMSG #hr.soc.politika :JA ZUDIM!\r\n", "PRIVMSG #hr.soc.politika :Želiš moje TESTISE???????? MUDA??????????\r\n", "PRIVMSG #hr.soc.politika :DAJ MI MOLOHA JEBATE PATAK\r\n", "PRIVMSG #hr.soc.politika :Jezivo........\r\n", "PRIVMSG #hr.soc.politika :Gade, ja sam siroče\r\n", "PRIVMSG #hr.soc.politika :Prrrrrd........\r\n", "PRIVMSG #hr.soc.politika :ĆE ME TRTIŠ?\r\n", "PRIVMSG #hr.soc.politika :OŠ MOJA MUDA? \r\n", "PRIVMSG #hr.soc.politika :OŠ ME JEBAT? \r\n", "PRIVMSG #hr.soc.politika :JEDAN JEBE A DRUGI JE JEBEN!! \r\n", "PRIVMSG #hr.soc.politika :AKTIVAC I PASIVAC \r\n", "PRIVMSG #hr.soc.politika :Uuuuuuuu, kako sam iz-bacivao iz-metine iz ČMARA! \r\n", "PRIVMSG #hr.soc.politika :MIRSAD JE PONOVO ROĐENI KRŠĆANIN \r\n", "PRIVMSG #hr.soc.politika :LOOOOOL \r\n", "PRIVMSG #hr.soc.politika :U MENI IMA ZRNO LJUDSKOSTI \r\n", "PRIVMSG #hr.soc.politika :Mirsad opet prdi \r\n", "PRIVMSG #hr.soc.politika :ŽIVI LEŠ \r\n", "PRIVMSG #hr.soc.politika :PRAVO U ĆĆĆĆMAR! \r\n", "PRIVMSG #hr.soc.politika :NABIJANJE KURĆĆĆĆĆĆINE U ĆĆĆĆĆĆĆMAR \r\n", "PRIVMSG #hr.soc.politika :RAZBIJANJE LOBANJE ČEKIĆEM \r\n", "PRIVMSG #hr.soc.politika :PEDERE U LUDNICE \r\n", "PRIVMSG #hr.soc.politika :SAĆE DA TE TRTIM!!! \r\n", "PRIVMSG #hr.soc.politika :JA SAM AKTIVAC \r\n", "PRIVMSG #hr.soc.politika :JA NIJESAM PASIVAC \r\n", "PRIVMSG #hr.soc.politika :JEBEM TI SRBOČETNIČKU MATERIJU!!!!! \r\n", "PRIVMSG #hr.soc.politika :SRBOČETNICIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII \r\n", "PRIVMSG #hr.soc.politika :ŽIV'LA 'RVACKA \r\n", "PRIVMSG #hr.soc.politika :PAZITE SE SRBOČETNICI \r\n", "PRIVMSG #hr.soc.politika :MI DOLAZIMO \r\n", "PRIVMSG #hr.soc.politika :GNJIDO \r\n", "PRIVMSG #hr.soc.politika :SAĆU DA TE TRTIM \r\n", "PRIVMSG #hr.soc.politika :SRBO \r\n", "PRIVMSG #hr.soc.politika :JA SAM GENIJE DO YAYA \r\n", "PRIVMSG #hr.soc.politika :DA, TO SAM YA \r\n", "PRIVMSG #hr.soc.politika :PE------ŠKOOOOOO \r\n", "PRIVMSG #hr.soc.politika :ZNAJU GEJEVI DA PEVAJU \r\n", "PRIVMSG #hr.soc.politika :KAO KASTRATI AKA 'KONTRATENORI' \r\n", "PRIVMSG #hr.soc.politika :DAJ GEJA BRE \r\n", "PRIVMSG #hr.soc.politika :NE ŽELIŠ VEČITE GOLE ORGIJE S KURVAMA??????? \r\n", "PRIVMSG #hr.soc.politika :JA VOLIM \r\n", "PRIVMSG #hr.soc.politika :KURVE \r\n", "PRIVMSG #hr.soc.politika :MRZIM TRŽIŠTE \r\n", "PRIVMSG #hr.soc.politika :TRŽIŠTE LJUCKIH BIĆA \r\n", "PRIVMSG #hr.soc.politika :POČNI DA ME MLATIŠ PO GLAVI \r\n", "PRIVMSG #hr.soc.politika :GAY KLUB \r\n", "PRIVMSG #hr.soc.politika :MASNI PASIVAC \r\n", "PRIVMSG #hr.soc.politika :ŽELIM TE GOLOG! \r\n", "PRIVMSG #hr.soc.politika :DEČACI KURVE \r\n", "PRIVMSG #hr.soc.politika :DEČACI MURATI \r\n", "PRIVMSG #hr.soc.politika :NEŠ GA KUPIT \r\n", "PRIVMSG #hr.soc.politika :ŽELIM PAKAO \r\n", "PRIVMSG #hr.soc.politika :UNAKAZITE ME!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :ZEKA ZNA \r\n", "PRIVMSG #hr.soc.politika :NEŠ \r\n", "PRIVMSG #hr.soc.politika :AJDE DOĐI I KOLJI \r\n", "PRIVMSG #hr.soc.politika :SUDIT ĆE TI BOJOVNICI IZ ČAVOGLAVA \r\n", "PRIVMSG #hr.soc.politika :TAKO SE BOJIM.......... \r\n", "PRIVMSG #hr.soc.politika :NEMOJ ME UMLAĆIVAT MOČUGOM \r\n", "PRIVMSG #hr.soc.politika :ŽELATINOZNA MASA \r\n", "PRIVMSG #hr.soc.politika :ŽVALE \r\n", "PRIVMSG #hr.soc.politika :STRAH OBUZIMA \r\n", "PRIVMSG #hr.soc.politika :BOJIM SE........ \r\n", "PRIVMSG #hr.soc.politika :ULAZE MI U ČAKRU \r\n", "PRIVMSG #hr.soc.politika :ULJEZI \r\n", "PRIVMSG #hr.soc.politika :U Istočnoj Hercegovini se govori ijekavski ludaku \r\n", "PRIVMSG #hr.soc.politika :ŠAŠOLJENJE MUDA \r\n", "PRIVMSG #hr.soc.politika :GUJE U POTAJI \r\n", "PRIVMSG #hr.soc.politika :VOLIM DEČAKE \r\n", "PRIVMSG #hr.soc.politika :NEŠ MENE!! \r\n", "PRIVMSG #hr.soc.politika :YAOY \r\n", "PRIVMSG #hr.soc.politika :ZARIJ MI GA U ĆĆĆĆĆĆMAR \r\n", "PRIVMSG #hr.soc.politika :kajkaFske popeFke \r\n", "PRIVMSG #hr.soc.politika :MUŠKARCI MUŠKARCI \r\n", "PRIVMSG #hr.soc.politika :OH DAAAAAAAAAAAA \r\n", "PRIVMSG #hr.soc.politika :KRŠTENJE MARKA MARINA \r\n", "PRIVMSG #hr.soc.politika :Hlače mi se sve više raspadaju, već nekoliko rupa yay \r\n", "PRIVMSG #hr.soc.politika :APAURIN je iz Raja izašo \r\n", "PRIVMSG #hr.soc.politika :ORGIJE!!!!!!!!!!! ORGIJE!!!!!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :OŠ AGRESORU \r\n", "PRIVMSG #hr.soc.politika :JA SAM GUZIČAR \r\n", "PRIVMSG #hr.soc.politika :UBITI KURVE \r\n", "PRIVMSG #hr.soc.politika :SRbSKE KURVEŠTIJE \r\n", "PRIVMSG #hr.soc.politika :DRISLO \r\n", "PRIVMSG #hr.soc.politika :Đa Đa \r\n", "PRIVMSG #hr.soc.politika :FEMINIZIRANI FRATRI \r\n", "PRIVMSG #hr.soc.politika :Poždrao sam lignje do kraja \r\n", "PRIVMSG #hr.soc.politika :TRAGEDIJA MOZGOVA \r\n", "PRIVMSG #hr.soc.politika :Popio sam kefir! \r\n", "PRIVMSG #hr.soc.politika :POŽUDA LUDAKA PREMA FRATRIMA \r\n", "PRIVMSG #hr.soc.politika :GOLA POŽUDA \r\n", "PRIVMSG #hr.soc.politika :FRATRI \r\n", "PRIVMSG #hr.soc.politika :BELZEBUB \r\n", "PRIVMSG #hr.soc.politika :Dzabe Oko \r\n", "PRIVMSG #hr.soc.politika :JA SAM ČIKA PEŠKO \r\n", "PRIVMSG #hr.soc.politika :VADI GA VAN!!!!!!! VADI GA VAN!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :RAŽDAGINJA I PROSLAP \r\n", "PRIVMSG #hr.soc.politika :VELELEBNI LIBAR \r\n", "PRIVMSG #hr.soc.politika :DAJ MI GUBICU \r\n", "PRIVMSG #hr.soc.politika :ČIMPANZE ODGRIZAJU LJUDSKA LICA \r\n", "PRIVMSG #hr.soc.politika :VELIKONEMAČKI REICH!!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :HEIL HITLER!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :KREVELJIM SE I URLAM \r\n", "PRIVMSG #hr.soc.politika :Begam pod deku! \r\n", "PRIVMSG #hr.soc.politika :TRGANJE MEEEEEEESSSSAAAAAAA \r\n", "PRIVMSG #hr.soc.politika :BLJUV \r\n", "PRIVMSG #hr.soc.politika :NEŠ GNJIDOOOOOOOOOOOOOOOO \r\n", "PRIVMSG #hr.soc.politika :Đoš \r\n", "PRIVMSG #hr.soc.politika :DAJ MI PASJU GUBICU \r\n", "PRIVMSG #hr.soc.politika :Hroh \r\n", "PRIVMSG #hr.soc.politika :Dođi mi otmi penziju, ajde!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Odoh da buljim u strop..... i zvodoravnog položaja, heh \r\n", "PRIVMSG #hr.soc.politika :DAJ MI KURVE DAJ MI IH \r\n", "PRIVMSG #hr.soc.politika :DAJ MI BOŽE KURVE!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Zašto, o zašto mi jeBog oduzeo KURVE??????????? \r\n", "PRIVMSG #hr.soc.politika :KURVE sam sanjo \r\n", "PRIVMSG #hr.soc.politika :Na gležnjevima imam sloj smeđe prljavštine, mrtvu kožu koja se ljušti \r\n", "PRIVMSG #hr.soc.politika :U BERLINU je moje mesto \r\n", "PRIVMSG #hr.soc.politika :Odstupi Sotono! Ja sam Božje Dijete! \r\n", "PRIVMSG #hr.soc.politika :Gri-boyed Gribo-yedovič Gri-bo-yedoF \r\n", "PRIVMSG #hr.soc.politika :Jeste, SveCka Zavera \r\n", "PRIVMSG #hr.soc.politika :URBAN SAM DO KOSKE! \r\n", "PRIVMSG #hr.soc.politika :Evo ME drugari!!! \r\n", "PRIVMSG #hr.soc.politika :Paranoja me pere........ \r\n", "PRIVMSG #hr.soc.politika :Tako sam dobar!!!! \r\n", "PRIVMSG #hr.soc.politika :GLEDAŠ TI PEDERA U PRKNU! \r\n", "PRIVMSG #hr.soc.politika :AAAAHAHHAAAHAHHHH \r\n", "PRIVMSG #hr.soc.politika :TRTADŽIJA TRTKO \r\n", "PRIVMSG #hr.soc.politika :Žderao sam desetke čokoladnih tortica.... danima.... \r\n", "PRIVMSG #hr.soc.politika :Potiho URLAM \r\n", "PRIVMSG #hr.soc.politika :ISTO--SPOLCI \r\n", "PRIVMSG #hr.soc.politika :PEDER PEDRO \r\n", "PRIVMSG #hr.soc.politika :KRUTE KURĆĆĆĆĆINE \r\n", "PRIVMSG #hr.soc.politika :PENIS PEDERA \r\n", "PRIVMSG #hr.soc.politika :TRUNITE U FILTERU \r\n", "PRIVMSG #hr.soc.politika :Vreme za ŠIBANJE..........\r\n", "PRIVMSG #hr.soc.politika :Yeeeeeeeee, donet će mi drugar sa sela vrbove šibe :-)))\r\n", "PRIVMSG #hr.soc.politika :Odoh opet pod deku da njušim dlaku i smirujem se....\r\n", "PRIVMSG #hr.soc.politika :PSINO ČETNIČKA CRNA\r\n", "PRIVMSG #hr.soc.politika :Oyla! Zeku nazvao drugar pa sam jeo, i to toplo, ugrijao pasulj prebranac, yeeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :ISTOVARUJEŠ GOLA GOVNA BRE\r\n", "PRIVMSG #hr.soc.politika :Sad ću ja da idem lepo u šetnju opet, lep je dan :-)\r\n", "PRIVMSG #hr.soc.politika :Hehe, dok ja radim svoje, vi se pitate šta ću i kako ću ja, a ja i dalje radim svoje i ide mi\r\n", "PRIVMSG #hr.soc.politika :Izaći će Zeka opet ujutro u kafić na jutarnju kafu\r\n", "PRIVMSG #hr.soc.politika :yeha, Zeka ždero\r\n", "PRIVMSG #hr.soc.politika :STRAH........\r\n", "PRIVMSG #hr.soc.politika :Strah i žudnja.....\r\n", "PRIVMSG #hr.soc.politika :Zeka mete pod od mrvica\r\n", "PRIVMSG #hr.soc.politika :Strah me obuzeo.......\r\n", "PRIVMSG #hr.soc.politika :Kako god bilo- Zeka dolazi :-)\r\n", "PRIVMSG #hr.soc.politika :Piše u pozivu - možete doneti svoje igračke....\r\n", "PRIVMSG #hr.soc.politika :+ donesite i grickalice i piće\r\n", "PRIVMSG #hr.soc.politika :a ja ću doneti 2 sexy bombonjere + flašu finog likera\r\n", "PRIVMSG #hr.soc.politika :Zeka ide na sado-mazo žurku, yeeeeeeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :Yeah, Zeka se obrazovao u BDSM-u :-)))\r\n", "PRIVMSG #hr.soc.politika :Prelepo je videti rođenu subicu kako služi Gospodaru\r\n", "PRIVMSG #hr.soc.politika :Kaj se more, nije bilo slobodnih subitza\r\n", "PRIVMSG #hr.soc.politika :Oprali svoj veš kod mene i sutra će još\r\n", "PRIVMSG #hr.soc.politika :hlače, čarape, majice....\r\n", "PRIVMSG #hr.soc.politika :Ide Zeka zadovoljan pod deku :-))\r\n", "PRIVMSG #hr.soc.politika :One čekaju da im ja odredim vrem i mesto sastanka, jer su poslušne subice\r\n", "PRIVMSG #hr.soc.politika :Sad ću da naručim Zečice za dejt\r\n", "PRIVMSG #hr.soc.politika :Kulminirat ću ja svojom spermom u njihovim guzama......\r\n", "PRIVMSG #hr.soc.politika :imat ćemo blind date! :-) da bude uzbudljivo\r\n", "PRIVMSG #hr.soc.politika :POzvao subicu na dejt u sredu\r\n", "PRIVMSG #hr.soc.politika :Ma........ ali super je bio film Blind Date sa Kim Basinger i Bruceom Willisom\r\n", "PRIVMSG #hr.soc.politika :Ovaj tjedan bi trebali stići NOVCI :-)))))))))\r\n", "PRIVMSG #hr.soc.politika :Izaći ću ujutro u dućan i kafić\r\n", "PRIVMSG #hr.soc.politika :6 sati mirnog sna\r\n", "PRIVMSG #hr.soc.politika :Popio 2 xanaxa\r\n", "PRIVMSG #hr.soc.politika :Sat vremena urlao u kujini\r\n", "PRIVMSG #hr.soc.politika :O-ho-ho, kako Zeka RADI...... svaki dan\r\n", "PRIVMSG #hr.soc.politika :Bit će na partyju sprava za mučenje, žestokog bičevanja i torture strujom\r\n", "PRIVMSG #hr.soc.politika :Idem sutra poi kartu za novi sado-mazo party\r\n", "PRIVMSG #hr.soc.politika :Nemaš blage veze šta je to subica\r\n", "PRIVMSG #hr.soc.politika :ti poznaš samo kurve\r\n", "PRIVMSG #hr.soc.politika :Ne pada mi na pamet tebi išta objašnjavati\r\n", "PRIVMSG #hr.soc.politika :2 sata sna, sanjanje subica\r\n", "PRIVMSG #hr.soc.politika :Ja ne drkam\r\n", "PRIVMSG #hr.soc.politika :Deka....\r\n", "PRIVMSG #hr.soc.politika :Da bar tegliš kad ništa ne pomažeš u domaćinstvu\r\n", "PRIVMSG #hr.soc.politika :ali naše parcele su sve plodne a tvoje su goleti\r\n", "PRIVMSG #hr.soc.politika :Boduli imaju male parcele\r\n", "PRIVMSG #hr.soc.politika :Ja imam 2 kuće i 3,5 ha zemlje\r\n", "PRIVMSG #hr.soc.politika :Nema kubičnog metra mog stana koji nije uredila moja ruka!\r\n", "PRIVMSG #hr.soc.politika :Javljaju mi se nove subice na BDSM oglas svaki dan :-))\r\n", "PRIVMSG #hr.soc.politika :Sve ih treba pojebat iizbičevat\r\n", "PRIVMSG #hr.soc.politika :drugara u posetu čeka\r\n", "PRIVMSG #hr.soc.politika :Maska Zeke dolazi prema meni\r\n", "PRIVMSG #hr.soc.politika :brže će mi doći ovako s manjom poštarinom nego s većom\r\n", "PRIVMSG #hr.soc.politika :SVE mi ide na ruku\r\n", "PRIVMSG #hr.soc.politika :Zeka cveta\r\n", "PRIVMSG #hr.soc.politika :Život je lep :-))\r\n", "PRIVMSG #hr.soc.politika :Predivno je........\r\n", "PRIVMSG #hr.soc.politika :Sve mi to šalje moj zaštitnik - sveti mamek sa Nebesa!\r\n", "PRIVMSG #hr.soc.politika :toliko sam iskusan i verziran u igri zavođenja\r\n", "PRIVMSG #hr.soc.politika :malo bucmasta, lepa, mekana i podatna, mmmmm\r\n", "PRIVMSG #hr.soc.politika :Osećam se sposoban da idem tako daleko\r\n", "PRIVMSG #hr.soc.politika :a male subice vole zrele muškarce\r\n", "PRIVMSG #hr.soc.politika :FILTER \r\n", "PRIVMSG #hr.soc.politika :ZAKLAO BI I TI DA MOREŠ\r\n", "PRIVMSG #hr.soc.politika :Čmar jer ja sam GUZIČAR\r\n", "PRIVMSG #hr.soc.politika :Najlepše je trteti robinje u prkno...........\r\n", "PRIVMSG #hr.soc.politika :Oporavljam se dakle u svakom pogledu :-)) A sasvim ću se oporaviti kada nađem DEVOJKU\r\n", "PRIVMSG #hr.soc.politika :Lučenje kortizola, hormona straha, mi je manje, pa trebam sve manje slatkog jesti\r\n", "PRIVMSG #hr.soc.politika :STRAH mi je sve manji, više se ne bojim groma, ne pomišljam na požar, ali se i dalje bojim PSA\r\n", "PRIVMSG #hr.soc.politika :Zeka je umoran, nije dovoljno spavao, ali treba trtiti\r\n", "PRIVMSG #hr.soc.politika :Da, ali ja ne jebem bilo koga!\r\n", "PRIVMSG #hr.soc.politika :SAMO U JEBANJU JESTE SPAS ZA OVAJ PALI SVET......\r\n", "PRIVMSG #hr.soc.politika :Dominacija i usred noći............\r\n", "PRIVMSG #hr.soc.politika :MOja prva devojka-subica Sunčica je dobro sisala kurac\r\n", "PRIVMSG #hr.soc.politika :Sanjao sam kako mi pred vrata banuo narkoman\r\n", "PRIVMSG #hr.soc.politika :Umor me shrvava........ pod deku..........\r\n", "PRIVMSG #hr.soc.politika :Zeka ždero lep sendvič s pohanom piletinom kupljen kod Šiptara\r\n", "PRIVMSG #hr.soc.politika :Dominant se dopisuje i usred noći sa ženama, yeeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :Đorč, gotovo........ hladno mi je, svaki put nakon što idem van\r\n", "PRIVMSG #hr.soc.politika :Zeka pod deku konačno....\r\n", "PRIVMSG #hr.soc.politika :Ma... odoh ja jopet pod deku\r\n", "PRIVMSG #hr.soc.politika :Da želim mogao bih i trandže i pedere da trtim\r\n", "PRIVMSG #hr.soc.politika :Ode Zeka pod deku.......\r\n", "PRIVMSG #hr.soc.politika :đorč, opet sam dobro :-))\r\n", "PRIVMSG #hr.soc.politika :Evo, smirio sam se skroz.... xanax pomaže!\r\n", "PRIVMSG #hr.soc.politika :Izbacili me iz takta MIrko i Ilija, gadoooovi\r\n", "PRIVMSG #hr.soc.politika :Ja sam prelepi Zeka, karizmatična ličnost\r\n", "PRIVMSG #hr.soc.politika :Popio još 1 xanax, pomozi Bože!!\r\n", "PRIVMSG #hr.soc.politika :Svinja nije samo sub, on je switch. On i trti i biva trten\r\n", "PRIVMSG #hr.soc.politika :Ljudi me hvale kako sam 'opaki Dominant', vele... hehe\r\n", "PRIVMSG #hr.soc.politika :Sanjao sam opet nakon dužeg vremena noćnu moru, yay\r\n", "PRIVMSG #hr.soc.politika :Opaka Dominacija........\r\n", "PRIVMSG #hr.soc.politika :sub sub sub\r\n", "PRIVMSG #hr.soc.politika :Subice me spopadaju, žude za mojom prisutnošću\r\n", "PRIVMSG #hr.soc.politika :Zeka kakio usred noći\r\n", "PRIVMSG #hr.soc.politika :POkorit će se meni SVI\r\n", "PRIVMSG #hr.soc.politika :Bijedni Zeka nije višpe bijedan :-))\r\n", "PRIVMSG #hr.soc.politika :Zeka nema kompleksa odavno.... od 1992.\r\n", "PRIVMSG #hr.soc.politika :Jednom u životu sam probao viski \r\n", "PRIVMSG #hr.soc.politika :Piškio sam i češao skrotum \r\n", "PRIVMSG #hr.soc.politika :Zatvorena mi je prva čakra \r\n", "PRIVMSG #hr.soc.politika :AGRESIJA POVAMPIRENIH USTAŠA NA REPUBLIKU SRbSKU KRAJINU \r\n", "PRIVMSG #hr.soc.politika :NIJEDAN USTAŠA NE KANI PROĆI! \r\n", "PRIVMSG #hr.soc.politika :NEŠ VIŠE NIKAD!!!!!!!!!!!!!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :OLOOOOOŠI \r\n", "PRIVMSG #hr.soc.politika :SMEĆEEEEEEE \r\n", "PRIVMSG #hr.soc.politika :PUSTITE ME NA MIRU GADOVI!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Nema serije nedeljom \r\n", "PRIVMSG #hr.soc.politika :Pustite me da živim kao PAS!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Ja radim kao mrav!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Dirinčim za mameka!! \r\n", "PRIVMSG #hr.soc.politika :Prljav sam ko svinja!! \r\n", "PRIVMSG #hr.soc.politika :Ja nisam lažov!! Stvarno imam skorelu prljavštinu koja se ljušti!! \r\n", "PRIVMSG #hr.soc.politika :NEĆETE MI UNIŠTITI EGZISTENCIJU!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :i dok spavam brljavite o meni! \r\n", "PRIVMSG #hr.soc.politika :Prokleti bullyji!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Znate da sam nemoćnik i udri po meni \r\n", "PRIVMSG #hr.soc.politika :Ja sam DOBAR! \r\n", "PRIVMSG #hr.soc.politika :Živim mirno s mamekom i nikoga ne ugoržovam \r\n", "PRIVMSG #hr.soc.politika :Reći ću svima šta mi radite!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :SMEĆE ljucko \r\n", "PRIVMSG #hr.soc.politika :Ajde DOĐI I ZAKOLJI ME \r\n", "PRIVMSG #hr.soc.politika :Ne, nego otimaš zadnji dinar invalidima?? \r\n", "PRIVMSG #hr.soc.politika :Tako te učio tvoj šloser??? \r\n", "PRIVMSG #hr.soc.politika :DOKAŽITE!! \r\n", "PRIVMSG #hr.soc.politika :Ne tučem ja mameka \r\n", "PRIVMSG #hr.soc.politika :Zasmegmana je tvoja gubica!! \r\n", "PRIVMSG #hr.soc.politika :Svrbi me od puno sedenja pa se uznoji \r\n", "PRIVMSG #hr.soc.politika :Neću se utopiti ali mogu pasti i ubiti se! \r\n", "PRIVMSG #hr.soc.politika :Pa se počešem ko čovek \r\n", "PRIVMSG #hr.soc.politika :Ja nisam peder \r\n", "PRIVMSG #hr.soc.politika :Pederi su čisti :-) \r\n", "PRIVMSG #hr.soc.politika :VI mene zajebavate kao mladog majmuna \r\n", "PRIVMSG #hr.soc.politika :A ja to neću više da trpim!!! \r\n", "PRIVMSG #hr.soc.politika :Ovo je bullyjing gori nego kad su trešeri zajebavali Turinu \r\n", "PRIVMSG #hr.soc.politika :Trebam puno sna jer sam bolesnik!! \r\n", "PRIVMSG #hr.soc.politika :a ja pijem sve po propisu! \r\n", "PRIVMSG #hr.soc.politika :prokleti pomahnitali alkoholičar! \r\n", "PRIVMSG #hr.soc.politika :Svrbe me prsti gadovi \r\n", "PRIVMSG #hr.soc.politika :Gadni buliji \r\n", "PRIVMSG #hr.soc.politika :Ja sam SIROTI smrda \r\n", "PRIVMSG #hr.soc.politika :................. \r\n", "PRIVMSG #hr.soc.politika :ćeš me zaklati na Ovčari??? \r\n", "PRIVMSG #hr.soc.politika :NEŠ ČETNIČARO!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Sve je ovo gluma, mrzite me samo zato što sam HRVAT IZVORNJAK! \r\n", "PRIVMSG #hr.soc.politika :CVILITE \r\n", "PRIVMSG #hr.soc.politika :JESAM VAS OLOOOOOOŠI!!!!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :JECAJ ČETNIČARO \r\n", "PRIVMSG #hr.soc.politika :ZAJEBO SAM VAS GNJIDE \r\n", "PRIVMSG #hr.soc.politika :POBEDA!!! POBEDA!!! \r\n", "PRIVMSG #hr.soc.politika :Mislili ste da sam vaše govno!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Četkam četkom nokat, prst koji smrdi od češanja čmara! \r\n", "PRIVMSG #hr.soc.politika :Bolje mi ponjuši smrdljiv čmar!! \r\n", "PRIVMSG #hr.soc.politika :Znaš li ti da je mene peško u javnom nužniku vatao za muda??? \r\n", "PRIVMSG #hr.soc.politika :OŠ SVRAČJE CRKOTINE? \r\n", "PRIVMSG #hr.soc.politika :OŠ MIŠJE STRVINE? \r\n", "PRIVMSG #hr.soc.politika :Ne trza....... \r\n", "PRIVMSG #hr.soc.politika :Ja obožavam lučenje smrdljivih sekreta iz skrotuma \r\n", "PRIVMSG #hr.soc.politika :ORGIJE LUDAKA........... \r\n", "PRIVMSG #hr.soc.politika :KULT VAGINE JE KULT ZMIJURINE!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :A KULT PENISA - KULT JARCA!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :DEST HILJADA DO ZUBA NAORUŽANIH USTAŠA......... \r\n", "PRIVMSG #hr.soc.politika :UBI UBI SRbINA \r\n", "PRIVMSG #hr.soc.politika :ŽIVEO SRbSKI NAAAAAAAAAAROD \r\n", "PRIVMSG #hr.soc.politika :\"U Imockom ima ništo pravoslavni, narod ji zove rišćani i rkači, nu svagdi su u velikoj manjini. Ljudi dobri i mirni, ne valeć jim zakona.\" \r\n", "PRIVMSG #hr.soc.politika :Ološu, jedem tunj iz konzerve \r\n", "PRIVMSG #hr.soc.politika :a meso pileće ostavljam mameku! \r\n", "PRIVMSG #hr.soc.politika :AJDE REZAČI LJUCKIH TELA, AJDE!!! \r\n", "PRIVMSG #hr.soc.politika :Onanišete opet na mene? \r\n", "PRIVMSG #hr.soc.politika :ZBLJUV OLOŠI \r\n", "PRIVMSG #hr.soc.politika ::-)))) dao Bog! \r\n", "PRIVMSG #hr.soc.politika :ALLAH ILLAHIM \r\n", "PRIVMSG #hr.soc.politika :ALLAH ALLAH \r\n", "PRIVMSG #hr.soc.politika :Kako je lep taj filter \r\n", "PRIVMSG #hr.soc.politika :DoŽot Fy-ka \r\n", "PRIVMSG #hr.soc.politika :Jebali te srBski zločinci, četniče!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :U ničemu ja ne uživam kao u svom statusu INVALIDA \r\n", "PRIVMSG #hr.soc.politika :NEŠ GMIZAT!!! \r\n", "PRIVMSG #hr.soc.politika :KRAO SI??? \r\n", "PRIVMSG #hr.soc.politika :Moj mamek nije krao \r\n", "PRIVMSG #hr.soc.politika :Ode gad \r\n", "PRIVMSG #hr.soc.politika :Ma zaklali ga \r\n", "PRIVMSG #hr.soc.politika :Zove me mamek da mu pomažem \r\n", "PRIVMSG #hr.soc.politika :O dragi mamek moj :-)) \r\n", "PRIVMSG #hr.soc.politika :Prikrivam svoju gadost \r\n", "PRIVMSG #hr.soc.politika :Pasja gubica je nešto najogavnije \r\n", "PRIVMSG #hr.soc.politika :NE VERUJ ČETNIKU NI KAD DAROVE NOSI \r\n", "PRIVMSG #hr.soc.politika :Idem da čalabrcnem skroman obrok \r\n", "PRIVMSG #hr.soc.politika :ŽIVIJA GOLI STIPE MESIĆ!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :da stiskam sfinkter i izbacujem izmet iz čmara \r\n", "PRIVMSG #hr.soc.politika :Pokakio sam se, ko vidra \r\n", "PRIVMSG #hr.soc.politika :Uvek je lepo kakiti \r\n", "PRIVMSG #hr.soc.politika :Zeka ide pod deku malo \r\n", "PRIVMSG #hr.soc.politika :Hladno je drug \r\n", "PRIVMSG #hr.soc.politika :Imam debelu jaknu ali je poderana! \r\n", "PRIVMSG #hr.soc.politika :Kao student sam hodao u zelenoj vojničkoj jakni \r\n", "PRIVMSG #hr.soc.politika :hehe, darkerska subkultura \r\n", "PRIVMSG #hr.soc.politika :a jedno vreme sam nosio i crnu dolčevitu \r\n", "PRIVMSG #hr.soc.politika :SAND BAKIJA \r\n", "PRIVMSG #hr.soc.politika :Kašljem ko konj! od cigareta \r\n", "PRIVMSG #hr.soc.politika :povraća mi se \r\n", "PRIVMSG #hr.soc.politika :GOLI MUŠKARAC VITLA PENISOM NA NASIPU SAVSKOM \r\n", "PRIVMSG #hr.soc.politika :SAVSKI NASIP \r\n", "PRIVMSG #hr.soc.politika :Mamek traži da joj donesem čepiće za čmar \r\n", "PRIVMSG #hr.soc.politika :Opet piškiti... \r\n", "PRIVMSG #hr.soc.politika :Bokač! \r\n", "PRIVMSG #hr.soc.politika :Opet ću tegliti \r\n", "PRIVMSG #hr.soc.politika :Obući ću zimske cipele \r\n", "PRIVMSG #hr.soc.politika :Jeo sam GUJDU \r\n", "PRIVMSG #hr.soc.politika :Ždero sam SVINJE \r\n", "PRIVMSG #hr.soc.politika :O kako sam ŽDERO \r\n", "PRIVMSG #hr.soc.politika :Knjabež Buls \r\n", "PRIVMSG #hr.soc.politika :Joj što volem PEDERE \r\n", "PRIVMSG #hr.soc.politika :BALKAN POTARACATI ATOMSIM BOMBAMA!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :RINI MI PENIS U PRKNO \r\n", "PRIVMSG #hr.soc.politika :TURI MI GA \r\n", "PRIVMSG #hr.soc.politika :ŠABAT ŠALOM \r\n", "PRIVMSG #hr.soc.politika :PA TO SU USTAŠE JEBA TE PATAK \r\n", "PRIVMSG #hr.soc.politika :BRAVO!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Klao bih ja SVAKOGA \r\n", "PRIVMSG #hr.soc.politika :Pedere treba TRTITI! \r\n", "PRIVMSG #hr.soc.politika :Okani se pedera!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :ONI SU DIVNI \r\n", "PRIVMSG #hr.soc.politika :Svrbi me trbuh, češem ga \r\n", "PRIVMSG #hr.soc.politika :USTAŠO, JEL JEČIŠ???????? \r\n", "PRIVMSG #hr.soc.politika :NE DIRAJ MI PUPAFCA GADE \r\n", "PRIVMSG #hr.soc.politika :GADE ČETNIČKI \r\n", "PRIVMSG #hr.soc.politika :PRDARO STARA! \r\n", "PRIVMSG #hr.soc.politika :SVE SAM JA SHVATIO \r\n", "PRIVMSG #hr.soc.politika :OBA U FILTERU \r\n", "PRIVMSG #hr.soc.politika :Bog će da mi da MILIONE \r\n", "PRIVMSG #hr.soc.politika :Moram kakiti drugari \r\n", "PRIVMSG #hr.soc.politika :Češanje dandala je najlepše, najugodnije \r\n", "PRIVMSG #hr.soc.politika :Tako si stimulišem Prvu Čakru! \r\n", "PRIVMSG #hr.soc.politika :SAKATA, MORBIDNA RITUALNA KLANJA \r\n", "PRIVMSG #hr.soc.politika :JA SAM OD SUŠTINSKE VAŽNOSTI ZA SVET \r\n", "PRIVMSG #hr.soc.politika :POKAKIT ĆE TI BRABONJAK NA GLAVU \r\n", "PRIVMSG #hr.soc.politika :Žderao sam skroman obrok skuše i nudli \r\n", "PRIVMSG #hr.soc.politika :FRATAR KAO OBJEKT POŽUDE \r\n", "PRIVMSG #hr.soc.politika :Piškio sam prvo, sad idem \r\n", "PRIVMSG #hr.soc.politika :MALO PRIJE SI PRETIO \r\n", "PRIVMSG #hr.soc.politika :PSIHOPATU \r\n", "PRIVMSG #hr.soc.politika :SVIM ŽRTVAMA KAŽEŠ DA IH VOLIŠ \r\n", "PRIVMSG #hr.soc.politika :MLATIT ĆEŠ ME KAO PSA!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :I SILOVATI \r\n", "PRIVMSG #hr.soc.politika :JA SAM SLAB I NEMOĆAN \r\n", "PRIVMSG #hr.soc.politika :Kaje zlikofci? Kakio sam tvrdu stolicu \r\n", "PRIVMSG #hr.soc.politika :Enigma liže muda hercegovačkom fratru \r\n", "PRIVMSG #hr.soc.politika :Zaklat ću te četniče!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Prenosiš sidu bre!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Ilija PEDERU \r\n", "PRIVMSG #hr.soc.politika :Kaje peško??? \r\n", "PRIVMSG #hr.soc.politika :FUUUUUUUUUUUJJJJJJJJJJJJJJJJ \r\n", "PRIVMSG #hr.soc.politika :FALA DRUG! \r\n", "PRIVMSG #hr.soc.politika :FEMINIZIRAN FRATAR \r\n", "PRIVMSG #hr.soc.politika :MIrsad žestoko žudi za fratrom \r\n", "PRIVMSG #hr.soc.politika :Kakio sam i češao dandalo i čmar \r\n", "PRIVMSG #hr.soc.politika :HAHAHAHHAHAHHHAHHHH \r\n", "PRIVMSG #hr.soc.politika :PRDARO stara!! \r\n", "PRIVMSG #hr.soc.politika :Egeštenija Maka \r\n", "PRIVMSG #hr.soc.politika :Bolje snimi ČMAROVE \r\n", "PRIVMSG #hr.soc.politika :Kaje Mirkec??? Buš me JEBAL????????!??!?!?? \r\n", "PRIVMSG #hr.soc.politika :Isprdim ti se na lobanju ćelavu! \r\n", "PRIVMSG #hr.soc.politika :JA SAM IZRAZITO PERVERZAN PERVERTIT \r\n", "PRIVMSG #hr.soc.politika :TI Mirko ločeš na LITRE \r\n", "PRIVMSG #hr.soc.politika :Stimuliram ti ja čmar butt plugom MIrko! \r\n", "PRIVMSG #hr.soc.politika :trt \r\n", "PRIVMSG #hr.soc.politika :Ja imam predivno prkno \r\n", "PRIVMSG #hr.soc.politika :Evo, čim sam pojeo moram da kakim \r\n", "PRIVMSG #hr.soc.politika :Mamek veli da je iskakio veliku kobasicu \r\n", "PRIVMSG #hr.soc.politika :Zaranjam u kacu s govnima!! \r\n", "PRIVMSG #hr.soc.politika :Mazanje govnima golog Turila \r\n", "PRIVMSG #hr.soc.politika :Gola Mazanja \r\n", "PRIVMSG #hr.soc.politika :TRANDŽAAAAAAAAAA \r\n", "PRIVMSG #hr.soc.politika :Banketi od govana....... \r\n", "PRIVMSG #hr.soc.politika :Žderanje dreka \r\n", "PRIVMSG #hr.soc.politika :PERVERZIJE S PTERODAKTILOM \r\n", "PRIVMSG #hr.soc.politika :GADE JA SAM LUD \r\n", "PRIVMSG #hr.soc.politika :Sad sam urlao na mameka pa pobego da pijem antipsihotik \r\n", "PRIVMSG #hr.soc.politika :NAKAZO LJUCKA!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :FUJ SMEĆE PROKLETO!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :MENE ĆEŠ TI, MENE..........!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :NGO DINH DIEM BUDALE!!!!!!!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :DOĐI I CIGLOM MI RAZBIJAJ GLAVU \r\n", "PRIVMSG #hr.soc.politika :GNJIDE jedne proklete!! \r\n", "PRIVMSG #hr.soc.politika :RAD JE SMRT \r\n", "PRIVMSG #hr.soc.politika :ČETNIKE UBITI \r\n", "PRIVMSG #hr.soc.politika :Ispijam 2 jutarnja leka \r\n", "PRIVMSG #hr.soc.politika :Mamek je meni ZAHVALAN!! \r\n", "PRIVMSG #hr.soc.politika :Ja sam hranu DONEO \r\n", "PRIVMSG #hr.soc.politika :Mamek i ja ćemo da se gostimo! \r\n", "PRIVMSG #hr.soc.politika :Pojeo sam 5 čoko štangica \r\n", "PRIVMSG #hr.soc.politika :A sad ću da preživam pod dekom! \r\n", "PRIVMSG #hr.soc.politika :SAKATI SRRRRRRBBBBBBUUUUUUUUUUU \r\n", "PRIVMSG #hr.soc.politika :EJ SRRRRRBO ČEKA TE VRRRRRRBO \r\n", "PRIVMSG #hr.soc.politika :Kaj kaj kaj, predragi domaČi naš KAJ \r\n", "PRIVMSG #hr.soc.politika :HM... \r\n", "PRIVMSG #hr.soc.politika :BDSM PEDERASTIJA \r\n", "PRIVMSG #hr.soc.politika :GUZIM TE ČETNIČE \r\n", "PRIVMSG #hr.soc.politika :LJUCKI OLOOOOOŠI \r\n", "PRIVMSG #hr.soc.politika :JEZIVO \r\n", "PRIVMSG #hr.soc.politika :Život nam je jednoličan pa da dam malo živosti \r\n", "PRIVMSG #hr.soc.politika :Pevam kao operni pevač \r\n", "PRIVMSG #hr.soc.politika :UDBA UBIJA \r\n", "PRIVMSG #hr.soc.politika :POjeo sam cele čoko štangice \r\n", "PRIVMSG #hr.soc.politika :KRVNIČE hrvatskog naroda!!!! \r\n", "PRIVMSG #hr.soc.politika :Meni je Božić svaki dan \r\n", "PRIVMSG #hr.soc.politika :VEŠTAĆĆĆĆĆĆKA VAGINA \r\n", "PRIVMSG #hr.soc.politika :ALTIPLANO \r\n", "PRIVMSG #hr.soc.politika :RAD JE SMRT! \r\n", "PRIVMSG #hr.soc.politika :ARBEIT IST TODT \r\n", "PRIVMSG #hr.soc.politika :DEČAK SPERMA \r\n", "PRIVMSG #hr.soc.politika :DOĐI TA TE TASLAČIM \r\n", "PRIVMSG #hr.soc.politika :BUĐAVO DETE \r\n", "PRIVMSG #hr.soc.politika :NAMAŽEM TE GOVNIMA \r\n", "PRIVMSG #hr.soc.politika :PROLJEV \r\n", "PRIVMSG #hr.soc.politika :PEVAJU O GOVNETU \r\n", "PRIVMSG #hr.soc.politika :Upravo mi se raspala šlapa! provirio palac van :-D \r\n", "PRIVMSG #hr.soc.politika :DA LI TI IMAŠ PENIS????????????????? \r\n", "PRIVMSG #hr.soc.politika :SRbINA SKINI DO GOLOG \r\n", "PRIVMSG #hr.soc.politika :TRI PRSTA!!!!!!!! U ĆĆĆĆĆĆMAR!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :TROPRSTI JUGOOFICIRI \r\n", "PRIVMSG #hr.soc.politika :PEVAJ PARTIJO!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :PARTIJO MAJKO!!!!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :DAJ MI KRUTE KURĆĆĆĆĆINE PEŠKO \r\n", "PRIVMSG #hr.soc.politika :MiliJon ustaških ubica je spremno da kolje!! \r\n", "PRIVMSG #hr.soc.politika :Satanski masakri \r\n", "PRIVMSG #hr.soc.politika :DEČAK ZELEN OD MRŽNJE \r\n", "PRIVMSG #hr.soc.politika :PRIMAĆĆĆĆ KRUTIH CIGANSKIH KURĆĆĆĆĆĆINA \r\n", "PRIVMSG #hr.soc.politika :SAD SAM SE MLATIO PO ŽELUCU \r\n", "PRIVMSG #hr.soc.politika :ALLE JUDEN VERGASEN!!!!!!!!!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :AKTIVAC NABIJA GLAVU PASIVCA U KACU S GOVNIMA \r\n", "PRIVMSG #hr.soc.politika :BOZON! \r\n", "PRIVMSG #hr.soc.politika :PSYHOZA \r\n", "PRIVMSG #hr.soc.politika :Ja sam MNOGOSTRUK \r\n", "PRIVMSG #hr.soc.politika :==U== \r\n", "PRIVMSG #hr.soc.politika :Izjedam Jaffa kekse \r\n", "PRIVMSG #hr.soc.politika :ŽUDNJA PRKNADŽIJE ZA PRKNOM \r\n", "PRIVMSG #hr.soc.politika :Mamek me tera da si redovno mažem kraste na prstima \r\n", "PRIVMSG #hr.soc.politika :Ja sam mrtav čovek....... mrca...... \r\n", "PRIVMSG #hr.soc.politika :PARANJE UTROBE \r\n", "PRIVMSG #hr.soc.politika :Neš mi oduzet zoloft!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :NEHIGIJENA \r\n", "PRIVMSG #hr.soc.politika :NEPRANJE \r\n", "PRIVMSG #hr.soc.politika :ZA PENISE GOLE PEDERI VAS MOLE \r\n", "PRIVMSG #hr.soc.politika :Muškarac siše penis muškarcu, na kolenima u zahodu javnom \r\n", "PRIVMSG #hr.soc.politika :USHTRIA QLIRIMTARE E KOSOVES \r\n", "PRIVMSG #hr.soc.politika :Lep, velik drek, zapažene teksture i mirisa!!! \r\n", "PRIVMSG #hr.soc.politika :Mamek pokakio velik drek, hoh \r\n", "PRIVMSG #hr.soc.politika :Polevanjem dreka vodom nastala je čorbasta smesa \r\n", "PRIVMSG #hr.soc.politika :Trtili te crnački azilanti????? \r\n", "PRIVMSG #hr.soc.politika :ŽIVILI ČETNIČKI DERNECI \r\n", "PRIVMSG #hr.soc.politika :Napred, napred četnici!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Kad ustanem prvo piškim a onda uvek malo žderem \r\n", "PRIVMSG #hr.soc.politika :žderem Jaffa kekse! \r\n", "PRIVMSG #hr.soc.politika :LJUBLJENJE VRAGA U STRAŽNJICU!!!! \r\n", "PRIVMSG #hr.soc.politika :Grecam krastu pa opet mažem i obavijam flasterom \r\n", "PRIVMSG #hr.soc.politika :Ja ne pijem sopstveni URIN \r\n", "PRIVMSG #hr.soc.politika :Kurva mi je govorila da će piti moj urin \r\n", "PRIVMSG #hr.soc.politika :DAJ MI GUBICU RAZBIJAJ BOKSEROM \r\n", "PRIVMSG #hr.soc.politika :Ja sam BEDA - NIKO & NIŠTA! \r\n", "PRIVMSG #hr.soc.politika :Kakio sam, izbacio sigurno kilu dreka! \r\n", "PRIVMSG #hr.soc.politika :Smatraš me budalom? \r\n", "PRIVMSG #hr.soc.politika :POJEDI NOVAC I RECI 'HVALA TI ŽIVOTEEEEEEE' \r\n", "PRIVMSG #hr.soc.politika :NIMA UMENI NIKAPI SRBSKE KRFCE \r\n", "PRIVMSG #hr.soc.politika :PARENJE U SRODSTVU \r\n", "PRIVMSG #hr.soc.politika :REŽEM ŽILE BREZ TEBE \r\n", "PRIVMSG #hr.soc.politika :BUŠAN TI JE KAZAN, JUGOOFICIRU \r\n", "PRIVMSG #hr.soc.politika :TAKO TEPAŠ FLAŠI DREKOVAČE? \r\n", "PRIVMSG #hr.soc.politika :POSERITE se po meni!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Komad pizze čeka mameka ujutro, moj komentar: a ja sam pozdrao ostalih 7 \r\n", "PRIVMSG #hr.soc.politika :Digo se i ždero malo ribe bez ulja \r\n", "PRIVMSG #hr.soc.politika :Imam rupu na košulji, na laktu \r\n", "PRIVMSG #hr.soc.politika :MILIJON USTAŠA JE SPREMNO DA KOLJE U SVAKOM TRENUTKU! \r\n", "PRIVMSG #hr.soc.politika :Poždro sam sva medena srca \r\n", "PRIVMSG #hr.soc.politika :Naručio me mamek kod zubara \r\n", "PRIVMSG #hr.soc.politika :Mamek me je spasio da me ne strpaju \r\n", "PRIVMSG #hr.soc.politika :Koje KURVE u mojoj seriji!!! \r\n", "PRIVMSG #hr.soc.politika :Pomažem popišanom mameku! \r\n", "PRIVMSG #hr.soc.politika :Ja sam dječarac jarac \r\n", "PRIVMSG #hr.soc.politika :ISKUSNI PREVEJANI PEDERI \r\n", "PRIVMSG #hr.soc.politika :GOLO KOLJAŠTVO \r\n", "PRIVMSG #hr.soc.politika :Dragi Isuse, molim te oslobodi me pederluka!! \r\n", "PRIVMSG #hr.soc.politika :Odoh pod deku, mamek kaki umesto da jede \r\n", "PRIVMSG #hr.soc.politika :Mamek bi hteo da ga pazim celu noć! \r\n", "PRIVMSG #hr.soc.politika :NIšta još nisam spavao, svako malo moram piškiti \r\n", "PRIVMSG #hr.soc.politika :Zaljubljen si u mene pederu???? \r\n", "PRIVMSG #hr.soc.politika :NAŠMINKANI PASIVAC \r\n", "PRIVMSG #hr.soc.politika :PEDER JECA ZA KURCOM \r\n", "PRIVMSG #hr.soc.politika :Izluđuje me ludački STRAH koji me parališe! \r\n", "PRIVMSG #hr.soc.politika :Odoh kakiti \r\n", "PRIVMSG #hr.soc.politika :Iz nosa mi raste dlaka \r\n", "PRIVMSG #hr.soc.politika :Idem da jedem skroman obrok \r\n", "PRIVMSG #hr.soc.politika :O što volem SF serije \r\n", "PRIVMSG #hr.soc.politika :ČETNIKA UBITI KAO P S A !!!!!!!!!!!!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :PROKLETI SRBOČETNIČKI KOLJAČI!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Mamek zamolio da joj dam - jednu pusu :-))))))) \r\n", "PRIVMSG #hr.soc.politika :Ja sumnjam da možda imam DVE bešike/mjehura!! \r\n", "PRIVMSG #hr.soc.politika :Vadim goleme smeđe balce iz nosa \r\n", "PRIVMSG #hr.soc.politika :Probudio me mamek nemilosrdni \r\n", "PRIVMSG #hr.soc.politika :Treba ti ODSEĆI PENIS, najbolje satarom! \r\n", "PRIVMSG #hr.soc.politika :Možeš da mi puvaš i prdneš pod prozor!! \r\n", "PRIVMSG #hr.soc.politika :MUTEŽ U MOZGU \r\n", "PRIVMSG #hr.soc.politika :GMIZAVCI \r\n", "PRIVMSG #hr.soc.politika :SKUPO ĆU PRODATI SVOJU KOŽU!!! \r\n", "PRIVMSG #hr.soc.politika :KLAN, KLAN, PA ZAKLAN \r\n", "PRIVMSG #hr.soc.politika :Mamek voli sineka najviše na svetu!! \r\n", "PRIVMSG #hr.soc.politika :Probudim se i vidim - doživio sma opet IZLJEV u snu! \r\n", "PRIVMSG #hr.soc.politika :sanjao seks s maloleticama \r\n", "PRIVMSG #hr.soc.politika :Čelovjek Jarac \r\n", "PRIVMSG #hr.soc.politika :ROČNICI I PRIČUVNICI \r\n", "PRIVMSG #hr.soc.politika :Nemam poriv da zatučem mameka šipkom \r\n", "PRIVMSG #hr.soc.politika :NJihove pretnje su SNIMLJENE!!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Nemojte mene drugari, šalio sam se!!!!! \r\n", "PRIVMSG #hr.soc.politika :DEDA DŽUKELAMA LIŽE GUBICU \r\n", "PRIVMSG #hr.soc.politika :ŽIVIJA DOTUR IVO SANADER \r\n", "PRIVMSG #hr.soc.politika :SAMO UBIJANJA NA PAMETI LUDAKA \r\n", "PRIVMSG #hr.soc.politika :ŠTETA ŠTO NEMAM SABLJU \r\n", "PRIVMSG #hr.soc.politika :Ja sam invalid i ne mogu čučati i klečati \r\n", "PRIVMSG #hr.soc.politika :MLAĆENJE MAČKOM SA DEVET REPOVA \r\n", "PRIVMSG #hr.soc.politika :Opet sam češao čmar, svrbi \r\n", "PRIVMSG #hr.soc.politika :SRBSKO TLO NATOPITI RADIOAKTIVNIM URANOM \r\n", "PRIVMSG #hr.soc.politika :Ćuti ćććććetnićććććar \r\n", "PRIVMSG #hr.soc.politika :Uvaljo bi ja njega u crnački i ciganski DREK!!!!!! \r\n", "PRIVMSG #hr.soc.politika :JEBO GA ĆALE DUŠAN U PRKNO!!!! SMEĆE CIGANSKO!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :HAHAHAHHAHAHAA, CVILI OD STRAHA ČETNO!!!! \r\n", "PRIVMSG #hr.soc.politika :Mi HRvati te NEĆEMO :-) \r\n", "PRIVMSG #hr.soc.politika :Oprat ću ja vas SrBe u krvavoj kupelji! \r\n", "PRIVMSG #hr.soc.politika :saterao sam SrBu u mišju rupu!! \r\n", "PRIVMSG #hr.soc.politika :JA napadam kao besan pas \r\n", "PRIVMSG #hr.soc.politika :KOga ću prvog da trtim ovde??? \r\n", "PRIVMSG #hr.soc.politika :Fliktuacije u kemiji mozga drug.... \r\n", "PRIVMSG #hr.soc.politika :Pederastija druže..... \r\n", "PRIVMSG #hr.soc.politika :Nećeš me pomaknuti ni za jotu! \r\n", "PRIVMSG #hr.soc.politika :STAN JE MOJ! \r\n", "PRIVMSG #hr.soc.politika :Krckam zglobove na prstima, mamek kaže da mi je to od dide \r\n", "PRIVMSG #hr.soc.politika :PENIS UBOJICA \r\n", "PRIVMSG #hr.soc.politika :SELJAK SODOMIT \r\n", "PRIVMSG #hr.soc.politika :Cudi me da jos nisi shvatio da se sa Zecom ne raspravlja. Sto mislis, zasto ga svi normalni ljudi na ovoj grupi drze u filteru? \r\n", "PRIVMSG #hr.soc.politika :I dok ja preživam pod dekom govna ljuCka seru li seru \r\n", "PRIVMSG #hr.soc.politika :Imam o--durnu žgaravicu od odvratnih cigareta \r\n", "PRIVMSG #hr.soc.politika :JA NISAM HOMOSEKSUALAC, MENE NAPASTUJE HOMOSEKSUALNI DUH! \r\n", "PRIVMSG #hr.soc.politika :LOČI DREKOVAČU JUGOOFICIRU \r\n", "PRIVMSG #hr.soc.politika :POPIT ĆU LEK PROTIVU STRAHA \r\n", "PRIVMSG #hr.soc.politika :Mamek plače... platit ćete mi za svaku njegovu suzu, zlikovci!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :Kreten si ti! Ovo sad nisu gluposti, žele da nas izbace \r\n", "PRIVMSG #hr.soc.politika :Možemo samo da se dignemo u vazduh zajedno sa stanom!! \r\n", "PRIVMSG #hr.soc.politika :IMA meso pileće, ribu tunj, sve ima!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :SVE LAŽ DO LAŽI...... \r\n", "PRIVMSG #hr.soc.politika :JA NISAM ČOVEK MIRKO \r\n", "PRIVMSG #hr.soc.politika :Obožavam da žderem zobene pahuljice sa mlekom \r\n", "PRIVMSG #hr.soc.politika :Često povraćam \r\n", "PRIVMSG #hr.soc.politika :Podrigujem kao svinja \r\n", "PRIVMSG #hr.soc.politika :Moj mamek se zna piškiti u gaće i ja mu onda pomognem!! \r\n", "PRIVMSG #hr.soc.politika :Ja piškim u kahlicu ako je mamek na WC-u \r\n", "PRIVMSG #hr.soc.politika :JESTE, PRODAO VERU ZA VEČERU........... ALI STIĆĆĆĆI ĆĆĆĆE GA ĆĆĆĆĆĆETNIĆĆĆĆĆKA PRAVDA......... \r\n", "PRIVMSG #hr.soc.politika :Kakio sam, i žestoko si češao čmar \r\n", "PRIVMSG #hr.soc.politika :Ja žudim da si četkicom za zube češem čmar! \r\n", "PRIVMSG #hr.soc.politika :Al mamek mi kaže da to ne smem, da je čmar osetljiv \r\n", "PRIVMSG #hr.soc.politika :ŽIVOT TI JE UNIŠTEN OTKAD SI NAPAO NA ZECA!!! \r\n", "PRIVMSG #hr.soc.politika :UNIŠTENI STE S V I !!!!!!!!!!! \r\n", "PRIVMSG #hr.soc.politika :TI SI GOVNO \r\n", "PRIVMSG #hr.soc.politika :ULIČARU PRLJAVI \r\n", "PRIVMSG #hr.soc.politika :Vređao sam mameka LUDAČKI \r\n", "PRIVMSG #hr.soc.politika :Ja sam obično SMEĆE \r\n", "PRIVMSG #hr.soc.politika :Opet sam ga malo pre popio!! \r\n", "PRIVMSG #hr.soc.politika :Ja ne mogu da trpim jer sam bolesnik psihički \r\n", "PRIVMSG #hr.soc.politika :Iščačko sam si levo uvo i sad bolje čujem \r\n", "PRIVMSG #hr.soc.politika :Sve meni lepo piše u psihijatrijskom nalazu \r\n", "PRIVMSG #hr.soc.politika :Dragi mamek! toliko je drag.... \r\n", "PRIVMSG #hr.soc.politika :ŠTA PAMETUJEŠ, GLUPI \r\n", "PRIVMSG #hr.soc.politika :TI SI ILIJA BULLY \r\n", "PRIVMSG #hr.soc.politika :Kad sam patio za njom imao sam rupu u auri \r\n", "PRIVMSG #hr.soc.politika :GADNI SRbINE \r\n", "PRIVMSG #hr.soc.politika :Mamek me probudio urlanjem...... :-) \r\n", "PRIVMSG #hr.soc.politika :U-hu-hu, drugi put kakio danas \r\n", "PRIVMSG #hr.soc.politika :Volem da kakim, tako izbacujem otrove iz tela! \r\n", "PRIVMSG #hr.soc.politika :Ja sam viša rasa - ne perem se a ne smrdim! \r\n", "PRIVMSG #hr.soc.politika :Trbuh mi je naduven, u želucu mi fermentira.... \r\n", "PRIVMSG #hr.soc.politika :Odoh treći put da kakim... al nije proljev \r\n", "PRIVMSG #hr.soc.politika :Evo kakio sam ČETVRTI put danas! \r\n", "PRIVMSG #hr.soc.politika :Ti stigmatiziraš nas psihičke bolesnike, gade \r\n", "PRIVMSG #hr.soc.politika :Dok vi laprdate ja pomažem & pomažem svom mameku u kujini \r\n", "PRIVMSG #hr.soc.politika :yey, jeo sam skorman obrok zobene pahuljice s jagodom u mleku \r\n", "PRIVMSG #hr.soc.politika :Odoh pod deku da se molim Bogu \r\n", "PRIVMSG #hr.soc.politika :Odoh pod deku da se molim Bogu \r\n", "PRIVMSG #hr.soc.politika :DOĐI, GADE, DOĐI \r\n", "PRIVMSG #hr.soc.politika :KRVNIČE POGANA RASO \r\n", "PRIVMSG #hr.soc.politika :Odvratan je ovaj bot :-( \r\n", "PRIVMSG #hr.soc.politika :NABIJ GA \r\n", "PRIVMSG #hr.soc.politika :ROBOVI GREHA \r\n", "PRIVMSG #hr.soc.politika :SATANSKO SKVIČANJE \r\n", "PRIVMSG #hr.soc.politika :JEBI BARABU BRE \r\n", "PRIVMSG #hr.soc.politika :Odoh probati pod deku..... \r\n", "PRIVMSG #hr.soc.politika :Vršim defragmentaciju diska! \r\n", "PRIVMSG #hr.soc.politika :Ima fragmentiranih datoteka \r\n", "PRIVMSG #hr.soc.politika :Brabonjci ispadaju iz čmara \r\n", "PRIVMSG #hr.soc.politika :Podriguju mi se jetrene knedle \r\n", "PRIVMSG #hr.soc.politika :JEBI JAREĆE PRKNO \r\n", "PRIVMSG #hr.soc.politika :LJUBAV :-) \r\n", "PRIVMSG #hr.soc.politika :NABIJAĆĆĆĆINA PEDERA U PRKNO \r\n", "PRIVMSG #hr.soc.politika :Njištim kao konj, lud sam \r\n", "PRIVMSG #hr.soc.politika :Škrgućem zubima i režim \r\n", "PRIVMSG #hr.soc.politika :kreveljim se \r\n", "PRIVMSG #hr.soc.politika :1800 UDARACA PENISOM U ČMAR U SEKUNDI? \r\n", "PRIVMSG #hr.soc.politika :Toliko sam ponosan što sam INVALID :-) \r\n", "PRIVMSG #hr.soc.politika :Ja moram da izgovaram REČI \r\n", "PRIVMSG #hr.soc.politika :PIJ MUŠKI URIN \r\n", "PRIVMSG #hr.soc.politika :JEL I TAMO IMA PEDERA? \r\n", "PRIVMSG #hr.soc.politika :MASOVNA KUPOVINA VEŠTAČKIH VAGINA \r\n", "PRIVMSG #hr.soc.politika :Imam majicu prljavu od pepela.... oseća se i užegli smrad.... \r\n", "PRIVMSG #hr.soc.politika :Ne pada mi na pamet da se operem! \r\n", "PRIVMSG #hr.soc.politika :HRANIT ĆU JA TEBE GOVNIMA \r\n", "PRIVMSG #hr.soc.politika :SALATA OD SRbSKE DECE \r\n", "PRIVMSG #hr.soc.politika :ZAGRIZI GOVNO \r\n", "PRIVMSG #hr.soc.politika :Povratim ti po vratu \r\n", "PRIVMSG #hr.soc.politika :ČEKA VAS 50 GODINA MUČENJA \r\n", "PRIVMSG #hr.soc.politika :JA NE SMEM NI DA VIDIM NOŽ \r\n", "PRIVMSG #hr.soc.politika :POKENJAM TI SE NA USNE \r\n", "PRIVMSG #hr.soc.politika :U, kako sam kakio, u \r\n", "PRIVMSG #hr.soc.politika :Čim sam pojeo - kakio \r\n", "PRIVMSG #hr.soc.politika :SRbOČETNIČKA ARMADA....... \r\n", "PRIVMSG #hr.soc.politika :https://www.facebook.com/watch/?v=2324409530910955 \r\n", "PRIVMSG #hr.soc.politika :POKAKIM TI SE PRAVO U USNE \r\n", "PRIVMSG #hr.soc.politika :Džinofska klaonica..... \r\n", "PRIVMSG #hr.soc.politika :POdešavam kompjuter, večeras mi ga je doneo majstor sa popravka!! \r\n", "PRIVMSG #hr.soc.politika :NAUČEN SAM NA GOLO TRPLJENJE \r\n", "PRIVMSG #hr.soc.politika :TRTIM MIRKA U PRKNO \r\n", "PRIVMSG #hr.soc.politika :Šaralampov Krycaj \r\n", "PRIVMSG #hr.soc.politika :Promjene donose smrt \r\n", "PRIVMSG #hr.soc.politika :Mrzim promjene \r\n", "PRIVMSG #hr.soc.politika :Ja mrzim automobile, konje i pse \r\n", "PRIVMSG #hr.soc.politika :Moraš ti probati TRTENJE U ČMAR! \r\n", "PRIVMSG #hr.soc.politika :Popiškio sam se u gaće! \r\n", "PRIVMSG #hr.soc.politika :da se skineš nag i potrčiš ulicom sa sekirom u ruci????? \r\n", "PRIVMSG #hr.soc.politika :3 sata ukočenog ležanja zatvorenih očiju, heh \r\n", "PRIVMSG #hr.soc.politika :Ne mogu...................... \r\n", "PRIVMSG #hr.soc.politika :Prodaješ mi četničku bozu......... \r\n", "PRIVMSG #hr.soc.politika :IZgleda da ću opet kakiti od štrudli \r\n", "PRIVMSG #hr.soc.politika :Ja nijesam Hrki \r\n", "PRIVMSG #hr.soc.politika :MOJ ČMAR JE UZAK, NEMA ULJEZA UNJEMU\r\n", "PRIVMSG #hr.soc.politika :LAŽ\r\n", "PRIVMSG #hr.soc.politika :Kao dečak sam kopao prstom po sopstvenom čmaru i vadio drek van\r\n", "PRIVMSG #hr.soc.politika :ZNam sve o čmarovima :-) :-(\r\n", "PRIVMSG #hr.soc.politika :TRT TRT TRTICA :-)\r\n", "PRIVMSG #hr.soc.politika :SAMO SAM ANALAN, ALI NE PEDER\r\n", "PRIVMSG #hr.soc.politika :ZAŠTO ONDA NE PRIMAM PENISE U SVOJ ČMAR, HA??\r\n", "PRIVMSG #hr.soc.politika :MNOGI PEDERI SU ME HTELI, A JA SAM BEŽAO\r\n", "PRIVMSG #hr.soc.politika :Meni je zakržljao mali prst na levoj ruci\r\n", "PRIVMSG #hr.soc.politika :Ja sam moćan momak a ti si PIZDEK koji anonimno čita i skriva se\r\n", "PRIVMSG #hr.soc.politika :Odoh da kakim od gomile višanja koje sam poždro\r\n", "PRIVMSG #hr.soc.politika :Kakio, pa češao čmar, dandalo i skrotum\r\n", "PRIVMSG #hr.soc.politika :Pedro je moćan peder\r\n", "PRIVMSG #hr.soc.politika :RAZMAZUJEM TI GOVNO PO GUBICI MIRKO\r\n", "PRIVMSG #hr.soc.politika :MASAKRI SMAKA SVETA\r\n", "PRIVMSG #hr.soc.politika :Kakio sam brzo ko vidra\r\n", "PRIVMSG #hr.soc.politika :Čelovjek Mozgoyed\r\n", "PRIVMSG #hr.soc.politika :JA SAM IZVORNI MEDITERANAC\r\n", "PRIVMSG #hr.soc.politika :KAD BUDEM KREPAO BULIJI ĆE URLATI OD SLADOSTRAŠĆA\r\n", "PRIVMSG #hr.soc.politika :SVINJE ĆE SE VALJATI U BLATU I DREKU\r\n", "PRIVMSG #hr.soc.politika :SMRDI MI SKROTUM\r\n", "PRIVMSG #hr.soc.politika :bwuahahahahahahahhahahh\r\n", "PRIVMSG #hr.soc.politika :https://www.facebook.com/gayshitpostingar/\r\n", "PRIVMSG #hr.soc.politika :Ja sam užasno moćan bednik, dobivam milostinju i onda cvilim od radosti\r\n", "PRIVMSG #hr.soc.politika :POKORITE SE PEDRU\r\n", "PRIVMSG #hr.soc.politika :Zeka kakio kobasu :-), pa jeo jabuku pa kahvu\r\n", "PRIVMSG #hr.soc.politika :prd prd prd\r\n", "PRIVMSG #hr.soc.politika :Kad mi se ždere - ja žderem!\r\n", "PRIVMSG #hr.soc.politika :Žderem još 1 konzervu tunja sa teksaškim miksom povrća :-)\r\n", "PRIVMSG #hr.soc.politika :Smrdim ko FUTAVAC\r\n", "PRIVMSG #hr.soc.politika :Iz dana u dan sve više SMRDIM........\r\n", "PRIVMSG #hr.soc.politika :Sad bih još mogo da operem skrotum i međunožje i - kosu!\r\n", "PRIVMSG #hr.soc.politika :OŠ ME UBIT?\r\n", "PRIVMSG #hr.soc.politika :PROKLETI CRNCI ODGRIZAJ IM LOBANJE\r\n", "PRIVMSG #hr.soc.politika :SAMO UBIJAJ CRNACA ŠTO VIŠE!\r\n", "PRIVMSG #hr.soc.politika :VUDU ZOMBIJI.........\r\n", "PRIVMSG #hr.soc.politika :Žderao sam skroman obrok oslića i žganaca/palente\r\n", "PRIVMSG #hr.soc.politika :Obožavaj GOLI DIVOVSKI PENIS!\r\n", "PRIVMSG #hr.soc.politika :GOLA ŽILAVA HOMOSEKSUALNOST\r\n", "PRIVMSG #hr.soc.politika : HOĆEŠ LI DA SIŠEŠ P E N I S ???????????????????\r\n", "PRIVMSG #hr.soc.politika :To ti je sve MIrko jedan KRUG zapravo, i na jednom mestu se dotiču ekstremna ljevica i ekstremna desnica. Na tom mjestu sedim JA\r\n", "PRIVMSG #hr.soc.politika :SEKIRČETOM PO LOBANJI BREEEEEEEE............\r\n", "PRIVMSG #hr.soc.politika :Spao mi je nokat sa palca nožnog, yey\r\n", "PRIVMSG #hr.soc.politika :MOj tatek je imao bič, a sada i ja imam bič - korbač\r\n", "PRIVMSG #hr.soc.politika :A ja ležem sa muškarcem i budim se sa jarcem\r\n", "PRIVMSG #hr.soc.politika :Muči me opet srčana čakra sad popodne\r\n", "PRIVMSG #hr.soc.politika :tanka mi je aura.....\r\n", "PRIVMSG #hr.soc.politika :Nekako mi se podebljala aura na srčanoj čakri, hu\r\n", "PRIVMSG #hr.soc.politika :A JA SAM BIO PRVI KURVAR GRADA ZAGREBA\r\n", "PRIVMSG #hr.soc.politika :Kad su me pipali još nisam bio dominantan\r\n", "PRIVMSG #hr.soc.politika :Zdepasti_Zeka is now known as GAY_GLODAR\r\n", "PRIVMSG #hr.soc.politika :Invalid se digao, a vi niste prestajali da prdite o meni\r\n", "PRIVMSG #hr.soc.politika :HOMOSEKSUALNOŠĆ?\r\n", "PRIVMSG #hr.soc.politika :PSINO\r\n", "PRIVMSG #hr.soc.politika :Zeka loče punu čašu sa tabletom multivitamina\r\n", "PRIVMSG #hr.soc.politika :EJ ČETNO! GDE TI JE \"MIRKO\"?!?!?!?!?!?!? KAJ NIJE \"DOŠO\"??!?!?!?\r\n", "PRIVMSG #hr.soc.politika :3 put su me pipali\r\n", "PRIVMSG #hr.soc.politika :UJMOCA ISINA IDUVA SVETOGA AMIN\r\n", "PRIVMSG #hr.soc.politika :ĐIRČ\r\n", "PRIVMSG #hr.soc.politika :UGUŠI SE KURĆĆĆĆĆĆĆĆINOM, PEDERĆĆĆĆĆINO\r\n", "PRIVMSG #hr.soc.politika :NA MENE SI NAŠAO ONANISATI U SVOJIM PEDERSKIM FANTAZMAGORIJAMA, LUDAČE?!?!?!?\r\n", "PRIVMSG #hr.soc.politika :SRBOSEČA SRBE SEČE\r\n", "PRIVMSG #hr.soc.politika :OPSEDNUT SI PUŠENJEM PENISA, PEDERU\r\n", "PRIVMSG #hr.soc.politika :Noćno mučenje........ mučim se........\r\n", "PRIVMSG #hr.soc.politika :STARI I PREVEJANI HOMOSEKSUALAC.........\r\n", "PRIVMSG #hr.soc.politika :SRbSKA ŽENA JE KURVA, A RVACKA JE GOVNO\r\n", "PRIVMSG #hr.soc.politika :AFRO - ETNO - ČETNO\r\n", "PRIVMSG #hr.soc.politika :GOLO DETE TERAJ NAULICU BRE\r\n", "PRIVMSG #hr.soc.politika :OOOOOOOOOOOO\r\n", "PRIVMSG #hr.soc.politika :Peder si Ilija, peder koji onaniše na grube mišićave primitivce!\r\n", "PRIVMSG #hr.soc.politika :VEWLIKOSRBI!!!!!!! NEĆETE NIKAD VIŠE!!!!!!!!!!!\r\n", "PRIVMSG #hr.soc.politika :SPREČIT ĆU JA SERVSKU VOJSKU U AGRESIJI NA RVACKU\r\n", "PRIVMSG #hr.soc.politika :VELIKI MOĆNIK ZEKA, HILJADE KURVI KLEČI PRED NJIM\r\n", "PRIVMSG #hr.soc.politika :Nemate poYma s kim sam sada razgovarao preko FB, sa jednom - ženom! :-)\r\n", "PRIVMSG #hr.soc.politika :M.O.Ć.\r\n", "PRIVMSG #hr.soc.politika :Zeka je MOĆAN\r\n", "PRIVMSG #hr.soc.politika :Zeka moćno prosjači\r\n", "PRIVMSG #hr.soc.politika :POLA\r\n", "PRIVMSG #hr.soc.politika :Danas sam vidio 1 lepu devojku u kafiću, dečačkog izgleda sa kratkom kosom, darkerica\r\n", "PRIVMSG #hr.soc.politika :Drugari ja se neprekidno ČEŠEM\r\n", "PRIVMSG #hr.soc.politika :Evo poždrao pola štrudle\r\n", "PRIVMSG #hr.soc.politika :PROKLETI SRbI!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n", "PRIVMSG #hr.soc.politika :SMRSKAJ SRbE!!!!!!!!!!!!!!!!!!\r\n", "PRIVMSG #hr.soc.politika :Samo da je instant kave, cigareta i kolača :-)\r\n", "PRIVMSG #hr.soc.politika :Šta ću sad da gledam kad je gotova moja serija?\r\n", "PRIVMSG #hr.soc.politika :Pogle ga kak ima srpski nos :-D\r\n", "PRIVMSG #hr.soc.politika :NEĆETE DUGO!!!!!!!!!!!!!!!!\r\n", "PRIVMSG #hr.soc.politika :TURKOVLAŠKI NAKOT UME SAMO DA PLJAČKA I KOLJE\r\n", "PRIVMSG #hr.soc.politika :6,5 sati sna\r\n", "PRIVMSG #hr.soc.politika :POĆĆĆĆNITE DA KOLJETE, ČČČETNICCCI!!!!!!!!!!!!\r\n", "PRIVMSG #hr.soc.politika :ČEREČI ČETNIČARU\r\n", "PRIVMSG #hr.soc.politika :BODENJE, UBADANJE\r\n", "PRIVMSG #hr.soc.politika :KOPRIVA U VAGINI A ĐUMBIR U ČMARU\r\n", "PRIVMSG #hr.soc.politika :Kad ja imam za jesti - ja žderem, kad nemam - gladujem, heh\r\n", "PRIVMSG #hr.soc.politika :Sad sam skoro pao u nesvest od kašlja od cigareta, yao\r\n", "PRIVMSG #hr.soc.politika :MI RVATI KOLJEMO SA STRAŠĆU\r\n", "PRIVMSG #hr.soc.politika :UŠMRKAVANJE DROGE U NOZDRVU \r\n", "PRIVMSG #hr.soc.politika :Stigle cigarete :-)\r\n", "PRIVMSG #hr.soc.politika :Probat ću isprositi i koji keks\r\n", "PRIVMSG #hr.soc.politika :Kašljem, ispuhujem nos, imam neki virus ali slab\r\n", "PRIVMSG #hr.soc.politika :Gadni peder se uvlaććći u ćććoveććććji ćććććmar\r\n", "PRIVMSG #hr.soc.politika :POpiškim ti se na muške usne!!\r\n", "PRIVMSG #hr.soc.politika :MRŽNJA PREMA SRbIMA SVIM SRCEM!!!\r\n", "PRIVMSG #hr.soc.politika :Širite se bre od 1804. u svim smerovima\r\n", "PRIVMSG #hr.soc.politika :Treba vas satrti\r\n", "PRIVMSG #hr.soc.politika :Ja sam već 20 godina dominantan!\r\n", "PRIVMSG #hr.soc.politika :Grecam skorene kraste iz nosa\r\n", "PRIVMSG #hr.soc.politika :POdrezujem par dlaka na kosi s leve strane\r\n", "PRIVMSG #hr.soc.politika :Šiašam se sam već 30 godina........\r\n", "PRIVMSG #hr.soc.politika :ILIJA MANDIĆ JE GLADAN KURĆĆĆINE!!!\r\n", "PRIVMSG #hr.soc.politika :Upregnut ću susedu da mi donosi voćne štrudle po 8 kuna\r\n", "PRIVMSG #hr.soc.politika :Treba se obžderavati u slatkom\r\n", "PRIVMSG #hr.soc.politika :Zove me Darija... :-)))))))))) napričali se, yeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :O kako mi je pasala palačinka sa čokoladom\r\n", "PRIVMSG #hr.soc.politika :Zamolio sam susedu da mi kupi štrudle voćne\r\n", "PRIVMSG #hr.soc.politika :Stavio sam novooprani tepih u klozet\r\n", "PRIVMSG #hr.soc.politika :Sve aparate u kući imam nove, yeeeeeeeeee\r\n", "PRIVMSG #hr.soc.politika :Odoh da piškim\r\n", "PRIVMSG #hr.soc.politika :MLAD MULAT??\r\n", "PRIVMSG #hr.soc.politika :Femmi Boy\r\n", "PRIVMSG #hr.soc.politika :Jedem das Seine.......\r\n", "PRIVMSG #hr.soc.politika :U zemaljskom životu blagoslovljen patnjom, na kraju dobiva sve šta je zaslužio\r\n", "PRIVMSG #hr.soc.politika :Božji čovek, da\r\n", "PRIVMSG #hr.soc.politika :Ajoj deko, utebi je meko! reko Zeko\r\n", "PRIVMSG #hr.soc.politika :TI ustao a ja ću pod deku\r\n", "PRIVMSG #hr.soc.politika :Advocatus Diaboli :-)\r\n", "PRIVMSG #hr.soc.politika :A ona inače ima puno novaca ali baš voli da pomaže ljudima, ne samo meni, puno ljudi, kao Anđeo je :-))\r\n", "PRIVMSG #hr.soc.politika :Ne kuca mi na vrata ali kad ona ZA SEBE ide da kupi nešto pita me jel i meni šta treba....\r\n", "PRIVMSG #hr.soc.politika :KAMERA TURENA U PIZDURINU\r\n", "PRIVMSG #hr.soc.politika :ZAKLATI MORAM...........\r\n", "PRIVMSG #hr.soc.politika :URLAM PO KUJINI KA NEZDRAV\r\n", "PRIVMSG #hr.soc.politika :Bez večere pod deku.........\r\n", "PRIVMSG #hr.soc.politika :BOG. LJUBAV. DOBROTA!\r\n", "PRIVMSG #hr.soc.politika :Zeka kakio, kakvo olakšanje\r\n", "PRIVMSG #hr.soc.politika :DOšla je bila već 2001. pa smo preživeli prosjačeći i prodajući dedine zlatne zube\r\n", "PRIVMSG #hr.soc.politika :Ohrabrujem svaku subverziju protiv Sistema\r\n", "PRIVMSG #hr.soc.politika :Pisano je: LJUBAV je jaka kao Smrt!\r\n", "PRIVMSG #hr.soc.politika :SVATKO tko DANAS ima nofce je proklet........danas i OVDE\r\n", "PRIVMSG #hr.soc.politika :SIFILIS ILI LUES?!?!?!?!!?!?!?\r\n", "PRIVMSG #hr.soc.politika :JAHANJE PASIVCA NA KURCU??????????????!?!?!?!?!??!!\r\n", "PRIVMSG #hr.soc.politika :SUBMISIVAC KOJI U PSEĆOJ ZDELICI DOBIVA OBROK GOVANA?!?!!?\r\n", "PRIVMSG #hr.soc.politika :Svi smo svedoci - oko 3 godine intenzivne propagande je dovoljno da jedan narod poludi\r\n", "PRIVMSG #hr.soc.politika :Treba na kolena pasti i zahvaljivati\r\n", "PRIVMSG #hr.soc.politika :jecati i cviliti dominantno\r\n", "PRIVMSG #hr.soc.politika :Sve poderano sam bacio\r\n", "PRIVMSG #hr.soc.politika :a za nagradu - šiba\r\n", "PRIVMSG #hr.soc.politika :NERAST NADNIČAR\r\n", "PRIVMSG #hr.soc.politika :NERAST!!\r\n", "PRIVMSG #hr.soc.politika :Napada me jedna Domina što sam se nazvo 'intelektualcem' :-D\r\n", "PRIVMSG #hr.soc.politika :Cviljenje........\r\n", "PRIVMSG #hr.soc.politika :U--hu--hu, kako sam Dominantan!!\r\n", "PRIVMSG #hr.soc.politika :Prepun sam madeža po telu i stalno rastu novi\r\n", "PRIVMSG #hr.soc.politika :MONSTRUOZNA MRŽNJA PREMA RVATU\r\n", "PRIVMSG #hr.soc.politika :NERAST KAO OBJEKT POŽUDE\r\n", "PRIVMSG #hr.soc.politika :Bole me prepone, madež na preponi mi se tare o hlače, yay\r\n", "PRIVMSG #hr.soc.politika :Unošenje u lice i dihanje za ovratnik........\r\n", "PRIVMSG #hr.soc.politika :Imam 3 male sličice mameka u sobi i u kujini\r\n", "PRIVMSG #hr.soc.politika :Ima jedna Hrvatica koja živi u Nemačkoj, ona se pali na muški znoj i smrad :-)\r\n", "PRIVMSG #hr.soc.politika : Da je ponižavam da udiše vonj mošusa sa mojih muda\r\n", "PRIVMSG #hr.soc.politika :Dajte mi stare, okorele i raspale KURVE!\r\n", "PRIVMSG #hr.soc.politika :Sad više nemam ništa poderano na sebi!\r\n", "PRIVMSG #hr.soc.politika :Pojeo sam i par zalogaja sira i vuršta uz krastavac\r\n", "PRIVMSG #hr.soc.politika :Annie Lennox peva pesmu Doubleplusgood\r\n", "PRIVMSG #hr.soc.politika :Dvaputvišedobar patkogovoritelj\r\n", "PRIVMSG #hr.soc.politika :Pod deku nakon žderanja skromnog suhog obroka\r\n", "PRIVMSG #hr.soc.politika :Svima nam je ntko umro od rodbine u tih 6 godina\r\n", "PRIVMSG #hr.soc.politika :Čim netko obrati pažnju na bednika zeca ja cvetam :-)\r\n", "PRIVMSG #hr.soc.politika :U klozetu imam grijalicu na zidu koju je ugradio prijatelj-majstor\r\n", "PRIVMSG #hr.soc.politika :Još bdijem u kujini slušam muziku i razmišljam a sad sam se vratio u sobu\r\n", "PRIVMSG #hr.soc.politika :KO oće dame zakolje zato što spavam - nek dođe da me zakolje!!!!\r\n" ] teranje = ["socna pica","lizi picu","vlazna pica","meka,spremna","pohotna pica","https://pbs.twimg.com/media/EAt9NNwXsAEo_Lz?format=jpg&name=small","https://www.menshealth.rs/stil/9832/higijenska-abeceda-za-svakog-muskarca"] zvijeri = ["Threadripper 2990WX","Xeon W-3175X"] jadnici = ["mali","veliki","ekstreman","pomalo"] response_get tm ref stdgen gsref pl s buf len = do gen <- readIORef stdgen str <- peekCStringLen (buf,fromIntegral len) if str == [] then do let (val,gen') = randomR (0,(length list_zeka)-1) gen write pl s $ list_zeka !! val writeIORef stdgen gen' t <- getPOSIXTime writeIORef tm t return 0 else do putStrLn $ "got "++str if isSuffixOf "\r\n" str then do b <- readIORef ref gs <- readIORef gsref let (res,gen',gs') = parse (b++str) gen gs putStrLn $ "Writing : "++ res writeIORef ref [] writeIORef stdgen gen' writeIORef gsref gs' write pl s res else do b <- readIORef ref writeIORef ref (b++str) pl_read pl s return 0 response_written pl s = do putStrLn "default done_write" pl_read pl s return 0 parse str stdgen gs = foldl parse_line ([],stdgen,gs) $ lines str where parse_line (s,stdgen,gs) l = case words l of ("PING":xs) -> (s++"PONG "++unwords xs++"\r\n",stdgen,gs) (_:"004":xs) -> (s++"JOIN :#hr.soc.politika\r\n",stdgen,gs) (_:"433":xs) -> let (s',[gen]) = nick [stdgen] in (s++"NICK "++s'++"\r\n" ,gen,gs) (who:"PRIVMSG":xs) -> let (str,gen,gs') = response (parse_who who) xs in (s++str,gen,gs') (who:"JOIN":xs) -> (s++(if parse_who who /= "zeka_bot" then "PRIVMSG #hr.soc.politika :Hello, " else "PRIVMSG #hr.soc.politika :Hi folks, ")++parse_who who++"\r\n",stdgen,gs) xs -> case find (=="response") xs of Nothing -> (s,stdgen,gs) _ -> (s++"USER zeka_bot 8 * :zeka_bot\r\n",stdgen,gs) parse_who (w:who) = if w == ':' then parse_who who else if w == '!' then [] else w:parse_who who response who (channel:cmds) = parse cmds where parse ((_:cmd'):cmds) = case cvt cmd' of cmd | cmd == "ustaša" || cmd == "budala" || cmd == "ustasa" || cmd == "усташа" || cmd == "cetnik" || cmd == "četnik" || cmd == "четник" || cmd == "komunist" || cmd == "комунист" || cmd == "peder" || cmd == "pederčina" || cmd == "srbin" || cmd == "србин" || cmd == "hrvat" || cmd == "хрват" || cmd == "crnogorac"|| cmd == "musliman" || cmd == "katolik" || cmd == "pravoslavac" || cmd == "židov" || cmd == "zidov" || cmd == "invalid" || cmd == "decak" || cmd == "dečak" || cmd == "dječak" || cmd == "znanstvenik" || cmd == "naučnik" || cmd == "kvir" || cmd == "bednik" || cmd == "jadnik" -> let (val,gen) = (case (cmd,who) of ("crnogorac","imandic")-> randomR (90::Int,100) stdgen ("crnogorac","IkaPrisnazitelj")-> randomR (90::Int,100) stdgen (cmd,"Zdepasti_Zeka") | cmd== "invalid" || cmd == "kvir" || cmd == "katolik" || cmd == "dečak" || cmd == "bednik" || cmd == "budala" -> randomR (80::Int,100) stdgen (cmd,"Stefan_J") | cmd == "naučnik" || cmd == "znanstvenik" -> randomR (85::Int,100) stdgen _ -> randomR (0::Int,100) stdgen) in case cmds of [] | cmd == "jadnik" ->("PRIVMSG #hr.soc.politika "++":"++ who ++ " ti si "++ jadnici !! (val `mod` (length jadnici)) ++ " jadnik\r\n",gen,gs) [] | cmd /= "jadnik" -> ("PRIVMSG #hr.soc.politika "++":"++ who++", you are "++show val++"% "++cmd'++"\r\n",gen,gs) (w:[]) -> ("PRIVMSG #hr.soc.politika "++":"++w++" is "++show val++"% "++cmd'++"\r\n",gen,gs) _ -> ("",gen,gs) cmd | cmd == "calc" -> ("PRIVMSG #hr.soc.politika "++":"++(calculate $ unwords cmds) ++ "\r\n",stdgen,gs) cmd | cmd == "quote" -> let (val,gen) = randomR(0,(length list_zeka)-1) stdgen in (list_zeka!!val,gen,gs) cmd | cmd == "fortune" -> unsafePerformIO $ do strs <- readProcess "fortune" ["-s","-a"] [] return (sendList $ lines $ strs,stdgen,gs) cmd | cmd == "teraj" -> let (val,gen) = randomR(0,(length teranje)-1) stdgen in (sendList $ [teranje!!val],gen,gs) cmd | cmd == "zvijer" -> let (val,gen) = randomR(0,(length zvijeri)-1) stdgen in (sendList $ [zvijeri!!val],gen,gs) cmd | cmd == "h" -> case cmds of [] -> if gameStatus gs /= Guessing then let (gs',gen') = newGame stdgen in (sendList $ displayState gs',gen',gs') else (sendList $ displayState gs,stdgen,gs) cmds -> let (res',gs',gen') = gameLoop gs cmds stdgen in (sendList res',gen',gs') _ -> ("",stdgen,gs) sendList strs = foldl cumul [] strs where cumul s str = s++"PRIVMSG #hr.soc.politika :"++str++"\r\n" cvt str = fmap toLower str type Operator = Rational -> Rational -> Rational type Entry = (String, Operator) type Register = [Entry] modulu :: Rational -> Rational -> Rational modulu a b = toRational ((round (fromRational a::Double)) `mod` (round (fromRational b::Double))) operatorRegister :: Register operatorRegister = [ ("-", (-)), ("+", (+)), ("/", (/)), ("*", (*)), ("%", modulu) ] --main = print $ calculate "3 * 2 + 5 / 2" calculate :: String -> String calculate str = case (eval operatorRegister . words) str of Just r -> printf "%.2f" (fromRational r::Double) Nothing -> "Nothing" eval :: Register -> [String] -> Maybe Rational eval [] _ = Nothing -- No operator found. eval _ [] = Nothing -- If a operator don't have anything to operate on. eval _ [number] = let a :: Maybe Double = readMaybe number in case a of Just a -> Just (toRational a) Nothing -> Nothing eval ((operator, function):rest) unparsed = case span (/=operator) unparsed of (_, []) -> eval rest unparsed (beforeOperator, afterOperator) -> function <$> (eval operatorRegister beforeOperator) <*> (eval operatorRegister $ drop 1 afterOperator) wordsPath :: FilePath wordsPath = "words.txt"-- "/usr/share/dict/words" data GameState = GameState { _wordsToGuess :: [String] , guesses :: [[String]] } data GameStatus = Guessing | GameWon | GameLost deriving Eq hangmanImages :: [[String]] hangmanImages = transpose [ [ " ", " O ", " O ", " O ", " O " , "_O " , "_O_" ] , [ " ", " ", " | ", " | ", " | " , " | " , " | " ] , [ " ", " ", " ", "/ ", "/ \\", "/ \\", "/ \\" ] ] fullHangmanImage :: Int -> [String] fullHangmanImage index = "=========" : "| |" : map ("| " ++) img where img = hangmanImages !! index maxWrongGuesses :: Int maxWrongGuesses = length hangmanImages - 1 numberOfWrongGuesses :: GameState -> Int numberOfWrongGuesses (GameState words' guesses') = length $ filter (charNotInWord.head.concat) guesses' where charNotInWord c = c `notElem` concat words' gameStatus :: GameState -> GameStatus gameStatus (GameState words' guesses') | isGuessed = GameWon | isLastGuess = GameLost | otherwise = Guessing where isGuessed = guesses' /= [] && (all isCharInGuesses (concat words') || concat words' == (concat.last) guesses') isCharInGuesses x = x `elem` map (head.head) guesses' gameState = GameState words' guesses' isLastGuess = numberOfWrongGuesses gameState == maxWrongGuesses displayState :: GameState -> [String] displayState gameState@(GameState words' guesses') = fullHangmanImage' ++ case gameStatus gameState of Guessing -> [ "Word to guess: " ++ wordWithGuesses , "Guesses: " ++ (unwords.concat) guesses' ] GameWon -> [ "CONGRATULATIONS!" , "You correctly guessed the word " ++ unwords words' , " in " ++ show (length guesses') ++ " tries " ] GameLost -> [ "YOU FAILED!" , "You failed to guess the word " ++ unwords words' ] where fullHangmanImage' = fullHangmanImage currentHangmanIndex currentHangmanIndex = numberOfWrongGuesses gameState wordWithGuesses = blankOrChar <$> unwords words' blankOrChar c | c `elem` (map (head.head)) guesses' = c | c == ' ' = c | otherwise = '_' gameLoop :: GameState -> [String]-> StdGen -> ([String],GameState,StdGen) gameLoop gameState words' gen = let gameState' = gameState { guesses = guesses gameState ++ [words'] } res = displayState gameState' in if gameStatus gameState == Guessing then (res,gameState',gen) else let (gs',gen') = newGame gen in (displayState gs',gs',gen') newGame :: StdGen -> (GameState,StdGen) newGame stdgen = unsafePerformIO $ do contents <- readFile wordsPath let words' = map words $ lines contents (randomNumber,gen) = randomR (0,length words'-1) stdgen randomWord = words' !! randomNumber return (GameState randomWord [],gen) From simon at joyful.com Wed Sep 22 03:57:11 2021 From: simon at joyful.com (Simon Michael) Date: Tue, 21 Sep 2021 17:57:11 -1000 Subject: [Haskell-cafe] ANN: hledger-1.23 Message-ID: <896CE907-6E95-43D6-8BA4-10EF132CBDAE@joyful.com> We are very pleased to announce.. ..that the hledger repo recently passed 10000 commits. See https://hledger.org/CREDITS.html for more details, perhaps your name is there. Also.. hledger 1.23 ! https://hledger.org/release-notes.html#hledger-1-23 describes the user-visible changes. Highlights include: - Capital gains reporting (`bal --gain`) - Separate symbol/number display (`--commodity-column`) - Command line commodity styling (`-c|--commodity-style`) - budget selection (`bal --budget=BUDGETNAME`) - weekday/weekend recurrence (`~ every weekday ...`) - 10% speedup - Bugfixes. Thank you to release contributors: Stephen Morgan, Lawrence Wu, Jakob Schöttl, Dmitry Astapov, Malte Brandy, Arsen Arsenović, Arjen Langebaerd, Alan Young, Daniel Gröber. hledger (https://hledger.org) is a dependable, cross-platform "plain text accounting" tool, with command-line, terminal and web interfaces. It is an actively maintained, largely compatible reimplementation of Ledger CLI with many improvements. You can use it to track money, time, investments, cryptocurrencies, inventory and more. See also the Plain Text Accounting site (https://plaintextaccounting.org). https://hledger.org/download shows all the ways to install hledger on mac, windows or unix (stack, cabal, brew, nix, CI binaries, your package manager..). Or, run this bash script to install or upgrade to the latest release: $ curl -sO https://raw.githubusercontent.com/simonmichael/hledger/master/hledger-install/hledger-install.sh $ less hledger-install.sh # security review $ bash hledger-install.sh New users, check out https://hledger.org/quickstart or the tutorials (with pictures) at hledger.org -> FIRST STEPS or the https://hledger.org/videos.html. To get help, see https://hledger.org#help, and join our chat via Matrix: - #hledger:matrix.org (http://matrix.hledger.org) or Libera (they are bridged): - #hledger:libera.chat (http://irc.hledger.org) Beginners and experts, contributors, sponsors, and all feedback are most welcome. Wishing you health and prosperity, -Simon From carter.schonwald at gmail.com Fri Sep 24 17:04:09 2021 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Fri, 24 Sep 2021 13:04:09 -0400 Subject: [Haskell-cafe] Numerics (was: Re: Trouble with asinh) In-Reply-To: References: Message-ID: Hey David, Create a tracking ticket on the ghc for the set of changes / issues you wanna address and how, and @ me on it (I’ll then make sure to at other applicable Dolan )and I’ll try to help you get oriented and make sure it has the right visibility so we can help you out! On Sat, Sep 18, 2021 at 12:00 PM David James wrote: > Hi thanks for the comments. I actually have draft rewrites of the Haskell > complex functions with (I think) the correct behaviour, including branch > cuts. But I discovered the errors in the underlying real functions while > testing them. I’d like to try fixing all of these, but will probably need > some help. > > Are there instructions somewhere on the process to fix a bug (presumably > forking in GitHub, fixing code, adding test cases, running some CI, both > for Linux and Windows, etc)? (And is there something similar for fixing > mingle-w64 bugs?) > > I’ve been developing more test cases (esp for infinities +/-0, etc), but > if there are any ideas/references on how to thoroughly test real or complex > functions, that would also be useful. > > I’m currently away (and struggling to type on a phone) but will send more > details (and pictures based on those in Common Lisp The Language 2nd > edition) when I’m back. > > Thanks! David. > > > > > On 17 Sep 2021, at 22:06, Barak A. Pearlmutter > wrote: > > > > I suspect that most implementations of Common Lisp just call the C > > standard library catan(3) etc, which are well tuned. > > > > $ clisp > > Welcome to GNU CLISP 2.49.92 (2018-02-18) > > [1]> (atan #c(0 1d-40)) > > #C(0 1.0d-40) > > > > In this particular case, the problem is that the Haskell Data.Complex > > code has its own implementation of atan, which uses a log(1 + x) in > > calculating the imaginary part. A foreign function call to the > > appropriate libm routine would robustly address this, but that would > > be difficult because it's trying to be generic over RealFloat a => > > Complex a, instead of special casing Complex Float / Complex Double. > > Anyway, the Standard Prelude code for this is naïve: it should call > > log1p, at the very least—which it actually goes to the trouble of > > defining correctly, but not exporting. > > _______________________________________________ > > Haskell-Cafe mailing list > > To (un)subscribe, modify options or view archives go to: > > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > > Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From andreas.abel at ifi.lmu.de Fri Sep 24 17:09:49 2021 From: andreas.abel at ifi.lmu.de (Andreas Abel) Date: Fri, 24 Sep 2021 19:09:49 +0200 Subject: [Haskell-cafe] [ANN] cabal-clean (new tool) Message-ID: === Wondering where your disk space goes with too many Haskell projects compiled with too many GHC versions? === https://hackage.haskell.org/package/cabal-clean https://github.com/andreasabel/cabal-clean `cabal-clean` is a small executable that removes outdated cabal build artifacts from `dist-newstyle`. A build tree is considered outdated if there is one with either - a newer version of the package you are building, or - a newer minor version of the GHC compiler. In contrast to `cabal clean`, the tool `cabal-clean` retains the latest build trees for each GHC major version. Thus, it is geared towards multi-GHC development. Example: (self-applied to cabal-clean's build directory) --- 3.7M ghc-8.8.4 /cabal-clean-0.1.20210815 --- 3.5M ghc-8.10.6/cabal-clean-0.1.20210815 --- 3.7M ghc-9.0.1 /cabal-clean-0.1.20210815 --- 3.5M ghc-8.10.6/cabal-clean-0.1.20210924 +++ 3.6M ghc-8.10.7/cabal-clean-0.1.20210924 +++ 3.7M ghc-9.0.1 /cabal-clean-0.1.20210924 The directories prefixed with --- will be deleted, the ones with +++ retained. Disclaimers: 1. cabal-clean does not check whether deletion will cause dangling references like broken symlinks etc. (Could happen if you created a symlink to an executable that resides in one of the deleted build directories.) 2. cabal-clean does not read nor utilize information from the .cabal file. 3. Calls `du` ("disk usage"), so, might not work on Windows. Enjoy, Andreas From fa-ml at ariis.it Fri Sep 24 17:17:47 2021 From: fa-ml at ariis.it (Francesco Ariis) Date: Fri, 24 Sep 2021 19:17:47 +0200 Subject: [Haskell-cafe] [ANN] cabal-clean (new tool) In-Reply-To: References: Message-ID: Il 24 settembre 2021 alle 19:09 Andreas Abel ha scritto: > === Wondering where your disk space goes with too many Haskell projects > compiled with too many GHC versions? === > > https://hackage.haskell.org/package/cabal-clean > https://github.com/andreasabel/cabal-clean > > `cabal-clean` is a small executable that removes outdated cabal build > artifacts from `dist-newstyle`. Godsent tool, thanks for writing it! —F From amindfv at mailbox.org Fri Sep 24 17:53:31 2021 From: amindfv at mailbox.org (amindfv at mailbox.org) Date: Fri, 24 Sep 2021 10:53:31 -0700 Subject: [Haskell-cafe] [ANN] cabal-clean (new tool) In-Reply-To: References: Message-ID: This seems like a useful tool, but the naming might be confusing: "cabal-install" generally means "cabal install" but "cabal-clean" and "cabal clean" have similar goals but behave differently. Tom On Fri, Sep 24, 2021 at 07:09:49PM +0200, Andreas Abel wrote: > === Wondering where your disk space goes with too many Haskell projects > compiled with too many GHC versions? === > > https://hackage.haskell.org/package/cabal-clean > https://github.com/andreasabel/cabal-clean > > `cabal-clean` is a small executable that removes outdated cabal build > artifacts from `dist-newstyle`. > > A build tree is considered outdated if there is one with either > > - a newer version of the package you are building, or > - a newer minor version of the GHC compiler. > > In contrast to `cabal clean`, the tool `cabal-clean` retains the latest > build trees for each GHC major version. Thus, it is geared towards > multi-GHC development. > > Example: (self-applied to cabal-clean's build directory) > > --- 3.7M ghc-8.8.4 /cabal-clean-0.1.20210815 > --- 3.5M ghc-8.10.6/cabal-clean-0.1.20210815 > --- 3.7M ghc-9.0.1 /cabal-clean-0.1.20210815 > --- 3.5M ghc-8.10.6/cabal-clean-0.1.20210924 > +++ 3.6M ghc-8.10.7/cabal-clean-0.1.20210924 > +++ 3.7M ghc-9.0.1 /cabal-clean-0.1.20210924 > > The directories prefixed with --- will be deleted, the ones with +++ > retained. > > Disclaimers: > > 1. cabal-clean does not check whether deletion will cause dangling > references like broken symlinks etc. (Could happen if you created a symlink > to an executable that resides in one of the deleted build directories.) > > 2. cabal-clean does not read nor utilize information from the .cabal file. > > 3. Calls `du` ("disk usage"), so, might not work on Windows. > > Enjoy, > Andreas > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From emilypi at cohomolo.gy Fri Sep 24 18:24:53 2021 From: emilypi at cohomolo.gy (Emily Pillmore) Date: Fri, 24 Sep 2021 18:24:53 +0000 Subject: [Haskell-cafe] [ANN] cabal-clean (new tool) In-Reply-To: References: Message-ID: If this solves a particular use-case and doesn't involve a ton of code, I'd gladly accept a port and hide it behind a flag in cabal-install On Fri, Sep 24, 2021 at 11:53 AM, amindfv--- < haskell-cafe at haskell.org > wrote: > > > > This seems like a useful tool, but the naming might be confusing: > "cabal-install" generally means "cabal install" but "cabal-clean" and > "cabal clean" have similar goals but behave differently. > > > > Tom > > > > On Fri, Sep 24, 2021 at 07:09:49PM +0200, Andreas Abel wrote: > > >> >> >> === Wondering where your disk space goes with too many Haskell projects >> compiled with too many GHC versions? === >> >> >> >> https:/ / hackage. haskell. org/ package/ cabal-clean ( >> https://hackage.haskell.org/package/cabal-clean ) >> https:/ / github. com/ andreasabel/ cabal-clean ( >> https://github.com/andreasabel/cabal-clean ) >> >> >> >> `cabal-clean` is a small executable that removes outdated cabal build >> artifacts from `dist-newstyle`. >> >> >> >> A build tree is considered outdated if there is one with either >> >> >> >> - a newer version of the package you are building, or >> - a newer minor version of the GHC compiler. >> >> >> >> In contrast to `cabal clean`, the tool `cabal-clean` retains the latest >> build trees for each GHC major version. Thus, it is geared towards >> multi-GHC development. >> >> >> >> Example: (self-applied to cabal-clean's build directory) >> >> >> >> --- 3.7M ghc-8.8.4 /cabal-clean-0.1.20210815 >> --- 3.5M ghc-8.10.6/cabal-clean-0.1.20210815 >> --- 3.7M ghc-9.0.1 /cabal-clean-0.1.20210815 >> --- 3.5M ghc-8.10.6/cabal-clean-0.1.20210924 >> +++ 3.6M ghc-8.10.7/cabal-clean-0.1.20210924 >> +++ 3.7M ghc-9.0.1 /cabal-clean-0.1.20210924 >> >> >> >> The directories prefixed with --- will be deleted, the ones with +++ >> retained. >> >> >> >> Disclaimers: >> >> >> >> 1. cabal-clean does not check whether deletion will cause dangling >> references like broken symlinks etc. (Could happen if you created a >> symlink to an executable that resides in one of the deleted build >> directories.) >> >> >> >> 2. cabal-clean does not read nor utilize information from the .cabal file. >> >> >> >> >> 3. Calls `du` ("disk usage"), so, might not work on Windows. >> >> >> >> Enjoy, >> Andreas >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: http:/ / mail. haskell. >> org/ cgi-bin/ mailman/ listinfo/ haskell-cafe ( >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe ) Only >> members subscribed via the mailman list are allowed to post. >> >> > > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: http:/ / mail. haskell. > org/ cgi-bin/ mailman/ listinfo/ haskell-cafe ( > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe ) Only > members subscribed via the mailman list are allowed to post. > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From frase at frase.id.au Fri Sep 24 23:55:16 2021 From: frase at frase.id.au (Fraser Tweedale) Date: Sat, 25 Sep 2021 09:55:16 +1000 Subject: [Haskell-cafe] [ANN] cabal-clean (new tool) In-Reply-To: References: Message-ID: On Fri, Sep 24, 2021 at 07:17:47PM +0200, Francesco Ariis wrote: > Il 24 settembre 2021 alle 19:09 Andreas Abel ha scritto: > > === Wondering where your disk space goes with too many Haskell projects > > compiled with too many GHC versions? === > > > > https://hackage.haskell.org/package/cabal-clean > > https://github.com/andreasabel/cabal-clean > > > > `cabal-clean` is a small executable that removes outdated cabal build > > artifacts from `dist-newstyle`. > > Godsent tool, thanks for writing it! > —F > +1. Please consider a mode that traverses the entire filesystem :) Cheers, Fraser > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From branimir.maksimovic at gmail.com Sat Sep 25 01:37:10 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sat, 25 Sep 2021 03:37:10 +0200 Subject: [Haskell-cafe] [ANN] cabal-clean (new tool) In-Reply-To: References: Message-ID: <05160756-1820-4FEE-8F46-FBE1910316E5@gmail.com> God send, thanks. Greetings, Branimir. > On 25.09.2021., at 01:55, Fraser Tweedale wrote: > > On Fri, Sep 24, 2021 at 07:17:47PM +0200, Francesco Ariis wrote: >> Il 24 settembre 2021 alle 19:09 Andreas Abel ha scritto: >>> === Wondering where your disk space goes with too many Haskell projects >>> compiled with too many GHC versions? === >>> >>> https://hackage.haskell.org/package/cabal-clean >>> https://github.com/andreasabel/cabal-clean >>> >>> `cabal-clean` is a small executable that removes outdated cabal build >>> artifacts from `dist-newstyle`. >> >> Godsent tool, thanks for writing it! >> —F >> > +1. > > Please consider a mode that traverses the entire filesystem :) > > Cheers, > Fraser > >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From branimir.maksimovic at gmail.com Sat Sep 25 01:58:50 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sat, 25 Sep 2021 03:58:50 +0200 Subject: [Haskell-cafe] [BUG] Criterion is tied to x86 architecture In-Reply-To: <990cf778-738b-3e60-791c-9fb86bb09d4f@gmail.com> References: <990cf778-738b-3e60-791c-9fb86bb09d4f@gmail.com> Message-ID: Thanks, it works now: bmaxa at Branimirs-Air sort % ghc -O2 ms.hs Loaded package environment from /Users/bmaxa/.ghc/aarch64-darwin-8.10.7/environments/default [1 of 1] Compiling Main ( ms.hs, ms.o ) ms.hs:23:44: warning: [-Wdeprecations] In the use of ‘bitSize’ (imported from Data.Bits): Deprecated: "Use 'bitSizeMaybe' or 'finiteBitSize' instead" | 23 | positiveLsdSort list = foldl step list [0..bitSize (head list)] where | ^^^^^^^ ms.hs:27:29: warning: [-Wdeprecations] In the use of ‘bitSize’ (imported from Data.Bits): Deprecated: "Use 'bitSizeMaybe' or 'finiteBitSize' instead" | 27 | positiveMsdSort list = aux (bitSize (head list) - 1) list where | ^^^^^^^ Linking ms ... bmaxa at Branimirs-Air sort % ./ms list size 65536 +++ OK, passed 100 tests. benchmarking msdSort/random time 109.4 ms (108.4 ms .. 110.6 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 107.2 ms (106.2 ms .. 108.0 ms) std dev 1.456 ms (966.8 μs .. 2.248 ms) benchmarking msdSort/sorted time 101.1 ms (100.4 ms .. 102.3 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 100.9 ms (100.5 ms .. 101.2 ms) std dev 550.8 μs (418.0 μs .. 801.1 μs) benchmarking msdSort/reverse sorted time 104.6 ms (103.8 ms .. 106.2 ms) 1.000 R² (0.999 R² .. 1.000 R²) mean 103.6 ms (102.8 ms .. 104.2 ms) std dev 1.134 ms (861.7 μs .. 1.447 ms) benchmarking lsdSort/random time 107.9 ms (106.9 ms .. 109.0 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 107.6 ms (107.1 ms .. 108.1 ms) std dev 765.3 μs (406.2 μs .. 983.7 μs) benchmarking lsdSort/sorted time 89.28 ms (88.80 ms .. 89.99 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 88.48 ms (88.19 ms .. 88.79 ms) std dev 513.3 μs (427.9 μs .. 624.1 μs) benchmarking lsdSort/reverse sorted time 89.04 ms (88.02 ms .. 89.83 ms) 1.000 R² (0.999 R² .. 1.000 R²) mean 89.26 ms (88.85 ms .. 89.68 ms) std dev 684.2 μs (536.5 μs .. 851.6 μs) benchmarking qsort/random time 18.90 ms (18.76 ms .. 19.02 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 18.91 ms (18.83 ms .. 19.02 ms) std dev 221.3 μs (168.4 μs .. 321.8 μs) benchmarking qsort/sorted time 13.27 ms (13.15 ms .. 13.41 ms) 0.999 R² (0.998 R² .. 1.000 R²) mean 13.33 ms (13.23 ms .. 13.45 ms) std dev 274.2 μs (218.5 μs .. 358.7 μs) benchmarking qsort/reverse sorted time 13.04 ms (12.95 ms .. 13.13 ms) 1.000 R² (0.999 R² .. 1.000 R²) mean 13.00 ms (12.88 ms .. 13.08 ms) std dev 274.5 μs (188.5 μs .. 439.5 μs) benchmarking sort/random time 46.24 ms (45.99 ms .. 46.49 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 46.08 ms (45.76 ms .. 46.27 ms) std dev 496.2 μs (263.1 μs .. 851.3 μs) benchmarking sort/sorted time 1.886 ms (1.862 ms .. 1.907 ms) 0.998 R² (0.997 R² .. 0.999 R²) mean 2.073 ms (2.035 ms .. 2.115 ms) std dev 139.7 μs (122.6 μs .. 167.1 μs) variance introduced by outliers: 49% (moderately inflated) benchmarking sort/reverse sorted time 776.4 μs (771.2 μs .. 781.4 μs) 0.999 R² (0.999 R² .. 1.000 R²) mean 805.7 μs (797.3 μs .. 817.1 μs) std dev 33.20 μs (26.90 μs .. 40.92 μs) variance introduced by outliers: 32% (moderately inflated) benchmarking msort/random time 59.61 ms (58.73 ms .. 60.14 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 58.98 ms (58.16 ms .. 59.34 ms) std dev 917.6 μs (386.7 μs .. 1.670 ms) benchmarking msort/sorted time 27.21 ms (27.01 ms .. 27.45 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 27.11 ms (26.92 ms .. 27.24 ms) std dev 325.1 μs (225.9 μs .. 491.0 μs) benchmarking msort/reverse sorted time 27.44 ms (27.35 ms .. 27.60 ms) 1.000 R² (1.000 R² .. 1.000 R²) mean 27.36 ms (27.21 ms .. 27.42 ms) std dev 200.6 μs (72.91 μs .. 378.0 μs) benchmarking rsort/random time 24.63 ms (24.36 ms .. 24.95 ms) 1.000 R² (0.999 R² .. 1.000 R²) mean 24.90 ms (24.72 ms .. 25.33 ms) std dev 542.9 μs (274.7 μs .. 912.1 μs) benchmarking rsort/sorted time 24.55 ms (24.32 ms .. 24.80 ms) 1.000 R² (0.999 R² .. 1.000 R²) mean 24.54 ms (24.41 ms .. 24.82 ms) std dev 408.0 μs (206.4 μs .. 727.4 μs) benchmarking rsort/reverse sorted time 24.67 ms (24.44 ms .. 24.97 ms) 1.000 R² (0.999 R² .. 1.000 R²) mean 24.38 ms (24.27 ms .. 24.52 ms) std dev 278.1 μs (197.5 μs .. 388.4 μs) [2,3,5,6,6,8,8,9,10,11] bmaxa at Branimirs-Air sort % cat ms.hs import Data.List import qualified Test.QuickCheck as QC import System.Random import Criterion.Main import Data.Bits import qualified Data.Vector.Mutable as VM import qualified Data.Vector as V import Data.Word import System.IO.Unsafe import Data.Bits lsdSort :: (Ord a, Bits a, Num a) => [a] -> [a] lsdSort = fixSort positiveLsdSort msdSort :: (Ord a, Bits a, Num a) => [a] -> [a] msdSort = fixSort positiveMsdSort -- Fix a sort that puts negative numbers at the end, like positiveLsdSort and positiveMsdSort fixSort :: (Bits a, Ord a, Num a)=>([a]->[a]) -> [a] -> [a] fixSort sorter list = uncurry (flip (++)) (break (< 0) (sorter list)) positiveLsdSort :: (Bits a) => [a] -> [a] positiveLsdSort list = foldl step list [0..bitSize (head list)] where step list bit = uncurry (++) (partition (not . flip testBit bit) list) positiveMsdSort :: (Bits a) => [a] -> [a] positiveMsdSort list = aux (bitSize (head list) - 1) list where aux _ [] = [] aux (-1) list = list aux bit list = aux (bit - 1) lower ++ aux (bit - 1) upper where (lower, upper) = partition (not . flip testBit bit) list msort :: Ord a =>[a] -> [a] msort xs | n < 2 = xs | otherwise = merge (msort x1s) (msort x2s) where n = length xs (x1s,x2s) = splitAt (n`quot`2) xs merge xs ys = case (xs,ys) of ([], ys') -> ys' (xs', []) -> xs' (x:xs',y:ys') | x < y -> x : merge xs' ys | otherwise -> y : merge xs ys' isort :: Ord a => [a] -> [a] isort xs = foldr insert [] xs where insert x [] = [x] insert x (y:ys) = if x [a] -> [a] qsort [] = [] qsort [x] = [x] qsort xs = let pivot = mot (x1s,x2s,pivots) = foldl (\(ys,zs,pivots) x-> if xpivot then (ys,x:zs,pivots) else (ys,zs,x:pivots)) ([],[],[]) xs in qsort x1s ++ pivots ++ qsort x2s where mot = let n = length xs (a,b,c) = (xs !! 0, (xs !! (n`quot`2)), xs !! (n-1)) in if a>b then if ab then c else b else if ba then c else a rsort :: [Word32] -> [Word32] rsort xs = unsafePerformIO $ do let base = 16 add_bucket :: Int -> Word32 -> VM.IOVector [Word32] -> VM.IOVector [Word32] add_bucket i n b = unsafePerformIO $ do lst <- VM.read b i VM.write b i (n:lst) return b clear b = mapM_ (\i-> VM.write b i []) [0..base-1] bucket <- VM.replicate base [] :: IO (VM.IOVector [Word32]) let loop = return $ foldl body xs [0..7] where body :: [Word32] -> Word32 -> [Word32] body nums n = unsafePerformIO $ do v <- V.freeze (foldl disp bucket nums) clear bucket return $ V.foldr gather [] v where disp :: VM.IOVector [Word32]->Word32->VM.IOVector [Word32] disp b val = add_bucket (fromIntegral ((val`shiftR`fromIntegral (n`shiftL`fromIntegral 2)).&.0xf)) val b gather :: [Word32]->[Word32] -> [Word32] gather b nums = foldl (\xs x->x:xs) nums b loop prop_msort :: [Word32]->Bool prop_msort xs = msort xs == sort xs && sort xs == isort xs && sort xs == qsort xs && sort xs == rsort xs && lsdSort xs == sort xs && msdSort xs == sort xs deepCheck p = QC.quickCheckWith (QC.stdArgs { QC.maxSize = 1000}) p n :: Word32 n = 4096 * 16 tl :: [Word32]->[Word32] tl = take (fromIntegral n) main = do putStrLn $ "list size " ++ show n deepCheck prop_msort g <- getStdGen let rl = randomRs (0,n) g let (s,rs) = ([(0::Word32)..],[(n-1::Word32),n-2..]) let rnd = tl rl srt = tl s rsrt = tl rs defaultMain [ bgroup "msdSort" [ bench "random" $ nf msdSort rnd, bench "sorted" $ nf msdSort srt, bench "reverse sorted" $ nf msdSort rsrt ], bgroup "lsdSort" [ bench "random" $ nf lsdSort rnd, bench "sorted" $ nf lsdSort srt, bench "reverse sorted" $ nf lsdSort rsrt ], bgroup "qsort" [ bench "random" $ nf qsort rnd, bench "sorted" $ nf qsort srt, bench "reverse sorted" $ nf qsort rsrt ], bgroup "sort" [ bench "random" $ nf sort rnd, bench "sorted" $ nf sort srt, bench "reverse sorted" $ nf sort rsrt ], bgroup "msort" [ bench "random" $ nf msort rnd, bench "sorted" $ nf msort srt, bench "reverse sorted" $ nf msort rsrt ],{- bgroup "isort" [ bench "random" $ nf isort rnd, bench "sorted" $ nf isort srt, bench "reverse sorted" $ nf isort rsrt ],-} bgroup "rsort" [ bench "random" $ nf rsort rnd, bench "sorted" $ nf rsort srt, bench "reverse sorted" $ nf rsort rsrt ] ] print $ take 10 $ rsort rnd Greetings, Branimir. > On 18.09.2021., at 11:55, Jaro Reinders wrote: > > This issue: https://github.com/haskell/criterion/issues/238, makes it seem like this should be fixed with criterion-measurement-0.1.3.0. If that doesn't work then I suggest placing a comment or opening a new issue there. > > Cheers, > > Jaro > > On 18-09-2021 11:24, Branimir Maksimovic wrote: >> Problem as I work on Apple M1 processor, can’t compile >> Criterion as it use x86 specific features. >> Greetings, Branimir. >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. From branimir.maksimovic at gmail.com Sat Sep 25 07:22:06 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sat, 25 Sep 2021 09:22:06 +0200 Subject: [Haskell-cafe] mine sockets lib vs yesod Message-ID: Let’s compare: 1000 parallel connections 100k requests yesod : 7658 recs/sec Errors 85808 Timeouted 0 Mine:: 12699 recs/sec Errors 0 Timeouted 0 10k connections, 100k requests: yesod: 5205 recs/sec Errors 81152 Timeouted 3842 Mine: 8160 recs/sec Errors 0 Timeouted 46 Sources: Yesod: / HomeR GET |] instance Yesod HelloWorld getHomeR :: Handler () getHomeR = do number <- liftIO (randomIO :: IO Float) let txt = pack $ "hello world " ++ show number sendResponse (txt:: Text) main :: IO () main = warp 3838 HelloWorld Mine: import Sockets import Foreign.C.String import Data.IORef import Control.Concurrent main = do ref <- newIORef 1 s <- socket defaultCallbacks { constructor = \ci -> set_cb ci defaultCallbacks { done_connected = binded ref, done_reading = process } } pl <- epoll 1000 pl1 <- epoll 1000 pl2 <- epoll 1000 pl3 <- epoll 1000 listen s "8080" pl_accept pl s pl_accept pl1 s pl_accept pl2 s pl_accept pl3 s let run pl = do forkIO $ run_loop pl (-1) run pl run pl1 run pl2 run_loop pl3 (-1) binded ref pl s = do i <- readIORef ref putStrLn $ "connection nr:"++show i writeIORef ref (i+1) pl_read pl s return 0 process pl s buf len = do str <- peekCStringLen (buf,fromIntegral len) ip <- client s str1 <- peekCString ip putStrLn $ "from "++str1++" \ngot "++str write pl s "Hello World!!!\r\n" return 0 if using -threaded performance is *worse*. Greetings, Branimir. From branimir.maksimovic at gmail.com Sat Sep 25 07:49:37 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sat, 25 Sep 2021 09:49:37 +0200 Subject: [Haskell-cafe] mine sockets lib vs yesod In-Reply-To: References: Message-ID: <92299499-8D63-4176-9975-62CC87C62FE3@gmail.com> It is mine lib for https://www.volomp.com I work now here https://www.rt-rk.com on this http://www.vti.mod.gov.rs/index.php?view=actuality&type=projects&category=1&id=72 I guess that if I port it to Haskell purely from CPP, I won’t have problems with copyright? Greetings, Branimir > On 25.09.2021., at 09:22, Branimir Maksimovic wrote: > > Let’s compare: > 1000 parallel connections 100k requests > > yesod : > 7658 recs/sec > Errors 85808 > Timeouted 0 > > Mine:: > 12699 recs/sec > Errors 0 > Timeouted 0 > > 10k connections, 100k requests: > yesod: > 5205 recs/sec > Errors 81152 > Timeouted 3842 > > Mine: > 8160 recs/sec > Errors 0 > Timeouted 46 > > Sources: > Yesod: > / HomeR GET > |] > > instance Yesod HelloWorld > > getHomeR :: Handler () > getHomeR = do > number <- liftIO (randomIO :: IO Float) > let txt = pack $ "hello world " ++ show number > sendResponse (txt:: Text) > > main :: IO () > main = warp 3838 HelloWorld > > Mine: > import Sockets > import Foreign.C.String > import Data.IORef > import Control.Concurrent > > main = do > ref <- newIORef 1 > s <- socket defaultCallbacks { > constructor = \ci -> set_cb ci defaultCallbacks { > done_connected = binded ref, > done_reading = process > } > } > pl <- epoll 1000 > pl1 <- epoll 1000 > pl2 <- epoll 1000 > pl3 <- epoll 1000 > listen s "8080" > pl_accept pl s > pl_accept pl1 s > pl_accept pl2 s > pl_accept pl3 s > let run pl = do forkIO $ > run_loop pl (-1) > run pl > run pl1 > run pl2 > run_loop pl3 (-1) > > binded ref pl s = do > i <- readIORef ref > putStrLn $ "connection nr:"++show i > writeIORef ref (i+1) > pl_read pl s > return 0 > > process pl s buf len = do > str <- peekCStringLen (buf,fromIntegral len) > ip <- client s > str1 <- peekCString ip > putStrLn $ "from "++str1++" \ngot "++str > write pl s "Hello World!!!\r\n" > return 0 > > if using -threaded performance is *worse*. > > Greetings, Branimir. -------------- next part -------------- An HTML attachment was scrubbed... URL: From leah at vuxu.org Sat Sep 25 15:39:17 2021 From: leah at vuxu.org (Leah Neukirchen) Date: Sat, 25 Sep 2021 17:39:17 +0200 Subject: [Haskell-cafe] Munich Haskell Meeting, 2021-09-27 @ 19:30 Message-ID: <871r5cacm2.fsf@vuxu.org> Dear all, next week, our monthly Munich Haskell Meeting will take place again on Monday, September 27 at Augustiner-Gaststätte Rumpler(!!) at 19h30. For details see here: http://muenchen.haskell.bayern/dates.html If you plan to join, please add yourself to this dudle until Monday 12:00 so we can reserve enough seats! It is OK to add yourself to the dudle anonymously or pseudonymously. Please note that not more than 10 people can attend---first come, first serve. https://dudle.inf.tu-dresden.de/haskell-munich-sep-2021/ Everybody is welcome! cu, -- Leah Neukirchen https://leahneukirchen.org/ From carter.schonwald at gmail.com Sun Sep 26 15:27:39 2021 From: carter.schonwald at gmail.com (Carter Schonwald) Date: Sun, 26 Sep 2021 11:27:39 -0400 Subject: [Haskell-cafe] mine sockets lib vs yesod In-Reply-To: <92299499-8D63-4176-9975-62CC87C62FE3@gmail.com> References: <92299499-8D63-4176-9975-62CC87C62FE3@gmail.com> Message-ID: That would be fun to share ! Look forward to learning what’s different On Sat, Sep 25, 2021 at 3:51 AM Branimir Maksimovic < branimir.maksimovic at gmail.com> wrote: > It is mine lib for https://www.volomp.com > I work now here https://www.rt-rk.com > on this > http://www.vti.mod.gov.rs/index.php?view=actuality&type=projects&category=1&id=72 > > I guess that if I port it to Haskell purely from CPP, I won’t have > problems with copyright? > > Greetings, Branimir > > > On 25.09.2021., at 09:22, Branimir Maksimovic < > branimir.maksimovic at gmail.com> wrote: > > Let’s compare: > 1000 parallel connections 100k requests > > yesod : > 7658 recs/sec > Errors 85808 > Timeouted 0 > > Mine:: > 12699 recs/sec > Errors 0 > Timeouted 0 > > 10k connections, 100k requests: > yesod: > 5205 recs/sec > Errors 81152 > Timeouted 3842 > > Mine: > 8160 recs/sec > Errors 0 > Timeouted 46 > > Sources: > Yesod: > / HomeR GET > |] > > instance Yesod HelloWorld > > getHomeR :: Handler () > getHomeR = do > number <- liftIO (randomIO :: IO Float) > let txt = pack $ "hello world " ++ show number > sendResponse (txt:: Text) > > main :: IO () > main = warp 3838 HelloWorld > > Mine: > import Sockets > import Foreign.C.String > import Data.IORef > import Control.Concurrent > > main = do > ref <- newIORef 1 > s <- socket defaultCallbacks { > constructor = \ci -> set_cb ci > defaultCallbacks { > done_connected = binded ref, > done_reading = process > } > } > pl <- epoll 1000 > pl1 <- epoll 1000 > pl2 <- epoll 1000 > pl3 <- epoll 1000 > listen s "8080" > pl_accept pl s > pl_accept pl1 s > pl_accept pl2 s > pl_accept pl3 s > let run pl = do forkIO $ > run_loop pl (-1) > run pl > run pl1 > run pl2 > run_loop pl3 (-1) > > binded ref pl s = do > i <- readIORef ref > putStrLn $ "connection nr:"++show i > writeIORef ref (i+1) > pl_read pl s > return 0 > > process pl s buf len = do > str <- peekCStringLen (buf,fromIntegral len) > ip <- client s > str1 <- peekCString ip > putStrLn $ "from "++str1++" \ngot "++str > write pl s "Hello World!!!\r\n" > return 0 > > if using -threaded performance is *worse*. > > Greetings, Branimir. > > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Sun Sep 26 15:29:43 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Sun, 26 Sep 2021 17:29:43 +0200 Subject: [Haskell-cafe] mine sockets lib vs yesod In-Reply-To: References: <92299499-8D63-4176-9975-62CC87C62FE3@gmail.com> Message-ID: just to translate all thing into Haskell, I have it whole in Rust currently: https://github.com/bmaxa/web_server_rust Greets, Branimir. > On 26.09.2021., at 17:27, Carter Schonwald wrote: > > That would be fun to share ! Look forward to learning what’s different > > On Sat, Sep 25, 2021 at 3:51 AM Branimir Maksimovic > wrote: > It is mine lib for https://www.volomp.com > I work now here https://www.rt-rk.com > on this http://www.vti.mod.gov.rs/index.php?view=actuality&type=projects&category=1&id=72 > > I guess that if I port it to Haskell purely from CPP, I won’t have problems with copyright? > > Greetings, Branimir > > >> On 25.09.2021., at 09:22, Branimir Maksimovic > wrote: >> >> Let’s compare: >> 1000 parallel connections 100k requests >> >> yesod : >> 7658 recs/sec >> Errors 85808 >> Timeouted 0 >> >> Mine:: >> 12699 recs/sec >> Errors 0 >> Timeouted 0 >> >> 10k connections, 100k requests: >> yesod: >> 5205 recs/sec >> Errors 81152 >> Timeouted 3842 >> >> Mine: >> 8160 recs/sec >> Errors 0 >> Timeouted 46 >> >> Sources: >> Yesod: >> / HomeR GET >> |] >> >> instance Yesod HelloWorld >> >> getHomeR :: Handler () >> getHomeR = do >> number <- liftIO (randomIO :: IO Float) >> let txt = pack $ "hello world " ++ show number >> sendResponse (txt:: Text) >> >> main :: IO () >> main = warp 3838 HelloWorld >> >> Mine: >> import Sockets >> import Foreign.C.String >> import Data.IORef >> import Control.Concurrent >> >> main = do >> ref <- newIORef 1 >> s <- socket defaultCallbacks { >> constructor = \ci -> set_cb ci defaultCallbacks { >> done_connected = binded ref, >> done_reading = process >> } >> } >> pl <- epoll 1000 >> pl1 <- epoll 1000 >> pl2 <- epoll 1000 >> pl3 <- epoll 1000 >> listen s "8080" >> pl_accept pl s >> pl_accept pl1 s >> pl_accept pl2 s >> pl_accept pl3 s >> let run pl = do forkIO $ >> run_loop pl (-1) >> run pl >> run pl1 >> run pl2 >> run_loop pl3 (-1) >> >> binded ref pl s = do >> i <- readIORef ref >> putStrLn $ "connection nr:"++show i >> writeIORef ref (i+1) >> pl_read pl s >> return 0 >> >> process pl s buf len = do >> str <- peekCStringLen (buf,fromIntegral len) >> ip <- client s >> str1 <- peekCString ip >> putStrLn $ "from "++str1++" \ngot "++str >> write pl s "Hello World!!!\r\n" >> return 0 >> >> if using -threaded performance is *worse*. >> >> Greetings, Branimir. > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Mon Sep 27 10:16:53 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Mon, 27 Sep 2021 12:16:53 +0200 Subject: [Haskell-cafe] mine sockets lib vs yesod In-Reply-To: References: <92299499-8D63-4176-9975-62CC87C62FE3@gmail.com> Message-ID: > On 27.09.2021., at 12:13, Mikolaj Konarski wrote: > > Hi Branimir, > >> I guess that if I port it to Haskell purely from CPP, I won’t have problems with copyright? > > I will retain exactly the same copyright it had. To get rid of the old > copyright, you'd need to clean-room re-implement it (you yell ideas > from another room and somebody implements them in Haskell not having > seen the CPP code beforehand). OK. > >> if using -threaded performance is *worse*. > > This is normal. You trade performance for the ability to pre-empt > (e.g., not get stuck on blocking FFI). > > Kind regards, > Mikolaj I will implement it whole in Haskell, in async fashion as it seems with current hardware bandwith is saturated with just single CPU/Core. Greettings, Branimir. From mikolaj at well-typed.com Mon Sep 27 10:17:10 2021 From: mikolaj at well-typed.com (Mikolaj Konarski) Date: Mon, 27 Sep 2021 12:17:10 +0200 Subject: [Haskell-cafe] mine sockets lib vs yesod In-Reply-To: References: <92299499-8D63-4176-9975-62CC87C62FE3@gmail.com> Message-ID: Hi Branimir, > I guess that if I port it to Haskell purely from CPP, I won’t have problems with copyright? I will retain exactly the same copyright it had. To get rid of the old copyright, you'd need to clean-room re-implement it (you yell ideas from another room and somebody implements them in Haskell not having seen the CPP code beforehand). > if using -threaded performance is *worse*. This is normal. You trade performance for the ability to pre-empt (e.g., not get stuck on blocking FFI). Kind regards, Mikolaj From P.Achten at cs.ru.nl Mon Sep 27 11:58:52 2021 From: P.Achten at cs.ru.nl (Peter Achten) Date: Mon, 27 Sep 2021 13:58:52 +0200 Subject: [Haskell-cafe] [TFP'22] first call for papers: Trends in Functional Programming 2022, 10-11 February (with Lambda Days 2022 & TFPIE 2022) Message-ID: <90b0e3a3-64c3-fabc-699e-c49532b55725@cs.ru.nl> ====== TFP 2022 ====== 23rd Symposium on Trends in Functional Programming 10-11 February, 2022 Krakow, Poland https://trendsfp.github.io/index.html == Important Dates == Submission deadline for pre-symposium review            Wednesday 1st December, 2021 Submission deadline for draft papers                    Wednesday 12th January, 2022 Notification for pre-symposium submissions              Friday 21st January, 2022 Notification for draft submissions                      Friday 21st January, 2022 Symposium dates                                         Thursday 10th - Friday 11th February, 2022 Submission deadline for post-symposium reviewing        Wednesday 16th March, 2022 Notification for post-symposium submissions             Friday 13rd May, 2022 The Symposium on Trends in Functional Programming (TFP) is an international forum for researchers with interests in all aspects of functional programming, taking a broad view of current and future trends in the area. It aspires to be a lively environment for presenting the latest research results, and other contributions. Please be aware that TFP uses two distinct rounds of submissions. TFP 2022 will be co-located with two other functional programming events. TFP 2022 will be accompanied by the International Workshop on Trends in Functional Programming in Education (TFPIE), which will take place on February 11. Simultaneously with TFP, Lambda Days '22 is a two day conference where academia meets industry, where research and practical application collide. == Scope == The symposium recognizes that new trends may arise through various routes. As part of the Symposium's focus on trends we therefore identify the following five article categories. High-quality articles are solicited in any of these categories: * Research Articles:   Leading-edge, previously unpublished research work * Position Articles:  On what new trends should or should not be * Project Articles:   Descriptions of recently started new projects * Evaluation Articles:   What lessons can be drawn from a finished project * Overview Articles:   Summarizing work with respect to a trendy subject Articles must be original and not simultaneously submitted for publication to any other forum. They may consider any aspect of functional programming: theoretical, implementation-oriented, or experience-oriented. Applications of functional programming techniques to other languages are also within the scope of the symposium. Topics suitable for the symposium include, but are not limited to: * Functional programming and multicore/manycore computing * Functional programming in the cloud * High performance functional computing * Extra-functional (behavioural) properties of functional programs * Dependently typed functional programming * Validation and verification of functional programs * Debugging and profiling for functional languages * Functional programming in different application areas:   security, mobility, telecommunications applications, embedded   systems, global computing, grids, etc. * Interoperability with imperative programming languages * Novel memory management techniques * Program analysis and transformation techniques * Empirical performance studies * Abstract/virtual machines and compilers for functional languages * (Embedded) domain specific languages * New implementation strategies * Any new emerging trend in the functional programming area If you are in doubt on whether your article is within the scope of TFP, please contact the TFP 2022 program chairs, Wouter Swierstra and Nicolas Wu. == Best Paper Awards == To reward excellent contributions, TFP awards a prize for the best paper accepted for the formal proceedings. TFP traditionally pays special attention to research students, acknowledging that students are almost by definition part of new subject trends. A student paper is one for which the authors state that the paper is mainly the work of students, the students are listed as first authors, and a student would present the paper. A prize for the best student paper is awarded each year. In both cases, it is the PC of TFP that awards the prize. In case the best paper happens to be a student paper, that paper will then receive both prizes. == Instructions to Author == Papers must be submitted at:   https://easychair.org/conferences/?conf=tfp22 Authors of papers have the choice of having their contributions formally reviewed either before or after the Symposium. == Pre-symposium formal review == Papers to be formally reviewed before the symposium should be submitted before an early deadline and receive their reviews and notification of acceptance for both presentation and publication before the symposium. A paper that has been rejected in this process may still be accepted for presentation at the symposium, but will not be considered for the post-symposium formal review. == Post-symposium formal review == Draft papers will receive minimal reviews and notification of acceptance for presentation at the symposium. Authors of draft papers will be invited to submit revised papers based on the feedback received at the symposium. A post-symposium refereeing process will then select a subset of these articles for formal publication. == Paper categories == Draft papers and papers submitted for formal review are submitted as extended abstracts (4 to 10 pages in length) or full papers (20 pages). The submission must clearly indicate which category it belongs to: research, position, project, evaluation, or overview paper. It should also indicate which authors are research students, and whether the main author(s) are students. A draft paper for which all authors are students will receive additional feedback by one of the PC members shortly after the symposium has taken place. == Format == Papers must be written in English, and written using the LNCS style. For more information about formatting please consult the Springer LNCS web site. == Program Committee == Program Co-chairs Nicolas Wu - Imperial College London Wouter Swierstra - Utrecht University The remainder of the PC will be announced on the conference website. From alexis.praga at gmail.com Tue Sep 28 08:00:40 2021 From: alexis.praga at gmail.com (Alexis Praga) Date: Tue, 28 Sep 2021 10:00:40 +0200 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: References: Message-ID: Hi, Small feedback in case it’s useful: Switching from stack to cabal was painless with ghcup. I could not make it work without it (some dependencies failed to compile on Archlinux). Alexis Praga > Le 18 sept. 2021 à 21:07, coot at coot.me a écrit : > >  > Hi Alexis, > > There are several reasons: > > * reproducible nix style local builds. By specifying hackage index one can build against the same set of packages locally and on CI. > * has access to whole hackage, though at times requires a bit of thought, most of the time it works just fine. > * `cabal.project` and `cabal.project.local`: the first corresponds to `stack.yaml`, the other does not have a counter part in stack. For example, this is very useful, when one wants to modify ghc options per package, e.g. adding or removing `-Werror` ghc option, or configuring a ghc plugin > * some options work better than in stack. One example is `--allow-newer`. > * one can experiment with backpack, > > Cheers > Marcin > > Sent with ProtonMail Secure Email. > > ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ >> On Saturday, September 18th, 2021 at 20:52, Alexis Praga wrote: >> Hi, >> >> As an intermediate beginner, I've been back into Haskell for the last >> months for a small project, using stack as the building tool. >> >> Why stack ? A few years back, I learned that it was the "best" way to build >> projects to avoid "cabal hell", which I understood at the time as >> "managing dependencies with cabal is hard". >> >> As such, I've use stack since and have been quite happy with it. The >> only drawback is that building a project can be quite long. >> >> This is usually not a problem, except for writing Haskell scripts using >> shelly (for example), where the stack layout is a bit impractical for >> fast-paced development. A solution is to use `runghc` or a script >> interpreter [1]. >> >> However, I've seen some projects where cabal is used to build directly >> instead of cabal, so it looks like the situation improved. >> >> My question is this: in 2021, is there a reason to switch back to cabal ? >> >> Thanks, >> >> [1] https://www.fpcomplete.com/haskell/tutorial/stack-script/ >> >> >> -- >> >> Alexis Praga > -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Tue Sep 28 08:12:00 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Tue, 28 Sep 2021 10:12:00 +0200 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: References: Message-ID: Arch Linux has broken ghc installation as package maintener has some weird ideas… You have to install it via soirces and avoid Arch packagases like plague. Greetings, Branimir. > On 28.09.2021., at 10:00, Alexis Praga wrote: > > Hi, > > > Small feedback in case it’s useful: > > Switching from stack to cabal was painless with ghcup. I could not make it work without it (some dependencies failed to compile on Archlinux). > > Alexis Praga > >> Le 18 sept. 2021 à 21:07, coot at coot.me a écrit : >> >>  >> Hi Alexis, >> >> There are several reasons: >> >> * reproducible nix style local builds. By specifying hackage index one can build against the same set of packages locally and on CI. >> * has access to whole hackage, though at times requires a bit of thought, most of the time it works just fine. >> * `cabal.project` and `cabal.project.local`: the first corresponds to `stack.yaml`, the other does not have a counter part in stack. For example, this is very useful, when one wants to modify ghc options per package, e.g. adding or removing `-Werror` ghc option, or configuring a ghc plugin >> * some options work better than in stack. One example is `--allow-newer`. >> * one can experiment with backpack, >> >> Cheers >> Marcin >> >> Sent with ProtonMail Secure Email. >> >> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ >> On Saturday, September 18th, 2021 at 20:52, Alexis Praga wrote: >>> Hi, >>> >>> As an intermediate beginner, I've been back into Haskell for the last >>> months for a small project, using stack as the building tool. >>> >>> Why stack ? A few years back, I learned that it was the "best" way to build >>> projects to avoid "cabal hell", which I understood at the time as >>> "managing dependencies with cabal is hard". >>> >>> As such, I've use stack since and have been quite happy with it. The >>> only drawback is that building a project can be quite long. >>> >>> This is usually not a problem, except for writing Haskell scripts using >>> shelly (for example), where the stack layout is a bit impractical for >>> fast-paced development. A solution is to use `runghc` or a script >>> interpreter [1]. >>> >>> However, I've seen some projects where cabal is used to build directly >>> instead of cabal, so it looks like the situation improved. >>> >>> My question is this: in 2021, is there a reason to switch back to cabal ? >>> >>> Thanks, >>> >>> [1] https://www.fpcomplete.com/haskell/tutorial/stack-script/ >>> >>> >>> -- >>> >>> Alexis Praga >> > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From alexis.praga at gmail.com Tue Sep 28 09:34:42 2021 From: alexis.praga at gmail.com (Alexis Praga) Date: Tue, 28 Sep 2021 11:34:42 +0200 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: References: Message-ID: <9F74D417-F7BB-43EE-93B3-23EBAE2DEC5C@gmail.com> The only thing that was holding me back from dumping Archlinux packages was xmonad. It turns out it can easily be installed with: cabal install —lib xmonad xmonad-contrib Thanks, Alexis Praga > Le 28 sept. 2021 à 10:12, Branimir Maksimovic a écrit : > > Arch Linux has broken ghc installation as package maintener has some weird ideas… > You have to install it via soirces and avoid Arch packagases like plague. > > Greetings, Branimir. > >> On 28.09.2021., at 10:00, Alexis Praga wrote: >> >> Hi, >> >> >> Small feedback in case it’s useful: >> >> Switching from stack to cabal was painless with ghcup. I could not make it work without it (some dependencies failed to compile on Archlinux). >> >> Alexis Praga >> >>>> Le 18 sept. 2021 à 21:07, coot at coot.me a écrit : >>>> >>>  >>> Hi Alexis, >>> >>> There are several reasons: >>> >>> * reproducible nix style local builds. By specifying hackage index one can build against the same set of packages locally and on CI. >>> * has access to whole hackage, though at times requires a bit of thought, most of the time it works just fine. >>> * `cabal.project` and `cabal.project.local`: the first corresponds to `stack.yaml`, the other does not have a counter part in stack. For example, this is very useful, when one wants to modify ghc options per package, e.g. adding or removing `-Werror` ghc option, or configuring a ghc plugin >>> * some options work better than in stack. One example is `--allow-newer`. >>> * one can experiment with backpack, >>> >>> Cheers >>> Marcin >>> >>> Sent with ProtonMail Secure Email. >>> >>> ‐‐‐‐‐‐‐ Original Message ‐‐‐‐‐‐‐ >>>> On Saturday, September 18th, 2021 at 20:52, Alexis Praga wrote: >>>> Hi, >>>> >>>> As an intermediate beginner, I've been back into Haskell for the last >>>> months for a small project, using stack as the building tool. >>>> >>>> Why stack ? A few years back, I learned that it was the "best" way to build >>>> projects to avoid "cabal hell", which I understood at the time as >>>> "managing dependencies with cabal is hard". >>>> >>>> As such, I've use stack since and have been quite happy with it. The >>>> only drawback is that building a project can be quite long. >>>> >>>> This is usually not a problem, except for writing Haskell scripts using >>>> shelly (for example), where the stack layout is a bit impractical for >>>> fast-paced development. A solution is to use `runghc` or a script >>>> interpreter [1]. >>>> >>>> However, I've seen some projects where cabal is used to build directly >>>> instead of cabal, so it looks like the situation improved. >>>> >>>> My question is this: in 2021, is there a reason to switch back to cabal ? >>>> >>>> Thanks, >>>> >>>> [1] https://www.fpcomplete.com/haskell/tutorial/stack-script/ >>>> >>>> >>>> -- >>>> >>>> Alexis Praga >>> >> _______________________________________________ >> Haskell-Cafe mailing list >> To (un)subscribe, modify options or view archives go to: >> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe >> Only members subscribed via the mailman list are allowed to post. > -------------- next part -------------- An HTML attachment was scrubbed... URL: From anthony.d.clayden at gmail.com Tue Sep 28 10:00:59 2021 From: anthony.d.clayden at gmail.com (Anthony Clayden) Date: Tue, 28 Sep 2021 23:00:59 +1300 Subject: [Haskell-cafe] Very binding semicolon Message-ID: >From the department of improbable syntax/I don't get how this works, but it does: > f :: [a] -> [a] > ;; f xs = xs ++ reverse xs Nicely (to my eye) groups/indents the binding under the signature. Especially handy with ScopedTypeVariables, to show how the scoped vars 'belong' > f :: forall a. [a] -> [a] > ;; f xs = xs ++ ys > where > ys :: [a] > ys = reverse xs The doubled `;;` stands out like a ditto. It could be a single semicolon (which means there's an empty decl/binding between the semis -- I don't see that's allowed by the syntax). Unfortunately, for multi-line bindings you need to repeat the `;;` > f :: [a] -> [a] > ;; f [] = [] > ;; f xs = xs ++ reverse xs -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Tue Sep 28 10:20:41 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Tue, 28 Sep 2021 12:20:41 +0200 Subject: [Haskell-cafe] Very binding semicolon In-Reply-To: References: Message-ID: <6E897A4F-42F9-4166-92EB-6038C5249658@gmail.com> Nice ++ returns list so no issue. list concat reverse of same list. Clear. No need for empty case as it is already covered Greets, Branimir. > On 28.09.2021., at 12:00, Anthony Clayden wrote: > > From the department of improbable syntax/I don't get how this works, but it does: > > > f :: [a] -> [a] > > ;; f xs = xs ++ reverse xs > > Nicely (to my eye) groups/indents the binding under the signature. Especially handy with ScopedTypeVariables, to show how the scoped vars 'belong' > > > f :: forall a. [a] -> [a] > > ;; f xs = xs ++ ys > > where > > ys :: [a] > > ys = reverse xs > > The doubled `;;` stands out like a ditto. It could be a single semicolon (which means there's an empty decl/binding between the semis -- I don't see that's allowed by the syntax). > > Unfortunately, for multi-line bindings you need to repeat the `;;` > > > f :: [a] -> [a] > > ;; f [] = [] > > ;; f xs = xs ++ reverse xs > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Tue Sep 28 10:38:10 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Tue, 28 Sep 2021 12:38:10 +0200 Subject: [Haskell-cafe] Very binding semicolon In-Reply-To: References: Message-ID: <1B568DD5-3768-4DD0-82FC-47CC5A48EB00@gmail.com> Why this works :P bmaxa at Branimirs-Air haskell % ghc -O2 semi.hs Loaded package environment from /Users/bmaxa/.ghc/aarch64-darwin-8.10.7/environments/default [1 of 1] Compiling Main ( semi.hs, semi.o ) Linking semi ... bmaxa at Branimirs-Air haskell % ./semi [1,2,3,3,2,1] bmaxa at Branimirs-Air haskell % cat semi.hs main = do let lst = lrl [1,2,3] print lst ; ; ; ; ; ; ; ;;;;lrl :: [a]->[a]; ;; ; ; ; ; lrl xs = xs ++ reverse xs > On 28.09.2021., at 12:00, Anthony Clayden wrote: > > From the department of improbable syntax/I don't get how this works, but it does: > > > f :: [a] -> [a] > > ;; f xs = xs ++ reverse xs > > Nicely (to my eye) groups/indents the binding under the signature. Especially handy with ScopedTypeVariables, to show how the scoped vars 'belong' > > > f :: forall a. [a] -> [a] > > ;; f xs = xs ++ ys > > where > > ys :: [a] > > ys = reverse xs > > The doubled `;;` stands out like a ditto. It could be a single semicolon (which means there's an empty decl/binding between the semis -- I don't see that's allowed by the syntax). > > Unfortunately, for multi-line bindings you need to repeat the `;;` > > > f :: [a] -> [a] > > ;; f [] = [] > > ;; f xs = xs ++ reverse xs > > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -------------- next part -------------- An HTML attachment was scrubbed... URL: From daniel.trstenjak at gmail.com Tue Sep 28 17:02:03 2021 From: daniel.trstenjak at gmail.com (Daniel Trstenjak) Date: Tue, 28 Sep 2021 19:02:03 +0200 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: <9F74D417-F7BB-43EE-93B3-23EBAE2DEC5C@gmail.com> References: <9F74D417-F7BB-43EE-93B3-23EBAE2DEC5C@gmail.com> Message-ID: <20210928170203.GA54662@octa> On Tue, Sep 28, 2021 at 11:34:42AM +0200, Alexis Praga wrote: > It turns out it can easily be installed with: > cabal install —lib xmonad xmonad-contrib If you need xmonad-contrib you most likely have your own xmonad configuration, in which case it's IMHO even simpler to define a cabal project for your xmonad configuration, which then depends on xmonad, xmonad-contrib or xmonad-extras (e.g https://github.com/dan-t/xmonad-config). This made it a lot easier for me to rebuild my xmonad configuration when updating anything on my system. Greetings, Daniel From emilypi at cohomolo.gy Wed Sep 29 04:26:08 2021 From: emilypi at cohomolo.gy (Emily Pillmore) Date: Wed, 29 Sep 2021 04:26:08 +0000 Subject: [Haskell-cafe] [ANN] CLC Elections Outcome - September 2021 Message-ID: Hello Haskell! I'm pleased to announce that the Core Libraries Committee Elections for September 2021 have concluded, and we have selected 2 new CLC members: - [Andrew Lelechenko]( https://github.com/Bodigrim ) - [Melanie Brown]( https://github.com/bi-functor ) The candidate pool was especially broad for this election and it was very difficult to choose, but we'd like to thank everyone for applying nonetheless. It is genuinely heartwarming to see so many people eager to help support the Haskell ecosystem in an official capacity! We encourage any and all candidates to continue helping to support the core libraries as we renovate the CLC. As mentioned in the latest CLC update (see: https://discourse.haskell.org/t/state-of-the-core-libraries-committee-update/2911 ), we are set to begin writing a new process and ways of working for the CLC now that the elections have concluded. We aim to have these finished within the month. Happy Hacking! Emily Pillmore - on behalf of the CLC -------------- next part -------------- An HTML attachment was scrubbed... URL: From branimir.maksimovic at gmail.com Wed Sep 29 04:56:43 2021 From: branimir.maksimovic at gmail.com (Branimir Maksimovic) Date: Wed, 29 Sep 2021 06:56:43 +0200 Subject: [Haskell-cafe] [ANN] CLC Elections Outcome - September 2021 In-Reply-To: References: Message-ID: Haskell is for hackers :P People that learn to program, by poking numbers into memory :P > On 29.09.2021., at 06:26, Emily Pillmore wrote: > > Hello Haskell! > > > Happy Hacking! > Thanks! From olf at aatal-apotheke.de Wed Sep 29 20:58:03 2021 From: olf at aatal-apotheke.de (Olaf Klinke) Date: Wed, 29 Sep 2021 22:58:03 +0200 Subject: [Haskell-cafe] canonicalization of interval libraries Message-ID: <389c8f1ea80b052009a506155ca834e0f2de884c.camel@aatal-apotheke.de> Emily Pillmore wrote: > Hello Haskell! > > I'm pleased to announce that the Core Libraries Committee Elections for September 2021 have concluded, and we have selected 2 new CLC members: > > - [Andrew Lelechenko]( https://github.com/Bodigrim ) > > - [Melanie Brown]( https://github.com/bi-functor ) > I could not help but notice that both new members have either written or contributed to an interval library. There are a handful out there (disclaimer: I have written one of them) but as far as I know there is no de-facto standard. Why is that? Is it because the applications of intervals are too diverse and hence no single type fits all? Or is it because it is such a niche application that no single library could gather enough traction? I'm curious whether others see the need to have a de-facto standard interval library that is both general and performant, as we are used to from our "core libraries". Judging from the number of downloads on hackage, people are mostly interested in intervals of floating point numbers and intervals of time. Olaf P.S. Yes, I am aware of the relevant xkcd comic on standards. From ruben.astud at gmail.com Thu Sep 30 14:59:11 2021 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Thu, 30 Sep 2021 11:59:11 -0300 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: <20210928170203.GA54662@octa> References: <9F74D417-F7BB-43EE-93B3-23EBAE2DEC5C@gmail.com> <20210928170203.GA54662@octa> Message-ID: On 28-09-21 14:02, Daniel Trstenjak wrote: > in which case it's IMHO even simpler to define a cabal project for your > xmonad configuration, which then depends on xmonad, xmonad-contrib or > xmonad-extras (e.g https://github.com/dan-t/xmonad-config). I do the same and I think it is better. I just want to point out that sometimes you will miss the mod-q keybinding to recompile and test on the fly :^| -- Rubén. (pgp: 4EE9 28F7 932E F4AD) From allbery.b at gmail.com Thu Sep 30 15:22:27 2021 From: allbery.b at gmail.com (Brandon Allbery) Date: Thu, 30 Sep 2021 11:22:27 -0400 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: References: <9F74D417-F7BB-43EE-93B3-23EBAE2DEC5C@gmail.com> <20210928170203.GA54662@octa> Message-ID: If you use a build script (see the xmonad-testing repo for one that works with cabal projects; it's tested because I use it myself) you can get mod-q back. On Thu, Sep 30, 2021 at 11:00 AM Ruben Astudillo wrote: > On 28-09-21 14:02, Daniel Trstenjak wrote: > > in which case it's IMHO even simpler to define a cabal project for your > > xmonad configuration, which then depends on xmonad, xmonad-contrib or > > xmonad-extras (e.g https://github.com/dan-t/xmonad-config). > > I do the same and I think it is better. I just want to point out that > sometimes you will miss the mod-q keybinding to recompile and test on the > fly :^| > > -- > Rubén. (pgp: 4EE9 28F7 932E F4AD) > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- brandon s allbery kf8nh allbery.b at gmail.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From ruben.astud at gmail.com Thu Sep 30 15:33:47 2021 From: ruben.astud at gmail.com (Ruben Astudillo) Date: Thu, 30 Sep 2021 12:33:47 -0300 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: References: <9F74D417-F7BB-43EE-93B3-23EBAE2DEC5C@gmail.com> <20210928170203.GA54662@octa> Message-ID: On 30-09-21 12:22, Brandon Allbery wrote: > If you use a build script (see the xmonad-testing repo for one that works > with cabal projects; it's tested because I use it myself) you can get mod-q > back. Good reference! Thanks! -- Rubén. (pgp: 4EE9 28F7 932E F4AD) From alexis.praga at gmail.com Thu Sep 30 20:53:31 2021 From: alexis.praga at gmail.com (Alexis Praga) Date: Thu, 30 Sep 2021 22:53:31 +0200 Subject: [Haskell-cafe] Cabal or stack in 2021 ? In-Reply-To: References: <9F74D417-F7BB-43EE-93B3-23EBAE2DEC5C@gmail.com> <20210928170203.GA54662@octa> Message-ID: <8735pl6b04.fsf@gmail.com> Speaking about a build script, FreeBSD has one for xmonad (see below, located in /usr/local/share/examples/xmonad/build). 8<------------------------------------------------------------------------------ #!/bin/sh # must match "executable" line from xmonad-config.cabal EXE_NAME=xmonad-config # xmonad tells us how it want resulting executable to be named output_file=$1; shift CFG_DIR="$HOME/.xmonad" if [ ! -f "$HOME/.cabal/config" ]; then cabal new-update fi # build the config cd $CFG_DIR cabal new-configure --enable-optimization --enable-executable-stripping cabal new-build if [ "$output_file" != "" ]; then # move resulting binary where it was requested to reside res=`find $CFG_DIR/dist-newstyle -type f -perm +111 -name $EXE_NAME` if [ "$res" == "" ]; then return 1 fi # use "mv" to be able to replace a running executable mv -f "$res" "$output_file" cp "$output_file" "$res" fi 8<------------------------------------------------------------------------------ > On 30-09-21 12:22, Brandon Allbery wrote: >> If you use a build script (see the xmonad-testing repo for one that works >> with cabal projects; it's tested because I use it myself) you can get mod-q >> back. > > Good reference! Thanks! > > -- > Rubén. (pgp: 4EE9 28F7 932E F4AD) > _______________________________________________ > Haskell-Cafe mailing list > To (un)subscribe, modify options or view archives go to: > http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe > Only members subscribed via the mailman list are allowed to post. -- Alexis Praga