Logs: liberachat/#haskell
| 2021-08-17 22:44:03 | × | fendor quits (~fendor@77.119.161.62.wireless.dyn.drei.com) (Remote host closed the connection) |
| 2021-08-17 22:44:13 | <monochrom> | Either that, or it lacks supporting cursor keys when in insert mode. |
| 2021-08-17 22:44:42 | <hpc> | it's both - i remember using real vi aaaaaages ago |
| 2021-08-17 22:45:14 | <sm> | cursor keys are always broken one way or another |
| 2021-08-17 22:45:25 | <sm> | it's a law |
| 2021-08-17 22:45:53 | <hpc> | sometimes i enjoy when they don't work |
| 2021-08-17 22:46:00 | <hpc> | once i put the konami code in my ssh password |
| 2021-08-17 22:46:12 | <sm> | in terminals, at least |
| 2021-08-17 22:46:28 | <monochrom> | hahaha |
| 2021-08-17 22:52:40 | → | lavaman joins (~lavaman@98.38.249.169) |
| 2021-08-17 22:52:42 | <pompez> | Hi, new and learning Haskell. I am wondering -- why does the this short snippet (https://paste.tomsmeding.com/6iIA5HM8) evaluate as I'd expect it to? I'd expect 2 input prompts and then evaluating as a 2 elements long IO [String]. But the program just doesn't stop with the prompts. Could it be something about IO that prevents it from being lazily evaluated? |
| 2021-08-17 22:53:11 | <pompez> | *doesn't |
| 2021-08-17 22:53:24 | → | merijn joins (~merijn@83-160-49-249.ip.xs4all.nl) |
| 2021-08-17 22:54:11 | <hpc> | you're mixing evaluation and execution |
| 2021-08-17 22:54:39 | <hpc> | execution is strict (unless you use a few specific definitions that use lazy IO) |
| 2021-08-17 22:55:10 | <sclv> | sequence just runs the io actions one after the other |
| 2021-08-17 22:55:38 | <hpc> | and since you use repeat, it's going to keep asking forever |
| 2021-08-17 22:56:04 | <hpc> | now what you can do is write something like do {lineActions <- repeat getLine; sequence (take 2 lineActions)} |
| 2021-08-17 22:56:19 | <hpc> | er |
| 2021-08-17 22:56:22 | <pompez> | I tried that and it worked as expected |
| 2021-08-17 22:56:37 | × | eggplantade quits (~Eggplanta@108-201-191-115.lightspeed.sntcca.sbcglobal.net) (Remote host closed the connection) |
| 2021-08-17 22:56:40 | <hpc> | that first line is let ...=... but you know what i mean |
| 2021-08-17 22:56:54 | <pompez> | I do |
| 2021-08-17 22:56:59 | <monochrom> | You're expecting the equivalent of: if you have "main = getLine >> getLine >> return ()", it will never need any input from you. |
| 2021-08-17 22:57:01 | × | geekosaur quits (~geekosaur@xmonad/geekosaur) (Remote host closed the connection) |
| 2021-08-17 22:57:07 | × | lavaman quits (~lavaman@98.38.249.169) (Ping timeout: 245 seconds) |
| 2021-08-17 22:57:07 | → | eggplantade joins (~Eggplanta@108-201-191-115.lightspeed.sntcca.sbcglobal.net) |
| 2021-08-17 22:57:39 | <monochrom> | I can respect that expectation if you don't know better a priori, but one single empirical test readily debunks that mental model. |
| 2021-08-17 22:58:51 | <monochrom> | Let's get more whimsical and philosophical. If you have "main = putStrLn "hello"" and run it but you don't look, does the printing happen? |
| 2021-08-17 22:59:17 | → | geekosaur joins (~geekosaur@xmonad/geekosaur) |
| 2021-08-17 22:59:23 | <pompez> | monochrom: That example (with a test) really helps |
| 2021-08-17 22:59:25 | × | jay-invariant quits (~jay@c-24-4-6-169.hsd1.ca.comcast.net) (Quit: Leaving) |
| 2021-08-17 22:59:26 | <sclv> | i'd need to look to find out :-) |
| 2021-08-17 22:59:37 | <sclv> | like maybe the computer caught fire |
| 2021-08-17 22:59:44 | <pompez> | Hah |
| 2021-08-17 23:00:09 | <hpc> | @quote warm |
| 2021-08-17 23:00:10 | <lambdabot> | edwardk says: i think the comonads are warm fuzzy, and the monads are warm sticky. its easy to get out of a comonad, its soft and you like wearing it. monads on the other hand stick to you and are |
| 2021-08-17 23:00:10 | <lambdabot> | icky |
| 2021-08-17 23:00:18 | <pompez> | Well, but would it be impossible to do inputs in a lazy manner? |
| 2021-08-17 23:00:28 | sclv | has debugged far too many things to trust anything happens |
| 2021-08-17 23:00:33 | <monochrom> | That's the realm of getContents. |
| 2021-08-17 23:00:59 | <hpc> | @quote 286.ghc |
| 2021-08-17 23:00:59 | <lambdabot> | cjeris says: vincenz: no, on a 286 GHC feels warm, like a little fire you can warm your hands at. wait, that smells funny. wait, that was my CPU. |
| 2021-08-17 23:01:18 | <monochrom> | I generally discourage it unless you have proved that you can perfectly predict lazy evaluation. |
| 2021-08-17 23:01:19 | <sclv> | you can look at the source of sequence, and write a similar version that calls `unsafePerformIO` every time it actually executes an IO action, and that would correspond to what you're looking for |
| 2021-08-17 23:01:25 | <sclv> | but I do _not_ recommend this in practice :-) |
| 2021-08-17 23:01:49 | <hpc> | more directly, there's unsafeInterleaveIO |
| 2021-08-17 23:02:06 | <sclv> | oh right, i meant to say interleave rather than what i did |
| 2021-08-17 23:02:41 | <hpc> | and just to emphasize, the word "unsafe" there is not just for fun |
| 2021-08-17 23:02:51 | <pompez> | Well, I am not intending to do something just because. But why is it not used in practice? |
| 2021-08-17 23:02:52 | × | Tuplanolla quits (~Tuplanoll@91-159-69-50.elisa-laajakaista.fi) (Quit: Leaving.) |
| 2021-08-17 23:02:58 | × | Pickchea quits (~private@user/pickchea) (Quit: Leaving) |
| 2021-08-17 23:03:08 | <sclv> | unsafeInterleaveIO basically takes an `IO a` and "delays" it so that when you get the `a` out of it, it doesn't actually perform the IO action until the `a` is evaluated. So hrm... you could map unsafeInterleave over your list, then sequence it..? |
| 2021-08-17 23:03:22 | × | notzmv quits (~zmv@user/notzmv) (Ping timeout: 245 seconds) |
| 2021-08-17 23:03:29 | <hpc> | pompez: evaluation order isn't guaranteed, so tying execution to evaluation makes execution order not guaranteed |
| 2021-08-17 23:03:34 | <sclv> | its not used in practice because predicting evaluation order is tricky, and can lead to surprising effects, even for seasoned programmers |
| 2021-08-17 23:04:01 | <sclv> | and at times things may be repeatedly executed you expected to only be executed once, or things you thought would be executed never are |
| 2021-08-17 23:04:07 | <monochrom> | We want I/O to jump-start lazy evaluation (lest there is really nothing to evaluate). This is simplest if I/O is not lazy. |
| 2021-08-17 23:04:31 | <sclv> | so the sequencing the IO monad provides gives nice guardrails that help reasoning |
| 2021-08-17 23:04:34 | <pompez> | Makes sense |
| 2021-08-17 23:04:35 | <monochrom> | Besides, we don't really want to answer the kind of whimsical philosophical question I posed. |
| 2021-08-17 23:05:05 | <monochrom> | "if no one is looking, should getLine and putStrLn do anything?" |
| 2021-08-17 23:05:24 | <monochrom> | You don't want to go down that rabbit hole. They do their jobs here and now. KISS. |
| 2021-08-17 23:05:27 | <sclv> | (note: I have used and do use these primitives carefully, and in situations that warrant it, but only after thinking really hard, consulting, and deciding it actually makes sense. and even then i've made mistakes and been surprised) |
| 2021-08-17 23:05:44 | × | Cajun quits (~Cajun@user/cajun) (Quit: Client closed) |
| 2021-08-17 23:05:55 | → | Guest84 joins (~Guest84@2406:3003:2006:447e:a859:4a56:2629:b84e) |
| 2021-08-17 23:07:27 | <pompez> | Could you maybe recommend a good resource that talks about evaluationand execution as it pertains to Haskell? |
| 2021-08-17 23:08:57 | <sclv> | https://www.seas.upenn.edu/~cis194/fall16/lectures/06-io-and-monads.html ? |
| 2021-08-17 23:09:07 | <sclv> | I suggest playing around yourself just a little longer as you have been |
| 2021-08-17 23:09:15 | <sclv> | and you'll probably get a good intuition fast |
| 2021-08-17 23:10:53 | <pompez> | Will do |
| 2021-08-17 23:10:57 | <pompez> | And thanks a lot |
| 2021-08-17 23:13:55 | → | notzmv joins (~zmv@user/notzmv) |
| 2021-08-17 23:20:17 | → | hiruji joins (~hiruji@user/hiruji) |
| 2021-08-17 23:20:35 | <Cale> | pompez: Evaluation is the process of turning expressions into values, typically for the purposes of deciding which pattern matches, or occasionally in order to turn an expression of a function type into a lambda so that it can be applied. |
| 2021-08-17 23:20:59 | <Cale> | pompez: In Haskell, that process doesn't cause anything user-visible to happen apart from memory being allocated and the CPU getting hot. |
| 2021-08-17 23:22:15 | <Cale> | Instead, IO action values describe effects. Evaluating the expression for an IO action doesn't cause the effect to occur, it just possibly does some work to figure out which thing to do is being described. |
| 2021-08-17 23:23:03 | <Cale> | Execution is the process of carrying out the effects described by IO action values. In a compiled program, the IO action called 'main' gets executed, and you can also execute IO actions by giving them to ghci. |
| 2021-08-17 23:23:53 | → | aarvar joins (~aaron@2601:602:a080:fa0:2492:1e35:77f6:26e2) |
| 2021-08-17 23:24:11 | <Cale> | (It will magically notice when an expression denotes an IO action and execute it for you as well as print the result of the execution. Otherwise, it just tries to use 'show' on things to turn them into a String to print.) |
| 2021-08-17 23:25:15 | <hpc> | one useful thing to note here is that there's no in-language notion of "just execute this" - just sequencing which is "after this executes, execute this" |
| 2021-08-17 23:25:22 | × | Matthia__ quits (~Matthias1@2603-8001-b545-4900-55c2-9e3a-8dc6-4263.res6.spectrum.com) (Remote host closed the connection) |
| 2021-08-17 23:25:47 | → | lbseale joins (~lbseale@user/ep1ctetus) |
| 2021-08-17 23:25:48 | <hpc> | and no in-language notion of "just evaluate this" either - just "in order to evaluate this, you need to evaluate that" |
| 2021-08-17 23:25:55 | <Cale> | Yeah, do-blocks let you combine a bunch of IO actions to produce another IO action, and those are syntax sugar for a chain of uses of (>>=) which basically does the same. |
| 2021-08-17 23:26:01 | → | argento joins (~argent0@168-227-97-23.ptr.westnet.com.ar) |
| 2021-08-17 23:26:02 | → | Matthias1 joins (~Matthias1@2603-8001-b545-4900-55c2-9e3a-8dc6-4263.res6.spectrum.com) |
| 2021-08-17 23:27:10 | <hpc> | and when you're figuring out how something gets evaluated, think in terms of chains of those if-thens |
| 2021-08-17 23:27:40 | × | merijn quits (~merijn@83-160-49-249.ip.xs4all.nl) (Ping timeout: 240 seconds) |
| 2021-08-17 23:28:52 | × | jgeerds quits (~jgeerds@55d45555.access.ecotel.net) (Ping timeout: 245 seconds) |
| 2021-08-17 23:29:03 | <hpc> | (also when someone says "expr is strict in x", they're saying "in order to evaluate expr, you need to evaluate x") |
| 2021-08-17 23:29:50 | × | superbil quits (~superbil@1-34-176-171.HINET-IP.hinet.net) (Ping timeout: 252 seconds) |
| 2021-08-17 23:30:52 | × | Matthias1 quits (~Matthias1@2603-8001-b545-4900-55c2-9e3a-8dc6-4263.res6.spectrum.com) (Ping timeout: 245 seconds) |
| 2021-08-17 23:32:27 | <lbseale> | I am using haddock to generate some docs, and it's working, but it's ignoring my input for the title. Instead of the title it just says "ml" in the top-left. Anyone know what to do? |
| 2021-08-17 23:32:33 | <pompez> | Cale: Are list comprehensions with <- also just synax sugar for the same thing? |
| 2021-08-17 23:33:35 | <Cale> | pompez: Basically. You could also desugar them in terms of concatMap, but that is equivalent to the (>>=) for lists. |
| 2021-08-17 23:33:59 | → | Gurkenglas_ joins (~Gurkengla@dslb-002-203-144-156.002.203.pools.vodafone-ip.de) |
| 2021-08-17 23:34:19 | <hpc> | [f x | x <- something; boolean expression] translates to do {x <- something; guard (boolean expression); pure (f x)} |
| 2021-08-17 23:34:26 | <monochrom> | Instead of answering that question, I would evade it and answer "the generated asm code is the same", and "does it really matter how to compiler gets there?" |
| 2021-08-17 23:34:26 | <hpc> | :t guard |
All times are in UTC.