Logs: liberachat/#haskell
| 2021-07-01 03:21:25 | <dsal> | Stuff like this. |
| 2021-07-01 03:21:29 | → | jao joins (~jao@cpc103048-sgyl39-2-0-cust502.18-2.cable.virginm.net) |
| 2021-07-01 03:21:30 | <dsal> | Why do you think go slices are mutable? |
| 2021-07-01 03:21:54 | → | sheepduck joins (~sheepduck@user/sheepduck) |
| 2021-07-01 03:22:07 | <qrpnxz> | uh cause they are |
| 2021-07-01 03:22:12 | <qrpnxz> | idk what you are demonstrating here btw |
| 2021-07-01 03:22:21 | <nshepperd> | this go program is claimed to be fast, so i assume 'primes = append(primes, n)' is not copying the vector, but writing to the available space at the end of the storage |
| 2021-07-01 03:22:33 | <qrpnxz> | only grows as needed |
| 2021-07-01 03:22:34 | <dsal> | (oops, messed up that format string) |
| 2021-07-01 03:22:41 | <dsal> | qrpnxz: Please demonstrate mutating a slice. |
| 2021-07-01 03:22:48 | <qrpnxz> | s[0] = 1 |
| 2021-07-01 03:22:53 | <dsal> | That doesn't change s. |
| 2021-07-01 03:23:15 | <qrpnxz> | obj.set(0) doesn't change obj either |
| 2021-07-01 03:23:32 | <dsal> | I don't know what obj is. |
| 2021-07-01 03:23:53 | <qrpnxz> | a reference type, like slices. You can imagine it as any java object |
| 2021-07-01 03:23:56 | <dsal> | nshepperd: append *might* copy and it might mutate the underlying array. If it mutates the underlying array, it might affect other things that share the array. |
| 2021-07-01 03:24:20 | <nshepperd> | in which case, a = append(primes, 1); b = append (primes, 2) will result in both a and b containing 2 |
| 2021-07-01 03:24:39 | <dsal> | nshepperd: Yeah, that's what I'm demonstrating. It'll do that *sometimes* |
| 2021-07-01 03:24:46 | <qrpnxz> | right, append returns a new slice, the new slice might be pointing to new memory. I don't care about the old slice, so i assign it on top of the old one |
| 2021-07-01 03:24:50 | <nshepperd> | sounds horribly |
| 2021-07-01 03:25:28 | <dsal> | There are a few places go makes for strange bugs. |
| 2021-07-01 03:25:36 | × | shapr quits (~user@pool-108-28-144-11.washdc.fios.verizon.net) (Ping timeout: 272 seconds) |
| 2021-07-01 03:25:48 | <qrpnxz> | a is always looks like primes with 1 at the end |
| 2021-07-01 03:25:55 | <qrpnxz> | b always looks like primes with 2 at the end |
| 2021-07-01 03:26:15 | <dsal> | qrpnxz: that's not true, as I demonstrated here: https://play.golang.org/p/FlJSCKXl-xE |
| 2021-07-01 03:26:16 | <nshepperd> | how does append enforce that? reference counting? |
| 2021-07-01 03:26:42 | <qrpnxz> | ah your thing works now |
| 2021-07-01 03:26:46 | <qrpnxz> | ah yeah ur right lol |
| 2021-07-01 03:26:56 | <qrpnxz> | well w/e, this literally never comes up |
| 2021-07-01 03:26:59 | <nshepperd> | lol |
| 2021-07-01 03:27:07 | <dsal> | This comes up *all the time*. |
| 2021-07-01 03:27:21 | <qrpnxz> | if you need a nice pure slice you just make yourself a new one like append([]int{}, old...) |
| 2021-07-01 03:27:31 | <qrpnxz> | lol where |
| 2021-07-01 03:27:34 | <dsal> | You can reslice with a maximum capacity without forcing a copy. |
| 2021-07-01 03:27:46 | <dsal> | In large go codebases? I work on... very large go codebases. |
| 2021-07-01 03:27:47 | <qrpnxz> | yeah so? |
| 2021-07-01 03:27:48 | <nshepperd> | so append assumes uniqueness |
| 2021-07-01 03:27:53 | <nshepperd> | that's pretty sharp |
| 2021-07-01 03:28:02 | <qrpnxz> | append doesn't assume anything |
| 2021-07-01 03:28:05 | <qrpnxz> | just does what it does |
| 2021-07-01 03:28:19 | <dsal> | append does two distinct things depending on stuff you're probably not paying attention to. |
| 2021-07-01 03:28:21 | <qrpnxz> | ok it assumes that you know what append does |
| 2021-07-01 03:28:22 | <qrpnxz> | lol |
| 2021-07-01 03:29:01 | <dsal> | If you're below cap, it just copies your new value into the underlying array past the len index and returns a new slice with len incremented. If you're at cap, it allocates a new array, copies all the existing data and then adds your new item. |
| 2021-07-01 03:29:19 | <dsal> | (which is sort of like realloc, which also has fun bugs) |
| 2021-07-01 03:30:12 | <qrpnxz> | idk how this ever comes up as a problem honestly, if you got a foreign slice that you don't own and you want to append and stuff, you copy it |
| 2021-07-01 03:30:24 | <dsal> | Why would you copy it? |
| 2021-07-01 03:30:34 | → | rachel231 joins (~rachel231@c-73-142-199-151.hsd1.nh.comcast.net) |
| 2021-07-01 03:30:59 | <dsal> | You can always reslice adjusting the cap down. |
| 2021-07-01 03:31:06 | <qrpnxz> | if you don't own it and you wanna do crap like append to it, or use it after the real owner needs it again |
| 2021-07-01 03:31:21 | <qrpnxz> | go giving you the change to copy if you need to and not copy if you don't need to |
| 2021-07-01 03:31:31 | × | TranquilEcho quits (~grom@user/tranquilecho) (Quit: WeeChat 2.8) |
| 2021-07-01 03:32:15 | <qrpnxz> | some api gives you a copy every time, sometimes it gives you a buffer slice only valid until next call. If it's the latter you can get very efficient, but if you need to keep the slice past the call, you copy yourself |
| 2021-07-01 03:33:02 | <nshepperd> | if you need to copy it before appending is safe, shouldn't copying return a different type so you don't fuck it up |
| 2021-07-01 03:33:32 | <dsal> | In general, I try to steer people towards doing stuff that doesn't create bugs. It's difficult sometimes. |
| 2021-07-01 03:33:52 | <qrpnxz> | bro this is not haskell, we don't do immutable data structures generally lol |
| 2021-07-01 03:34:19 | <nshepperd> | idk this api seems like a mistake |
| 2021-07-01 03:34:30 | <qrpnxz> | like for example https://golang.org/pkg/bufio/#Reader.ReadSlice if you don't need to keep the bytes, then you can zip through a reader super fast, by not copying, but if you do need them you just copy, or use another method that automatically copies |
| 2021-07-01 03:34:34 | <nshepperd> | compared to plain ol dynamic vectors |
| 2021-07-01 03:34:58 | <dsal> | Part of my day job is teaching people at google how to write less buggy go code. |
| 2021-07-01 03:34:59 | <qrpnxz> | well actually there is one exception, which is strings. If you want immutable byte slice in go you use string |
| 2021-07-01 03:35:33 | <qrpnxz> | dsal, i thought googlers were supposed to be good, not reuse slices they weren't supposed to |
| 2021-07-01 03:35:36 | → | spruit11 joins (~quassel@2a02:a467:ccd6:1:d8ed:8d81:7c94:d830) |
| 2021-07-01 03:35:56 | <nshepperd> | if googlers were good they wouldn't invent bad APIs |
| 2021-07-01 03:36:00 | <dsal> | haha |
| 2021-07-01 03:36:02 | <qrpnxz> | xd |
| 2021-07-01 03:36:34 | → | curiousggay_ joins (~curiousgg@77-120-144-167.kha.volia.net) |
| 2021-07-01 03:36:34 | <qrpnxz> | haskell definitely safer, but go so much more productive for me still with it's readers and writers |
| 2021-07-01 03:36:43 | <qrpnxz> | *its |
| 2021-07-01 03:36:49 | → | cloudy`` joins (~user@2600:8807:c207:f00:d412:4cce:d9f1:ba0) |
| 2021-07-01 03:37:02 | <DigitalKiwi> | go is garbage |
| 2021-07-01 03:37:17 | <qrpnxz> | nah |
| 2021-07-01 03:37:29 | × | Feuermagier_ quits (~Feuermagi@2a02:2488:4211:3400:5def:8486:9e4:b49a) (Read error: Connection reset by peer) |
| 2021-07-01 03:37:29 | × | curiousgay quits (~curiousgg@77-120-144-167.kha.volia.net) (Read error: Connection reset by peer) |
| 2021-07-01 03:37:29 | → | the_proffesor joins (~theproffe@2601:282:847f:8010::3a29) |
| 2021-07-01 03:37:29 | → | Feuermagier_ joins (~Feuermagi@2a02:2488:4211:3400:5def:8486:9e4:b49a) |
| 2021-07-01 03:37:29 | × | justache quits (~justache@user/justache) (Quit: Ping timeout (120 seconds)) |
| 2021-07-01 03:37:29 | × | azeem quits (~azeem@dynamic-adsl-94-34-20-185.clienti.tiscali.it) (Ping timeout: 240 seconds) |
| 2021-07-01 03:37:45 | → | justache joins (~justache@user/justache) |
| 2021-07-01 03:37:50 | × | img quits (~img@user/img) (Quit: ZNC 1.8.2 - https://znc.in) |
| 2021-07-01 03:37:54 | → | zmt00 joins (~zmt00@user/zmt00) |
| 2021-07-01 03:38:03 | <dsal> | I can get so much done so much faster in Haskell. |
| 2021-07-01 03:38:32 | × | the_proffesor quits (~theproffe@2601:282:847f:8010::3a29) (Changing host) |
| 2021-07-01 03:38:32 | → | the_proffesor joins (~theproffe@user/theproffesor) |
| 2021-07-01 03:38:32 | theproffesor | is now known as Guest2594 |
| 2021-07-01 03:38:32 | the_proffesor | is now known as theproffesor |
| 2021-07-01 03:38:38 | <qrpnxz> | yeah i hope to learn to do that one day, for now gotta use another language for results |
| 2021-07-01 03:38:42 | × | cloudy` quits (~user@2600:8807:c207:f00:d022:dd81:f0f8:bb22) (Ping timeout: 240 seconds) |
| 2021-07-01 03:38:42 | × | spruit11_ quits (~quassel@2a02:a467:ccd6:1:70d9:6b8a:7264:8769) (Ping timeout: 240 seconds) |
| 2021-07-01 03:38:42 | × | zmt01 quits (~zmt00@user/zmt00) (Ping timeout: 240 seconds) |
| 2021-07-01 03:38:42 | × | Guest2594 quits (~theproffe@user/theproffesor) (Ping timeout: 240 seconds) |
| 2021-07-01 03:38:48 | <qrpnxz> | like net package too good |
| 2021-07-01 03:38:55 | <qrpnxz> | how to live without net package |
| 2021-07-01 03:39:32 | <dsal> | I just realized I've been working in go for nearly 12 years. :/ But it's still painful. |
| 2021-07-01 03:40:13 | <qrpnxz> | how are haskellers doing error handling? I barely see any, do they just use exceptions or what? |
| 2021-07-01 03:40:40 | <dsal> | errors? We don't write code with errors. :P |
| 2021-07-01 03:41:10 | <qrpnxz> | xd |
| 2021-07-01 03:41:13 | <nshepperd> | I/O code uses exceptions, generally |
| 2021-07-01 03:41:17 | <dsal> | It depends on what you mean. There's maybe/either kinds of things and there's various exceptions. |
| 2021-07-01 03:41:24 | <qrpnxz> | ig the database just never fails when you program in haskell |
All times are in UTC.