Newest at the top
2024-12-22 06:03:41 +0100 | <orangeflu> | when you say 'strict', do you mean not lazily? |
2024-12-22 06:03:41 +0100 | housemate | (~housemate@124.187.109.206) housemate |
2024-12-22 06:02:43 +0100 | <haskellbridge> | <Bowuigi> Passing state around in a strict way, along with nice syntax sugar is what this is supposed to do |
2024-12-22 06:01:02 +0100 | <orangeflu> | anyway) |
2024-12-22 06:00:55 +0100 | <orangeflu> | i know what a state monad is, i think. like, if i have a function, that takes a container and returns a modified container and a result, i can chain them together with do notation. that's what i understand anyway. But how is that different from what i'm doing now? except for the fact that i don't chain them in a do block (which wouldn't be useful anyway, cause i don't execute instructions that way |
2024-12-22 05:58:10 +0100 | housemate | (~housemate@124.187.109.206) (Quit: Nothing to see here. I wasn't there. I take IRC seriously.) |
2024-12-22 05:58:10 +0100 | <haskellbridge> | <Bowuigi> Hmmm moving to a strict state monad to handle your emulator state could also help. It attacks space leaks more directly and is a smaller change |
2024-12-22 05:57:03 +0100 | merijn | (~merijn@128-137-045-062.dynamic.caiway.nl) (Ping timeout: 252 seconds) |
2024-12-22 05:56:33 +0100 | rvalue | (~rvalue@user/rvalue) rvalue |
2024-12-22 05:56:06 +0100 | <haskellbridge> | <Bowuigi> MVector is a somewhat extreme solution, mutable stuff is fairly common in heavily optimized programs/libraries like smalltt or flatparse (there are a lot more examples but I know those two more in depth than anything else) |
2024-12-22 05:56:01 +0100 | rvalue | (~rvalue@user/rvalue) (Read error: Connection reset by peer) |
2024-12-22 05:55:39 +0100 | xff0x | (~xff0x@p3704193-ipxg12201sapodori.hokkaido.ocn.ne.jp) (Ping timeout: 265 seconds) |
2024-12-22 05:55:02 +0100 | <orangeflu> | thing is, this is both a learning project and something that i want to be useful |
2024-12-22 05:54:35 +0100 | <orangeflu> | i'm sure i did a horrible job of writing this and there are a bunch of stuff that make no sense or could be optimized heavily |
2024-12-22 05:53:42 +0100 | <haskellbridge> | <Bowuigi> There might be a more obvious refactor that we missed tho |
2024-12-22 05:52:47 +0100 | <haskellbridge> | <Bowuigi> Just like optimization in other languages ofc |
2024-12-22 05:52:31 +0100 | merijn | (~merijn@128-137-045-062.dynamic.caiway.nl) merijn |
2024-12-22 05:52:25 +0100 | <haskellbridge> | <Bowuigi> With MVector you need something like IO everywhere yes. Haskell optimization is not for begginners |
2024-12-22 05:51:38 +0100 | <orangeflu> | This seems more trouble than its worth considering I don't even understand how to use, let alone modify all my pure functions into using it atop of my InputT IO stuff |
2024-12-22 05:51:38 +0100 | <haskellbridge> | <Bowuigi> c_wraith you might be able to help more with this, the codebase is in https://github.com/Flu/avr-emulator and the profiling results are in https://paste.tomsmeding.com/b9owLIrr |
2024-12-22 05:51:18 +0100 | peterbecich | (~Thunderbi@syn-047-229-123-186.res.spectrum.com) (Ping timeout: 265 seconds) |
2024-12-22 05:50:50 +0100 | <orangeflu> | Does that mean now I will need to have IO everywhere? |
2024-12-22 05:50:33 +0100 | <orangeflu> | well, the idea is to transition to mvectors, but i thought it would be easier. I am also using InputT IO (EmulatorState) in my REPL because i am using haskeline, so not sure how that is going to affect things with mvector. Also, there is also the functionality for reading a file and then ditching the IO after that, before executing |
2024-12-22 05:49:10 +0100 | xff0x | (~xff0x@p3704193-ipxg12201sapodori.hokkaido.ocn.ne.jp) |
2024-12-22 05:45:26 +0100 | housemate | (~housemate@124.187.109.206) housemate |
2024-12-22 05:43:35 +0100 | <haskellbridge> | <Bowuigi> The Array here was used as if it was a mutable one (it was the original idea, but the name Array was somewhat misleading since it isn't a C array) |
2024-12-22 05:41:47 +0100 | <c_wraith> | (It's likely to not avoid space leaks) |
2024-12-22 05:41:18 +0100 | <c_wraith> | That's a kind of bad way to avoid space leaks. It's better to write code that uses space invariants properly. But it has enough other benefits that it's still worth doing. |
2024-12-22 05:41:13 +0100 | <haskellbridge> | <Bowuigi> orangeflu the idea is to run the modifications on IO only (ST also works but it's not what we want here), that's what the "PrimMonad" stuff means |
2024-12-22 05:40:24 +0100 | merijn | (~merijn@128-137-045-062.dynamic.caiway.nl) (Ping timeout: 246 seconds) |
2024-12-22 05:39:41 +0100 | <haskellbridge> | <Bowuigi> c_wraith Some context, orangeflu is writing an emulator. This emulator has a fixed memory, which used to be in an Array. This caused space leaks, so I and [exa] suggested using an MVector because it provides benefits on this use case |
2024-12-22 05:37:37 +0100 | <orangeflu> | c_wraith said "you return an immutable value". So i go in ST or IO, mutate it however i wish based on what the instruction needs to do, then when i remove it from IO, it becomes immutable? |
2024-12-22 05:37:37 +0100 | <c_wraith> | If you're using IO mutable vectors, ignore everything about ST. |
2024-12-22 05:36:43 +0100 | <c_wraith> | Eh, I started answering questions starting from "what's the eliminator for ST" |
2024-12-22 05:36:30 +0100 | <haskellbridge> | <Bowuigi> What |
2024-12-22 05:36:02 +0100 | <orangeflu> | how do i return an immutable value? |
2024-12-22 05:36:01 +0100 | <haskellbridge> | <Bowuigi> The idea was to have an MVector on IO, not on ST |
2024-12-22 05:36:00 +0100 | merijn | (~merijn@128-137-045-062.dynamic.caiway.nl) merijn |
2024-12-22 05:33:21 +0100 | <c_wraith> | Bowuigi: eh? If you want to mutate it in ST, you need to allocate it in ST. |
2024-12-22 05:33:08 +0100 | <haskellbridge> | <Bowuigi> So you allocate the memory in main as usual, but instead of creating an array you create an MVector |
2024-12-22 05:32:43 +0100 | <haskellbridge> | <Bowuigi> orangeflu you have to create the MVector in IO, not in ST |
2024-12-22 05:30:13 +0100 | <c_wraith> | orangeflu: The point of ST is that you encapsulate *all* the mutation in a single call to runST. You return an immutable value. |
2024-12-22 05:28:35 +0100 | merijn | (~merijn@128-137-045-062.dynamic.caiway.nl) (Ping timeout: 265 seconds) |
2024-12-22 05:27:45 +0100 | aforemny | (~aforemny@89.244.199.39) aforemny |
2024-12-22 05:27:06 +0100 | aforemny | (~aforemny@2001:9e8:6cf6:8000:f088:f772:a53:8f63) (Ping timeout: 246 seconds) |
2024-12-22 05:24:27 +0100 | machinedgod | (~machinedg@d108-173-18-100.abhsia.telus.net) (Ping timeout: 276 seconds) |
2024-12-22 05:23:56 +0100 | merijn | (~merijn@128-137-045-062.dynamic.caiway.nl) merijn |
2024-12-22 05:19:06 +0100 | <orangeflu> | lose the vector, right? |
2024-12-22 05:19:00 +0100 | <orangeflu> | c_wraith: so, if i understand correctly, everywhere i need to modify the mvector, it needs to return ST s (MVector s Int). Just to read it, i need to be in at least ST s Int. Then how do I reconcile that with getting user input and stuff. I have a bunch of other monads i need to think about in my REPL, that need to take input from the user and so on. But if i escape this ST by running through runST, i |
2024-12-22 05:18:56 +0100 | <haskellbridge> | <thirdofmay18081814goya> I don't know, here's the type "switch :: SF i (o, Event e) -> (e -> SF i o) -> SF i o" |