--- Log opened Tue Sep 24 00:00:33 2019 |
--- Day changed Tue Sep 24 2019 |
00:00 | <&McMartin> | Hi catalyst |
00:00 | <&McMartin> | I had something code-related to tell you but then I forgot what it was |
00:00 | <&McMartin> | The famed double-reverse esprit d'escalier |
00:03 | < catalyst> | \o/ |
00:03 | < catalyst> | well, I look forward to you remembering |
00:11 | | * McMartin sips tea, remembers |
00:11 | <&McMartin> | OH yeah |
00:11 | <&McMartin> | It was about my article about jamming all of Apple's languages together at once |
00:11 | <&McMartin> | And how, unlike your parting shot at the time |
00:11 | <&McMartin> | It turns out C is not the sensible FFI layer despite being the lowest common denominator |
00:13 | <&McMartin> | ( https://bumbershootsoft.wordpress.com/2019/09/20/iglossolalia-mixing-all-of-apples-officially-supported-compiled-languages/ is the article. I lie about C++ in it!) |
00:13 | | Kindamoody is now known as Kindamoody[zZz] |
00:14 | | * McMartin has now, in the line of duty, mixed C, Obj-C, C++, and Swift APIs not only in a single file but in a single line of code. |
00:42 | <@Reiv> | ... |
00:43 | <@Reiv> | Doesn't that turn the whole thing into some kind of horrific meta-language |
00:51 | <@Reiv> | I mean, I read the article, and even followed significant portions of it |
00:52 | <@Reiv> | I did not realise it was being "Yeah so you can just type in three languages simultaneously" |
00:59 | <&McMartin> | The short answer is "yes, yes it does, and Xcode refers to that horrific metalanguage as 'Objective-C++'" |
00:59 | <&McMartin> | Swift gets into the mix by activating its mode where it poses as Objective-C |
00:59 | <&McMartin> | But at least actual swift *source code* has to live in different files because its top-level code structure is different |
01:17 | | celmin|away is now known as celticminstrel |
01:22 | | himi [sjjf@Nightstar-1drtbs.anu.edu.au] has joined #code |
01:22 | | mode/#code [+o himi] by ChanServ |
01:22 | | Pinkhair [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
01:25 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
01:27 | | * McMartin wipes out two more source files, which requires touching 56 others |
01:27 | <&McMartin> | My PRs lately have not been kind to my teammates |
01:56 | <@Reiv> | Are they OK with this fact |
02:23 | | Pink` [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
02:26 | | Pinkhair [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
02:58 | <&McMartin> | (a) They haven't openly complained, (b) it's part of the job, (c) it's in the service of a higher-priority principle when it comes to PRs, and (d) We've all had to do this at some point. |
02:59 | <&McMartin> | (The higher principle being "when delivering work for review pre-merging, the thing being merged should not, like, break everything") |
02:59 | < catalyst> | mixing compiled languages is a great way to make yourself sad though XD |
02:59 | <&McMartin> | (So if the core change the work is -- say, deleting two files out of the program entirely -- requires altering 56 other files -- say, because they referred to stuff in those files -- then tough shit) |
03:00 | <&McMartin> | catalyst: Very true, which is sort of why Project Trogdor is ongoing. |
03:01 | < catalyst> | I feel like I want to read that article once I am less tired |
03:01 | <&McMartin> | Right now most of our product is competent Objective-C turned to Objective-C++ so that it can call into probably-too-clever-for-its-own-good C++ which is then talking to the device and OS via a layer of extremely novice Objective-C++ |
03:01 | < catalyst> | also, I have been coding again and it's amazing because I've not been able to for months omg |
03:01 | < catalyst> | pretty much all C++ is too clever for its own good |
03:01 | < catalyst> | this is C++ we're talking about |
03:01 | <&McMartin> | Now that I have multiple years of ObjC under my belt and actually know what I'm doing, I'm burning away the lower level of Objective-C++ and replacing it with a sensible pure-ObjC layer |
03:01 | < catalyst> | (: |
03:02 | <&McMartin> | And then using that to let the C++ code fall away as the lower level APIs end up being easier to use directly than the buffering APIs we'd created so that the C++ core would be pure C++. |
03:02 | <&McMartin> | The bottom two layers in that four-layer cake I described live in a .a file during the build process |
03:02 | < catalyst> | aha |
03:03 | <&McMartin> | That .a file has shrunk by... |
03:03 | | * McMartin does a quick check and consults his table |
03:03 | | * catalyst rolls 2d6 |
03:03 | <&McMartin> | You rolled a 79.4! |
03:04 | <&McMartin> | It has shrunk by 79.4 MB so far and I'm not even at the point where I've converted enough stuff to have a compact, "core" DLL that can then be shared across our various iOS services. |
03:05 | <&McMartin> | I haven't done a check on the final binary alone recently, but at last check *that* had shrunk by more like 700KB |
03:05 | <&McMartin> | This is when I start saying things like "go home, C++, you're drunk" |
03:05 | < catalyst> | turn off exceptions |
03:06 | <&McMartin> | I'm turning off more than exceptions :D |
03:06 | < catalyst> | also yes, C++ has a fascinating amount of technical debt |
03:06 | <&McMartin> | (Sadly, much of the code that's falling away *uses* exceptions. We have, however, destroyed RTTI.) |
03:06 | < catalyst> | like the linker being the way it is because it tried not to have one |
03:06 | < catalyst> | oh yeah RTTI is painful and you can recreate it selectively if you need it if you want |
03:07 | < catalyst> | (with actually useful info) |
03:07 | <&McMartin> | More to the point, ObjC has, and Swift can opt into, smalltalk semantics |
03:07 | < catalyst> | oo |
03:07 | <&McMartin> | Yeah. |
03:08 | <&McMartin> | This architecture was originally designed for Java, more or less, and it makes some uncomfortable assumptions that I was Very Clever and worked around in my C++ code. |
03:08 | <&McMartin> | Those assumptions can be made significantly less uncomfortable by migrating that stuff into a non-C++ library. |
03:08 | < catalyst> | x) |
03:08 | <&McMartin> | But I do need two or three more really good ideas to realize my Grand Vision (tm) there. |
03:08 | <&McMartin> | I haven't had them yet. I've had three or four already and exploited them! |
03:09 | < catalyst> | \o/ |
03:09 | < catalyst> | those are good times |
03:09 | <&McMartin> | I hope I'm not the only one whose dev plans include little clouds of "I'll come up with something by the time I get actually painted into this corner I'm obviously painting myself into" |
03:09 | < catalyst> | I love the ones where you have a great idea and follow through then replace it with a much leaner great idea |
03:09 | < catalyst> | you're not |
03:09 | <&McMartin> | That has been how this whole project is going |
03:09 | < catalyst> | that's basically design in a nutshell no? |
03:09 | <&McMartin> | I was the principal designer, architect, and coder for this C++ stuff |
03:09 | <&McMartin> | Several Years Ago |
03:10 | <&McMartin> | Now I'm doing a comprehensive audit and redesign and optimization, and I'm doing it live, with no disruption |
03:10 | <&McMartin> | It's honestly pretty awesome. |
03:10 | < catalyst> | I'm still kind of revelling in not needing to maintain the systems I spent a decade developing in various guises |
03:10 | < catalyst> | :) |
03:10 | <&McMartin> | Yep |
03:10 | < catalyst> | that does sound fulfilling |
03:10 | <&McMartin> | This is my first chance to really do a serious redesign and rethink on one of my designs |
03:11 | <&McMartin> | Usually architects go in, design something, and move on before the flaws in the thing they design can become apparent, leaving the mess to a confused and resentful team of newcomers. |
03:11 | <&McMartin> | (Also motivating this "evolve away the C++ stuff" is that C++ was considered a credible mobile development language back when this was first designed and in the intervening years it has become increasingly stridently not) |
03:11 | <&McMartin> | (So the code is for all practical purposes unmaintainable except by me.) |
03:12 | <&McMartin> | (And there's only one cure for that, and it's LOTS OF FIRE) |
03:12 | < catalyst> | ah yes |
03:12 | <&McMartin> | Well |
03:12 | <&McMartin> | The CTO could |
03:12 | <&McMartin> | He's kind of busy being the CTO |
03:12 | < catalyst> | I wonder if they'll ever replace the completely incomprehensible until you stare at it for a couple of weeks system that a lot of the editor depends on |
03:12 | < catalyst> | that I nearly burned myself out trying to replace |
03:15 | < catalyst> | at least I know it all worked when I left |
03:27 | | * McMartin nods |
03:28 | < catalyst> | I'm actually legit really excited to be able to show off some of the code I write to people I respect |
03:28 | < catalyst> | because I never could do that before |
03:28 | <&McMartin> | :) |
03:28 | < catalyst> | and it was weird because there's things I wrote as throwaway systems on games from eight years ago that are core parts of current architecture at that company |
03:28 | < catalyst> | and like |
03:28 | < catalyst> | that's a bit freaky |
03:29 | < catalyst> | (and kind of flattering?) |
03:29 | <&McMartin> | Yeah, that's the other bit |
03:29 | <&McMartin> | Even if I were the sort to despise and disdain my former self |
03:29 | <&McMartin> | (which I'm not) |
03:29 | <&McMartin> | A ton of this code I'm burning away was core infrastructure requiring in some cases zero maintenance for years |
03:29 | < catalyst> | :) |
03:29 | < catalyst> | that's good stuff |
03:30 | <&McMartin> | And even when I find bugs and logic errors as I rework it... |
03:30 | <&McMartin> | ... by a fairly strong body of evidence, those bugs didn't actually amtter in practice |
03:30 | < catalyst> | I've spent a good part of the past year learning how not to put myself down too, so maybe I'll even feel proud of the things I do |
03:31 | <&McMartin> | Yeah, I try to keep an attitude of Never Stop Learning because that also means that you're less likely to fall into the trap of thinking that, e.g., your code is so great it doesn't *need* testing, etc. |
03:31 | < catalyst> | like, I improved the equivalent of vector::push_back to be 45% faster in many circumstances, and implemented an entirely retooled hash map class that's used everywhere there now |
03:31 | < catalyst> | if your code is so great it doesn't need testing I think you're about to get fired |
03:31 | < catalyst> | because that sentence makes no sense |
03:32 | < catalyst> | you know code is great because it's been tested X) |
03:32 | < catalyst> | anyone who wants to be a master programmer must understand how to test code and I know you know this but I need the universe to hear it |
03:32 | | * catalyst yells incoherently |
03:33 | < catalyst> | the biggest thing I've been excited by in my framework so far was figuring out how to effectively test failing asserts |
03:33 | <&[R]> | An untested backup is not a working backup -> Untested code is not working code? |
03:33 | < catalyst> | exactly |
03:33 | < catalyst> | there are a lot of ways to test code I mean one of those is to try and use your tool |
03:33 | < catalyst> | or play your game or what have you |
03:34 | < catalyst> | but some people don't even pass the low low bar of compiling and running the program |
03:34 | < catalyst> | "it's just a small change it doesn't need a compile" |
03:34 | <&[R]> | Then they introduce a syntax error and the build doesn't compile |
03:35 | < catalyst> | which kills the overnight resource build QA and half the artists were relying on and setting the whole company back a day's work yes |
03:36 | < catalyst> | or the people who fix the playstation build without caring about whether the xbox build works any more |
03:36 | < catalyst> | etc etc |
03:48 | <@Reiv> | I should learn how to write properly testable code. |
03:48 | <@Reiv> | But I have so much else to learn in coding that it seems a bit down the way |
03:48 | <@Reiv> | Even as I am fully aware that it's going to bite me in the ass when I finally need it~ |
03:49 | | * Reiv can write a reasonably testable SQL query, but that is a different skill in itself. |
03:53 | < Mahal> | I don't actually understand how code tests work |
03:53 | < catalyst> | a lot of that learning comes from experience |
03:53 | < Mahal> | I mean, at a very high level I grok the concept |
03:54 | < catalyst> | the very simplest test of a program is trying to use it to do a task, unit testing is basically taking that concept and applying it with much more granularity, and then building your systems so they can be easily tested in those ways (if reasonable) |
03:54 | < catalyst> | I don't know if that helps any |
03:55 | < catalyst> | wait that probably is covered by the high level bit |
03:55 | < Mahal> | Yes |
03:56 | < catalyst> | I can try and describe the mechanics of the tests I tend to write |
03:56 | < catalyst> | ? |
03:57 | < Mahal> | I'm good, but thanks for the offer :) |
03:57 | < catalyst> | okay x) |
04:00 | < catalyst> | I learned a lot of what I know about how to write unit tests by reading https://www.amazon.co.uk/Test-Driven-Development-Addison-Wesley-Signature/dp/0321146530 |
04:01 | < catalyst> | and now I'm going to go attempt to sleep |
04:02 | < catalyst> | and stop oversharing things |
04:02 | | * Mahal grins |
04:02 | | catalyst [catalyst@Nightstar-5dv16h.cable.virginm.net] has quit [[NS] Quit: Leaving] |
04:02 | < Mahal> | of course, I am not a developer |
04:02 | < Mahal> | at most I write scripts |
04:02 | < Mahal> | I realise there is some slight crossover there, but ... they are not the same. |
04:08 | <@Reiv> | ditto |
04:08 | <@Reiv> | I write /really fancy/ scripts |
04:08 | <@Reiv> | But they're scripts |
04:08 | <@Reiv> | It's an astonishing day if they even involve a loop, alas |
04:38 | <&McMartin> | I tend to be a bit skeptical of TDD, because I tend to think it gets offered as a panacaea for problem domains it has to be crowbarred into |
04:38 | <&McMartin> | ... and once you do that crowbarring, more often than not 'unit testing' has been redefined as just 'testing of any kind' |
04:39 | <&McMartin> | Meanwhile, I tend to be extremely aggressive about automated end-to-end testing in a way a lot of TDD disciplines seem to ignore or actively reject |
04:39 | <@Reiv> | how do you write said tests? |
04:40 | <&McMartin> | Depends on the kind of program it is. |
04:40 | <&McMartin> | For Ophis, it is a series of carefully crafted inputs and expected outputs, along with a few preliminary things that are closer to unit tests to isolate what may be going wrong if it cannot produce any output whatsoever. |
04:41 | <&McMartin> | For the mobile application that is my employer's flagship product, well, *I* don't write the tests, as we have a dedicated engineer for this, but she has access to a library provided by Apple that permits a suitably designed application to be botted and have its UI state queried and modified |
04:42 | <&McMartin> | So it is a matter of encoding the various workflows and making sure that the correct answers come out/the application has transitioned to the correct screen and is displaying the correct data. |
04:42 | <&McMartin> | This isn't *quite* enough -- you still need human testers for some of this to confirm that, e.g., the text in that screen is actually visible and there isn't a bug in the botting/scraping libraries |
04:42 | <&McMartin> | But it's miles ahead of what was available even three years ago. |
04:43 | <&McMartin> | A web application can be botted very easily because you can create requests to the server and check the results to make sure they make sense, or pretend to be the server and respond to a client carrying out various requests to make sure that everything behaves as expected. |
04:44 | <&McMartin> | The server side of a stateless web service is one of the few cases where I concede that TDD really does have major advantages |
04:44 | <@celticminstrel> | TDD? |
04:44 | <&McMartin> | Test-Driven Development |
04:45 | <@celticminstrel> | Ah. |
04:45 | <@celticminstrel> | A lot of things just aren't testable non-interactively... especially UI stuff. |
04:46 | <&McMartin> | This is where the botting/scraping frameworks that are now part of Xcode are genuine and enormously welcome. |
04:46 | <&McMartin> | My other objection to a lot of TDD stuff is that it doesn't know in advance what's actually the hard thing |
04:47 | <&McMartin> | So someone's suggestion for certain unit tests for Ophis, for example, were ultimately testing whether or not the language's string processing functions actually did what the docs said. |
04:47 | <&McMartin> | When your function returns [x.split() for x in f.readlines()], there is really not a lot of unit testing to do, and to the extent that you can, you're actually solving the wrong problem |
04:47 | <&McMartin> | To wit, you're insisting that f be a file-like object, which is going to be really inconvenient when you start looting the code later. |
04:50 | <&McMartin> | The specific flaw I find in TDD as a discipline is that it treats design as something happens along the way to getting all your tests passing and that gets to change as needed |
04:50 | <&McMartin> | This is an awful way to design an API. |
04:51 | <&McMartin> | This is only non-laughable if the design phase is so long over that there is no reasonable prospect of it ever changing. |
04:51 | <&McMartin> | Say, because you are implementing compliance with a published standard. |
04:53 | <&McMartin> | Indeed, my big work project I've been talking about, nearly the entire problem as it affects the developers today is that the API drew the abstraction barriers at the wrong points and this introduced a continuously expanding amount of infelicity into the code that used it and the code that it depended on. |
04:54 | <&McMartin> | So as I rework parts of the core library, this ends up reaching out into the application proper and altering how it does its work, usually by eliminating a lot of boilerplate that never "should have" been necessary. |
05:25 | | VirusJTG_ [VirusJTG@Nightstar-42s.jso.104.208.IP] has joined #code |
05:27 | | celticminstrel [celticminst@Nightstar-6an2qt.dsl.bell.ca] has quit [[NS] Quit: And lo! The computer falls into a deep sleep, to awake again some other day!] |
05:28 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has quit [Ping timeout: 121 seconds] |
05:47 | | Derakon is now known as Derakon[AFK] |
06:09 | | Vornicus [Vorn@ServerAdministrator.Nightstar.Net] has joined #code |
06:09 | | mode/#code [+qo Vornicus Vornicus] by ChanServ |
06:28 | <&McMartin> | OK, late-night crisis resolved. Hooray. |
07:07 | | gnolam [lenin@Nightstar-e3tf4i.priv.bahnhof.se] has quit [[NS] Quit: Gone] |
07:47 | | himi [sjjf@Nightstar-1drtbs.anu.edu.au] has quit [Ping timeout: 121 seconds] |
09:19 | <&jerith> | The main problem I have with TDD is that it requires you to know what you're actually building. |
09:20 | <&jerith> | That can work for a lot of software (it's basically top-down design) but certainly isn't universal. |
09:20 | <&jerith> | I tend to do quite a lot of exploratory programming. |
09:21 | <&jerith> | "Let's write some code that talks to the smallest piece of this API possible and see how it works." |
09:22 | <&jerith> | Then once I have those low-level bits figured out, I generally have a better idea of how to compose them into the things I *actually* need. |
09:22 | <&jerith> | Except more than half the time I learn things in the low-level work that change the high-level stuff significantly. |
09:24 | <&jerith> | I don't bother writing tests until I'm reasonably confident that the thing I'm building will stick around in its current form long enough for the tests to be worth more than the time spent writing them. |
09:24 | <&jerith> | Sometimes that means I end up with a big ugly thing that's very difficult to test. |
09:25 | <&jerith> | If necessary, I then set that aside, use it as a model for the behaviour I actually want, and then reimplement "from scratch" in a TDDish style. |
09:27 | <&jerith> | ("from scratch" usually involves reusing a nontrivial amount of the original code, but only where I decide I can usefully pull it into the new thing I'm writing.) |
09:28 | <&jerith> | Anyway, TDD *as originally described* is an excellent model for writing the kind of software that favours a top-down approach. |
09:29 | <&jerith> | The simplified red-green-refactor cycle even captures the essence (but not the details) is a useful way. |
09:30 | <&jerith> | Except almost everyone forgets (or misunderstands) the "refactor" bit. |
09:31 | <&jerith> | That's the bit where you're supposed to look at what you have so far and redesign it into something better. |
09:35 | | gnolam [quassel@Nightstar-0oc.n80.224.185.IP] has joined #code |
09:35 | | mode/#code [+o gnolam] by ChanServ |
10:20 | | Kindamoody[zZz] is now known as Kindamoody |
10:24 | <@sshine> | I finally found out how to exit Vim! |
10:24 | <@sshine> | <C-c><C-c><Esc><Backspace>:q!<Enter> |
10:25 | <@sshine> | (this key combo works in all six modes) |
10:26 | <~Vornicus> | that is a lot of exit |
10:27 | <@sshine> | this joke comes from a very old article I can't find any more, so I went through the puzzle and recreated it. |
10:27 | <@sshine> | basically, :q! only works in normal mode. <Esc>:q! also works in insert, visual, select mode. |
10:28 | <@sshine> | Ex mode, unfortunately interprets <Esc> literally, so <Esc><Backspace>:q! negates the literal escape without breaking the exit in the previous modes. |
10:29 | <@sshine> | Command-line mode, unfortunately, will only interpret this as exiting command-line mode (closing the buffer of the last typed commands), so <C-c><C-c> closes that without breaking the exit in the previous modes. |
10:29 | <@sshine> | my co-worker who uses Vim more pointed out that I could also do <Esc><Backspace>:qa! |
10:29 | <@sshine> | since :qa closes all buffers |
10:30 | <@sshine> | but <C-c><C-c> has a nice theatrical ring. |
10:33 | <&jerith> | In emacs, <C-g><C-g><C-g> will escape from pretty much anything, then <C-x><C-c> will exit (but may ask for confirmation). |
10:34 | <&jerith> | However, if you've hit <C-q> to insert a literal control character, you might end up with a stray ^G in the buffer. |
10:34 | <@sshine> | jerith, right. and I know that sometimes triple-<C-g> won't. I'm not sure if there's a reliable way to know when that is. |
10:34 | <@sshine> | yeah :) I'm pretty sure Vim can be in states where this command doesn't work. it just helps that they named six modes. |
10:35 | <&jerith> | I haven't yet run into any situation that triple-C-g won't escape. Usually just one C-g is sufficient. |
10:35 | <@sshine> | hmm, maybe I remember wrong. |
10:36 | <&jerith> | I'm not saying they don't exist. Just that they're not common. |
10:36 | <@sshine> | maybe I should add <C-q> as a state in Vim as well. |
10:37 | <&jerith> | I'm pretty sure that after hitting C-q in emacs there's no way out that doesn't modify the buffer. |
10:37 | <&jerith> | (That's pretty much the entire point of C-q.) |
10:37 | <@sshine> | <C-v> is Vim's verbatim character mode. |
10:38 | <&jerith> | :q! will discard the modified buffer, though. |
10:42 | <@sshine> | yes |
10:43 | <@sshine> | but when you're in insert mode and hit ^V, <Esc><Backspace>:qa!<Enter> won't work because the <Esc> gets caught. but <C-c><C-c><Esc><Backspace>:q!<Enter> will work because the <C-c>s are otherwise redundant in this mode. |
11:20 | | gnolam [quassel@Nightstar-0oc.n80.224.185.IP] has quit [[NS] Quit: Gone] |
11:44 | | catalyst [catalyst@Nightstar-5dv16h.cable.virginm.net] has joined #code |
11:50 | <@sshine> | Sebbe, jeg sidder og brokker mig til LeoNerd på #perl over List::MoreUtils' mærkelige semantik og spørger ham, om det er normalt at Perl-virksomheder bare ruller deres egen ListUtils-biblioteker. Så siger han, at det gør de nok ikke, og at han bare bruger List::Util og List::UtilsBy (som jo er de eneste to udvidede listebiblioteker, der er mere populære end List::MoreUtils), men at han nok er biased for |
11:50 | <@sshine> | di han selv har skrevet dem. :P |
12:00 | <@ErikMesoy> | Jasågitt |
12:01 | <@sshine> | whoops. |
12:01 | <@sshine> | wrong channel :õ |
12:02 | <@sshine> | TL;DR: 'List::MoreUtils::part { $_->is_fallback } ()' fails for me because 'undef' can't be called with the method 'is_fallback'. You know, the 'undef' element that hides in all empty lists. |
12:05 | <@ErikMesoy> | Jeg visste ikke at man sier 'biased' på dansk. |
12:06 | <@sshine> | det er en anglicisme |
12:06 | <@sshine> | 'forudindtaget' would be the correct danish term I think. |
12:07 | <@sshine> | hvad siger man på norsk? |
12:10 | <@ErikMesoy> | Hmm. 'forutinntaget' ville man kanskje finne i en gammel støvete ordbok her, mer vanlig er nok fordomsfull, forhåndsdom, eller å omskrive: 'han sier nok det [bare] fordi han selv har skrevet dem' |
12:11 | <@sshine> | you're right, 'forudindtaget' is kind of archaic in Danish as well. I just like archaic words. :) |
12:11 | <@ErikMesoy> | Nice. |
12:12 | <@sshine> | when I look up 'forudindtaget' in a da-en dictionary, it gives me 'biased' and 'prejudiced', and I think 'fordomsfull' is more like 'prejudiced'. |
12:12 | <@sshine> | that's why I keep the other word around. |
12:13 | <@sshine> | I guess you can be biased without being prejudiced. |
12:13 | <@sshine> | for example, you can be unaware of your bias. |
12:14 | <@sshine> | prejudiced is more negative than biased: biased is a positive preference one thing, prejudiced is a negative preference against another. |
12:15 | <@sshine> | I guess when a dictionary suggests both, it's because they're not really synonyms, but they're closely enough related that you may want to know that both exist. |
12:15 | <@sshine> | also, Perl sucks. |
12:32 | <@ErikMesoy> | We might also say 'partisk' (partisan, partial). |
12:34 | <@sshine> | that's a good word. |
12:34 | <@sshine> | really, norwegian *is* danish, but spelled as it's said. |
12:35 | | * TheWatcher readsup |
12:35 | <@TheWatcher> | jerith: there is one situation I've found where C-q fails, but it's not really emacs' fault |
12:37 | <@TheWatcher> | If you're using ECB in emacs 26.x, and try using tab complete while typing a M-x command, you'll end up with the minibuffer set to an unresponsive, unclosable, unquittable completion selection buffer |
12:38 | <&jerith> | Good thing I don't use ECB! |
12:38 | <@TheWatcher> | Only option is to deactivate ECB through the menu (because M-x ecb-deactivate doesn't work!) |
12:39 | <@TheWatcher> | Then you can kill the completion buffer |
12:39 | <&jerith> | (I tried it once a very long time ago. It added several seconds of latency to many operations I perform regularly.) |
12:43 | <@sshine> | TheWatcher, what's ECB? |
12:43 | <&jerith> | Emacs Code Browser. |
12:43 | <&jerith> | IIRC it adds a bunch of "IDE" features to emacs. |
12:43 | <@sshine> | ah. |
12:43 | <@sshine> | I use the 'fzf' plugin for Emacs. |
12:44 | <@sshine> | so C-f will let me open files by fuzzy matching. https://github.com/junegunn/fzf |
12:47 | <&jerith> | I use ido for more convenient filtering within a dir, but otherwise I prefer to navigate the project structure myself. |
12:48 | <&jerith> | Then again, I'm generally using languages that don't encourage deep nesting and do encourage import mechanisms that map to filesystems. |
12:49 | <@sshine> | I also use ido. but the codebase at work is just so immensely huge. |
12:49 | <&jerith> | These days lsp-mode supports "find definition" for the languages I use it with, which is nice. |
12:49 | <@sshine> | ah, nice. |
12:49 | <@sshine> | I just started experimenting with LSP in VSCode. |
12:50 | <@sshine> | in particular, ghcide (Haskell IDE that uses LSP). |
12:50 | <&jerith> | (I currently use it for Rust and Go (when I have to touch the latter), both of which are sufficiently static that it works reliably.) |
13:02 | <@TheWatcher> | The main thing I use ECB for is the file browser and function list sideboxes - https://i.imgur.com/oXsIezL.png |
13:03 | <@sshine> | I might eventually like a Ctrl+Space smart suggestion thingy for non-Java/C# languages, but I do fine without for now. |
13:04 | <@sshine> | I suppose that's comparable to the function list side box. |
13:18 | | celticminstrel [celticminst@Nightstar-6an2qt.dsl.bell.ca] has joined #code |
13:18 | | mode/#code [+o celticminstrel] by ChanServ |
13:25 | | Kindamoody is now known as Kindamoody|afk |
13:52 | | * catalyst mutters something about not being able to override functions in the std namespace |
13:58 | | celticminstrel is now known as celmin|away |
13:59 | <@celmin|away> | I guess the only way would be to make your own standard library. >_> |
13:59 | <@celmin|away> | (Obviously not recommending that.) |
14:01 | < catalyst> | I'm selectively doing that ;) |
14:02 | < catalyst> | my usual MO is to use the standard library functionality until it doesn't match my purpose then extend |
14:05 | <@sshine> | for Perl's extended list libraries, I am *very* tempted to make my own. |
14:05 | <@sshine> | List::Util, List::UtilsBy, List::MoreUtils don't agree about much and some have insane defaults. |
14:05 | < catalyst> | which is how I end up with things line https://github.com/jtempest/pyromancy/blob/master/src/core/include/pyro/core/core_math.hpp |
14:07 | < catalyst> | like* |
14:07 | | * sshine imagines the word 'fabsf' coming up in conversations. |
14:08 | < catalyst> | specifically I'm going to have an overload for float magnitude(vector3d const& value); or similar at some point |
14:08 | <@sshine> | reminds me of https://mr.gy/ansi-common-lisp/car_003b-cdr_003b-caar_003b-cadr_003b-cdar_003b-cddr_003b-caaar_003b-caadr_003b-cadar_003b-caddr_003b-cdaar_003b-cd_002b.html#cdr |
14:08 | < catalyst> | oh geez yeah |
14:08 | < catalyst> | mm, explicit tree traversal |
14:08 | < catalyst> | there's a code smell if I ever saw one |
14:08 | < catalyst> | LISP isn't all it's hyped to be, but it is pretty good |
14:09 | <@sshine> | like, can we agree on a standard length in milliseconds of prolonging the vowel so we know how many a's there were? |
14:09 | < catalyst> | XD |
14:09 | < catalyst> | how about naming your branches and having a concise syntax for accessing them |
14:09 | < catalyst> | to give it structure |
14:09 | < catalyst> | perhaps we can call it 'struct' for short |
14:10 | <@sshine> | yeah, the upside of not having absorbed Lisp fully is that I don't turn every single program into a DSL. and the downside is that I generally don't do much macro programming. I have TemplateHaskell on my TODO for one project, though. :) |
14:10 | < catalyst> | I have a tendency to go deep into template mania before realising all I need is a few overloaded functions |
14:11 | < catalyst> | my overriding feeling after using a couple different Lisps is 'there's something deeper I can find here' |
14:12 | <@sshine> | my feeling is that the kind of template programming I want to do should be type-safe. so Nim or TemplateHaskell. (I don't do C++.) |
14:12 | < catalyst> | (I also find that C++ standard library definitions are frustratingly underspecified mathematically, but I am a bit strict) |
14:12 | <~Vornicus> | is "deep template mania" your new musical genre |
14:12 | <&jeroud> | I'm quite enjoying my time implementing scheme. |
14:12 | < catalyst> | plausibly |
14:12 | < catalyst> | oh that sounds fun :D |
14:12 | < catalyst> | C++ isn't what I would call typesafe |
14:12 | <@sshine> | right |
14:13 | < catalyst> | its templates also think way too highly of themselves |
14:13 | <@sshine> | you might end up with templates generating stuff that won't compile, right? |
14:13 | <@sshine> | I guess TemplateHaskell will do that, too. but I sense that you can better control the error messages. |
14:13 | < catalyst> | more that any language which conflates 'single printable glyph' with 'smallest arithmetic type on the machine' has a dodgy basis |
14:14 | <@sshine> | hehe |
14:14 | < catalyst> | that magnitude function has the added benefit that if you do happen to call it on char, that it will compile-time error |
14:14 | <&jeroud> | I'm doing it partly as an exercise in writing something nontrivial in Rust and partly because I want to finally wrap my head around some lower-level stuff that I've never really had to think about much. |
14:14 | <@sshine> | can you get that error in an IDE? |
14:14 | <@sshine> | or do you need the template preprocessing before the error emanates? |
14:15 | < catalyst> | the static_assert fails so if you have a decent IDE it'll squiggly line it |
14:15 | <@sshine> | ok, cool |
14:15 | < catalyst> | drat, VS1029 doesn't |
14:16 | < catalyst> | hm, I wonder if I should just not define it |
14:16 | <@sshine> | is that Visual Studio? |
14:16 | < catalyst> | yeah |
14:16 | < catalyst> | I'm using community 2019 since I'm used to it as an environment, I mostly dev for windows currently, and it's free for individual use |
14:16 | <@sshine> | in Haskell the overloading equivalence would be type classes, so you'd get a compiler warning without a preprocessing pass. |
14:17 | <@sshine> | yes, it's a very fine editor. |
14:17 | <@sshine> | I came to miss VS after my old C# job. |
14:18 | <&jeroud> | I want a fine editor. :-( |
14:18 | < catalyst> | assert(pyro::magnitude('c') == 'c'); |
14:18 | < catalyst> | gives |
14:18 | < catalyst> | <...>pyro\core\core_math.hpp(15): error C2338: pyro::magnitude has not been implemented for this type. |
14:18 | < catalyst> | <...>core_math_tests.cpp(26): note: see reference to function template instantiation 'T pyro::magnitude<char>(T &&)' being compiled |
14:18 | < catalyst> | with |
14:18 | < catalyst> | [ |
14:18 | < catalyst> | T=char |
14:18 | < catalyst> | ] |
14:18 | < catalyst> | though you do need to attempt to compile it |
14:19 | < catalyst> | which is a shame |
14:19 | < catalyst> | even if you leave the template version unimplemented it still doesn't figure it out |
14:22 | <@sshine> | maybe C++ people have a way to provide IDE hints without compiling templates? |
14:22 | < catalyst> | if it was constexpr it'd probably do better |
14:22 | < catalyst> | hm |
14:23 | < catalyst> | that has the potential to be misleading from an implementer pov though |
14:23 | < catalyst> | since floating point can't be done at compile time |
14:23 | < catalyst> | (and the underlying integer functions aren't constexpr I think) |
14:23 | <@sshine> | as long as the source code compiles progressively, it should be ok, right? in haskell, if I do 'stack build --file-watch', I just do a recompile on only touched files on every save. |
14:24 | < catalyst> | oh I could do that I suppose, I compulsively compile after each change anyhow |
14:24 | < catalyst> | the problem with C++ is that it is horrendously and irretrivably slow to compile |
14:24 | <@sshine> | ok. it's just a workflow thing. I'm trying to learn some new workflows. having an IDE engine that does this behind the scenes is my current experiment. |
14:24 | < catalyst> | so if you make a change to a widely used header file you might be there all day |
14:24 | < catalyst> | I'd like one |
14:24 | < catalyst> | but C++ really sucks for it :) |
14:25 | <@sshine> | I guess the compilation of some C++ templates can be very time-consuming, too? |
14:25 | < catalyst> | I did setup a "compile and run all my unit tests" shortcut though |
14:25 | < catalyst> | the inclusion model, templates and linking templates can be slow aye |
14:25 | < catalyst> | especially when you have templates on templates like in the standard library |
14:26 | <@sshine> | ugh, yeah, okay. and this cascades to any use of these templates on templates in your code, right? |
14:26 | < catalyst> | yeah |
14:26 | < catalyst> | I try to write my own templated code to be very clean in terms of what depends on what template-wise |
14:26 | < catalyst> | but since I also rely on standard library type traits and such there's only so far I can go |
14:26 | <@sshine> | I have a vague sense that there's a balance in the Haskell ecosystem between using fancy features in your programs and using as few fancy features in reliable libraries. |
14:27 | < catalyst> | (you really don't want to implement those yourself, you cannot compete with the compiler's own intrinsic functions and you'll spend a long time with edge cases) |
14:27 | < catalyst> | I learn how to do fancy things in C++ so I can avoid them at all costs except when strictly necessary |
14:27 | <@sshine> | haha |
14:27 | <@sshine> | good point |
14:27 | < catalyst> | I think people who overload standard operators that look like what they want are mad |
14:27 | <&[R]> | cout << |
14:27 | <@sshine> | yes, + should be some kind of numeric addition. otherwise the world is bonkers! |
14:28 | < catalyst> | [R] EXACTLY |
14:28 | <@sshine> | << is shift-left normally? |
14:28 | < catalyst> | yeah |
14:28 | < catalyst> | it's also the 'stream out operator' or something to that effect |
14:28 | <@sshine> | also, it's an arrow looking thingy |
14:28 | <&[R]> | No, << is the output stream operator |
14:28 | <&[R]> | Obviously |
14:28 | <@sshine> | also, jesus died on the + |
14:28 | <&[R]> | I don't mind + for string concat |
14:28 | < catalyst> | iostreams is considered almost universally an abomination by the C++ standard but there hasn't really been much movement to replace it |
14:29 | <&[R]> | It's not like other languages don't do that |
14:29 | < catalyst> | though there's a promising format library in the C++20 draft right now |
14:29 | < catalyst> | I don't like + for string concat really |
14:29 | < catalyst> | I prefer if there's an .. operator or similar |
14:29 | <&[R]> | I'd rather + for string concat, than use sstream or a ton of nested/sequential/chained function calls. |
14:30 | <&[R]> | Or if there were an actual dedicated operator, yeah |
14:30 | < catalyst> | this vector book wants to overload operator^ as a mathematical function and then goes 'but the precedence doesn't work so you have to do this' at which point I just sighed |
14:30 | <@sshine> | Haskell has the <> operator for arbitrary semigroup composition. this has the added benefit that if you think your data type should be "added/multiplied/concatenated" in some special way, you have to be aware that it's a semigroup, and if your type has a neutral element, you have to extend it with the monoid type class. |
14:31 | < catalyst> | if I understood those terms I'm sure I'd be nodding in agreement |
14:31 | <@sshine> | basically: you say that type Foo can be +'ed? but is there a "0"? you have to think about these things when defining the overload. |
14:32 | <&[R]> | ; echo (1 2 3)^(a b c) |
14:32 | <&[R]> | 1a 1b 1c 2a 2b 2c 3a 3b 3c |
14:32 | <&[R]> | ^ something like that? |
14:34 | | * sshine pretends to know what correct API design looks like by looking at those Haskell packages that are currently stable. e.g. Vector has all the numbery operators, but they don't overload, because vectors are only sort of numbers. Data.Text has all the Data.String operators, but they're not overloaded, because the implementation varies *drastically* (e.g. Data.Text allowing loop fusion optimizations) |
14:34 | < catalyst> | ^ is xor |
14:34 | < catalyst> | bitwise xor |
14:34 | <&[R]> | In xs it's the "concatination" operator |
14:35 | <&[R]> | Which does the above |
14:35 | < catalyst> | ; help |
14:35 | <&[R]> | :p |
14:35 | < catalyst> | x) |
14:35 | < catalyst> | what's xs? |
14:35 | <@sshine> | catalyst, oh, that's bad. sure, exponentiation is probably more common in high-level languages than xor, but you can't just go and redefine something well-known, right?! |
14:35 | <&jeroud> | Is "arbitrary semigroup composition" the preferred way to write "deep template mania" tracks? |
14:36 | <@sshine> | jeroud, it's a sub-genre that mixes in triphop. |
14:36 | < catalyst> | boost spirit is usually my go-to on this school of antipattern, because it overrides various operators to provide a faux parsing grammar language |
14:36 | <&[R]> | catalyst: https://github.com/TieDyedDevil/XS |
14:36 | < catalyst> | oh, huh |
14:37 | <&[R]> | sshine: Your mention of the <> operator working on "semigroups", does that do something similar to the concatination operator I demo'd above? |
14:37 | <@sshine> | catalyst, I... I think that's probably something I'd condone! I mean a clearly fenced off embedded DSL for one particular purpose. as long as you keep it in a separate file. |
14:38 | < catalyst> | I just don't think C++ is equipped to handle it really |
14:38 | <@sshine> | [R], yeah, I guess you could call the Semigroup type class Appendable. it exactly exposes (<>) :: a -> a -> a |
14:39 | <@sshine> | [R], and then if there's a "zero" element, it's a Monoid instead. |
14:39 | <&[R]> | That became opaque after "yeah" |
14:40 | <@sshine> | [R], it's like Functor could be called Mappable because they're things that can be mapped over with some function. |
14:40 | <@sshine> | [R], Semigroup could be called Appendable or Concatenable because they're things that can be stuck together. |
14:41 | <@sshine> | the names are mathy but the things are often very relatable. |
14:44 | <@sshine> | there was some blog post by a Matt Parsons who said that it may seem like a bad thing that the names are mathy, but at least it lessens ambiguity, since there are fewer things that make sense to call Functor (but still an abundance) of things one call Functors (in SML it's a parameterized module, in Prolog it's a parameterized predicate, and in math, sigh...) than Mappable (Google Maps, etc.) |
14:45 | <@sshine> | or things that can be turned in to a HashMap |
14:45 | <@sshine> | or things that can be turned into a treasure map |
14:46 | <@sshine> | catalyst, I think that as long as you get the red squiggly lines without waiting a long time, it's kinda nice. |
14:46 | < catalyst> | it amuses me that C++ has no std::hash_map because so many people used that name for user types, so it's std::unordered_map instead |
14:46 | <@sshine> | std::unordered_map is a nicer name anyways :) |
14:46 | < catalyst> | (it's less amusing that that type is still horrendously slow because it enforces a particular implementation via its API) |
14:47 | <@sshine> | oh |
14:47 | < catalyst> | it has an explicit API for getting the buckets and an implicit API that the nodes it stores don't move in memory |
14:47 | < catalyst> | it really sucks |
14:47 | < catalyst> | unordered_map is a nice descriptive name aye |
14:47 | < catalyst> | I'm not displeased by it |
14:47 | <@sshine> | can you get an efficient ordered map without using balanced trees? |
14:47 | <@sshine> | (not in C++ necessarily, just thinking data structures.) |
14:48 | < catalyst> | I don't know |
14:48 | < catalyst> | I'd imagine not |
14:49 | <@sshine> | seems like there's a tradeoff. https://stackoverflow.com/questions/48260019/create-hash-map-with-parameters-ordered-in-the-way-inserted |
14:49 | <&[R]> | <sshine> can you get an efficient ordered map without using balanced trees? <-- yes. So long as you know what's going in there ahead of time, and never add anything afterwards |
14:50 | <@sshine> | [R], good point :) |
14:52 | <@sshine> | Perl had something that looked like efficient, ordered maps for a long time. |
14:53 | <&jerith> | pypy has an ordered map implementation as default for its dicts because it's faster than the unordered one. |
14:53 | <@sshine> | it kept very small hashmaps as lists of pairs internally. so as long as you didn't grow it beyond this linear representation's capacity, it'd have order. |
14:54 | <@sshine> | people started depending on this behavior, and it eventually popped up as a heisenbug when some arbitrary internal limit was reached. |
14:54 | <@sshine> | so what the Perl maintainers did was shuffle *all* key iterators to punish people making this assumption. |
14:54 | <&[R]> | lol |
14:55 | <&[R]> | I wonder how perl's documentation played into that. When I looked into perl I wasn't a big fan of their docs |
14:55 | <@sshine> | I'm not a big fan of Perl for anything beyond quick and dirty scripts. |
14:55 | <@sshine> | like Python and Ruby, it's amazing how much you can cram into a one-liner. |
14:56 | <&[R]> | Slashdot's entire website was written in perl at one point |
14:56 | <@sshine> | my job's website is 700k lines of Perl. >_< |
14:57 | <&jerith> | https://morepypy.blogspot.com/2015/01/faster-more-memory-efficient-and-more.html |
14:58 | <@sshine> | I like that dictionaries can be "more ordered". :-D |
14:59 | <&jerith> | [1 2 4 3 5] is more ordered than [1 4 3 2 5]. |
14:59 | <&[R]> | I think it's that the dictionaries were less ordered than before |
14:59 | <&jerith> | A pizza that is in the hands of a delivery person is more ordered than a pizza you're thinking about getting for supper. |
14:59 | <&[R]> | Or there were less of the ordered dictionaries |
15:00 | <&jerith> | fijal writes Polish-flavoured English. |
15:00 | <&jerith> | And arigo writes Swiss-flavoured English. |
15:02 | <&jerith> | Put those together and "more ordered" is just as reasonable as "a little bit everywhere". |
15:02 | <@sshine> | jerith, but this abuses the overloaded meaning of 'ordered'. I'd rather like to say that the state of a pizza being delivered is also *greater* under one total ordering, than say that if, somehow, a pizza being delivered could go from "currently baking" to "on its way" and back to "currently baking", this was "less ordered". it wouldn't be ordered at all! |
15:02 | <@sshine> | and I did experience that ordering a burger on Jan 1st some years ago. >_< |
15:04 | <@sshine> | so I assumed by "more ordered" they meant that, like Perl's fruity hashmaps, they were ordered under some suspect conditions, but not really under any reliable contract. |
15:05 | | * sshine has a very binary world view. :P |
15:05 | <&jerith> | Anyway, the thing that makes pypy's new dict implementation faster is that it's more memory-efficient and thus fits into caches better and causes less gc work. |
15:06 | <@sshine> | jerith, oh! okay. reading the SO post earlier I thought that the strategy that pypy also seems to use was to get O(1) deletions, at the cost of memory usage. are you saying that its memory efficiency comes at cache-level optimizations? I mean, they do use an extra array somewhere, right? |
15:09 | <&jerith> | Instead of having a sparse array full of big things, they have a sparse array full of small things and a dense array full of big things. |
15:09 | <&jerith> | Where "big" is a pointer and "small" is anything from a byte upwards. |
15:11 | <&jerith> | This is a big win when most dicts have <256 entries. |
15:13 | <@sshine> | this is the kind of standard-library data-structure optimization that I really like. |
15:21 | <&jerith> | Especially in Python, where dicts are used everywhere in the implementation. |
16:32 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
16:34 | | Pink` [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
16:54 | | Derakon[AFK] [Derakon@Nightstar-f1lpvo.ca.comcast.net] has quit [Connection closed] |
16:55 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has joined #code |
17:20 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
17:22 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
17:35 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
17:40 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
18:21 | <&[R]> | <betula> see in c++, when I create uninitialised variables outside main they are default initiailised, but inside main they are not initialised.. what's this "thing" called? |
18:21 | <&[R]> | ^ curious about this myself |
18:21 | <&[R]> | IIRC it's actually a feature of where the variables get stored in the binary |
18:22 | | Pinkhair [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
18:23 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
18:26 | | Pinkhair [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
18:27 | <&ToxicFrog> | [R]: at least on linux ELF (not sure about other platforms/executable formats), uninitialized globals are stored in .bss, which is allocated and cleared by the kernel during program loading |
18:28 | <&[R]> | Yeah, I was aware of that, just not the specific sections of the ELF file |
18:28 | <&ToxicFrog> | Uninitialized locals go on the stack, which is not cleared or otherwise initialized when the frame is allocated |
18:28 | <&ToxicFrog> | That includes locals in main |
18:29 | <&ToxicFrog> | C++ has additional rules around this, e.g. "unintialized" locals of class type will have their constructors properly called and whatnot |
18:29 | <&ToxicFrog> | But I'm pretty sure uninitialized primitives and pointers still have the old behaviour: you get whatever random garbage is in that part of the stack frame. |
18:30 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
18:30 | <&ToxicFrog> | (also the C++ behaviour around initialization of locals of class type changed in C++11, looks like, so behaviour may also depend on what compiler version you're using; catalyst can speak with considerably more expertise here than I have) |
18:31 | | Vorntastic [uid293981@Nightstar-6br85t.irccloud.com] has joined #code |
18:31 | | mode/#code [+qo Vorntastic Vorntastic] by ChanServ |
18:35 | | Pinkhair [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
18:37 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
18:55 | < catalyst> | the safest thing to assume in C++ is that any variable of fundamental type (ie not a class/struct) is uninitialized unless you explicitly set it |
19:37 | | Alek [Alek@Nightstar-o723m2.cicril.sbcglobal.net] has quit [[NS] Quit: ] |
19:38 | | Alek [Alek@Nightstar-o723m2.cicril.sbcglobal.net] has joined #code |
19:38 | | mode/#code [+o Alek] by ChanServ |
20:54 | | gnolam [quassel@Nightstar-csto10.cust.bahnhof.se] has joined #code |
20:54 | | mode/#code [+o gnolam] by ChanServ |
21:10 | | Kindamoody|afk is now known as Kindamoody |
21:12 | <@sshine> | do you get a static warning that a variable is being referred to without being initialized? |
21:12 | <@sshine> | or is that one of the footguns? |
21:16 | <~Vornicus> | thinking it's hard to detect |
21:17 | <~Vornicus> | constructor can leave a thing uninitialized with the intention that a particular method will initialize it but then you need to make sure that that method gets called before anything else |
21:20 | <~Vornicus> | --actually a thing that can technically happen in Vornonoi if you called the private functions - I don't create a mesh until you start adding points. |
--- Log closed Tue Sep 24 21:44:31 2019 |
--- Log opened Tue Sep 24 21:44:48 2019 |
21:44 | | TheWatcher [chris@GlobalOperator.Nightstar.Net] has joined #code |
21:44 | | Irssi: #code: Total of 34 nicks [25 ops, 0 halfops, 0 voices, 9 normal] |
21:44 | | mode/#code [+o TheWatcher] by ChanServ |
21:44 | | Irssi: Join to #code was synced in 15 secs |
21:49 | < Yossarian> | https://www.youtube.com/watch?v=TguVKVwqrwU - Thin Lizzy - Dancing In The Moonlight - The Peel Sessions (1977) |
22:05 | <&McMartin> | Oh goodness, backscroll, and it looks important |
22:06 | | gnolam [quassel@Nightstar-csto10.cust.bahnhof.se] has quit [[NS] Quit: Z?] |
22:07 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
22:09 | | Pinkhair [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
22:17 | | * McMartin finishes |
22:17 | <&McMartin> | It is definitely *possible* in ALGOLoid languages, of which C and its lineage are part, to detect use-before-def statically. |
22:18 | <&McMartin> | There are pathological cases, but there always are, and every single program analysis problem is fundamentally undecidable |
22:18 | <&McMartin> | Becuase you might have a program that, say, calls a function and then does the thing you'd want to detect, and now you have to know if that function halts. |
22:18 | <&McMartin> | Presto! |
22:19 | <&McMartin> | So what you do is essentially cheap type inference, backwards, with a type of "got a value", with "didn't get a value" being a "supertype" |
22:19 | <&McMartin> | Run that through the branches, merging at the ends of them, etc, and if you don't have the "have a value" type when accessed, warn |
22:19 | <&McMartin> | Or, if you are Java or Swift, straight-up error out. |
22:19 | <&McMartin> | Java calls this property "definite assignment", which is probably more accurate than use-before-def |
22:20 | <&McMartin> | This is also fun because you know how I mentioned "it's like cheap type inference, backwards"? |
22:20 | | Pinkhair [user1@Nightstar-g7hdo5.dyn.optonline.net] has joined #code |
22:20 | <&McMartin> | The two techniques were developed independently, use the same fundamental mathematical concept (semilattices), and picked opposite directions |
22:20 | <&McMartin> | So in one you start at Top and use join operations, and in the other you start at bottom and use meet operations. |
22:21 | <&McMartin> | Or you swap join and meet because I forget which is which and in a semilattice only one has meaning~ |
22:21 | <&McMartin> | Anyway. |
22:21 | <&McMartin> | Flow-sensitive dataflow analysis will generally be done by any good C/C++-ish compiler as long as at you set at least -O1 |
22:21 | | Pink [user1@Nightstar-g7hdo5.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
22:21 | <&McMartin> | Since the optimizations you do at the lowest nonzero optimization level need to do dataflow analyses anyway, it only pays the cost for those warning if it would do them anyway |
22:22 | <&McMartin> | That *does* mean that if your debug code is -O0, which it probably is, you won't get a complete warning set even with -Wall. |
22:22 | <&McMartin> | ... look at me, getting to lecture IRC on an advanced topic I actually formally studied <3 |
22:24 | | Emmy [Emmy@Nightstar-9p7hb1.direct-adsl.nl] has quit [Ping timeout: 121 seconds] |
22:43 | | VirusJTG_ [VirusJTG@Nightstar-42s.jso.104.208.IP] has quit [[NS] Quit: Leaving] |
22:43 | | VirusJTG [VirusJTG@Nightstar-42s.jso.104.208.IP] has joined #code |
22:44 | | mode/#code [+ao VirusJTG VirusJTG] by ChanServ |
23:00 | | Vorntastic [uid293981@Nightstar-6br85t.irccloud.com] has quit [[NS] Quit: Connection closed for inactivity] |
23:05 | < catalyst> | most decent C++ compilers can determine that you're using an uninitialised variable |
23:05 | < catalyst> | sometimes they're a bit too strict and you genuinely want that |
23:05 | < catalyst> | though if that's the case you should know how to turn it off |
23:05 | < Yossarian> | hmmm |
23:08 | | Kindamoody is now known as Kindamoody[zZz] |
23:24 | <&McMartin> | The case that a flow-sensitive analysis will miss is one where both the definition and the use don't run in every possible path |
23:24 | <&McMartin> | So, like |
23:25 | <&McMartin> | { int i; if (x) { i = 3; } /* Don't change x, don't assign i */ if (x) { return i; } return 0; } |
23:25 | <&McMartin> | "return i" will be falsely flagged as use-before-def |
23:26 | <&McMartin> | But then, in the general case, proving that x wasn't changed is the halting problem, and even the approximations can use beyond-astronomical numbers of facts. |
23:26 | <&McMartin> | (Seriously, pointer alias analysis is insane, and it's even worse in C-like languages) |
23:27 | <&McMartin> | (There's a seminal paper from the turn of the century named something like "Pointer analysis: Why haven't we solved this yet?") |
23:27 | < catalyst> | heh x) |
23:27 | <&McMartin> | I'm going to say John Whaley solved it in 2004 or so and in solving it proved why you don't want to, but (a) that's unhelpful and (b) I have a bias since he was in my research group =P |
23:27 | < catalyst> | partly because the languages were designed for very memory starved environments and haven't adapted to the fact that we have so much memory that there's several tiers of it before you even get out of RAM |
23:28 | <&McMartin> | Yeah, but also because your points-to representation has to take into account every invocation of every function independently, and that gets out of hand fast. |
23:28 | < catalyst> | honestly C-like languages' focus on modifying variables in place is really awful except it's not when you need it not to be |
23:28 | <&McMartin> | Whaley's approach was to use binary decision diagrams to compress the representation which worked *sometimes* and otherwise would just fall apart |
23:29 | < catalyst> | tl;dr use value based languages and functional programming etc etc |
23:29 | < Yossarian> | memory starved? hmm |
23:29 | < catalyst> | hm? |
23:29 | < catalyst> | you disagree? x) |
23:29 | <&McMartin> | But the size of the sets represented hadd, like, a quattuordecillion elements. |
23:29 | <&McMartin> | And that was on medium-sized Java programs. |
23:29 | <&McMartin> | speaking of value-based |
23:30 | <&McMartin> | I am somewhat convinced that many of my C++ woes are due to me writing it in a value-based style, and that switching to immutable reference types with uniform access rules is making my life much, much easier. |
23:31 | <&McMartin> | (Also, I suspect that C++'s insane use of headers is worse than in other languages that require headers, like C and Pascal, and I suspect this is because all C and Pascal really need to do with headers is fill in dictionaries) |
23:32 | < Yossarian> | elaborate a little more plz |
23:33 | <&McMartin> | I made two assertions; which one do you want expanded? |
23:33 | < Yossarian> | 15:26:28 <&McMartin> (Also, I suspect that C++'s insane use of headers is worse than in other languages that require headers, like C and Pascal, and I suspect this is because all C and Pascal really need to do with headers is fill in dictionaries) |
23:33 | <&McMartin> | OK. |
23:34 | <&McMartin> | C and Pascal headers generally define datatypes, symbols, and macros |
23:34 | < Yossarian> | So g++ doesn't use dictionaries when using headers or is more likely to use... ? |
23:34 | <&McMartin> | So processing one of those headers is just populating your symbol tables. |
23:34 | <&McMartin> | C++ headers tend to define complicated template relationships and the definitions of the relevant templated functions |
23:35 | <&McMartin> | So that means using those means more things to compile, plus you're going through like ten levels of template expansion to actually get to the material that must be compiled. |
23:35 | <&McMartin> | Also, C++ library development is absurdly include-happy |
23:35 | <&McMartin> | My project at work relies on a single include from the boost libraries, directly: <boost/optional.hpp>. |
23:35 | < catalyst> | and the accompanying linker that needs to prune all of the duplicates |
23:35 | <&McMartin> | This pulls in an entire megabyte of header text over just under 150 files |
23:36 | | * catalyst shudders |
23:36 | <&McMartin> | This is something that is theoretically possible in C but it is not really something you see done. |
23:36 | < catalyst> | boost is horrible for that |
23:36 | <&McMartin> | Certainly not in stuff that is on standards-track for inclusion in the core libraries. |
23:36 | <&McMartin> | But that also means the core libraries are similarly awful. >_< |
23:36 | < Yossarian> | oh so, C++ definitions in headers can describe more complicated relationships between -- |
23:37 | <~Vornicus> | in C++ you often have to include entire classes in headers |
23:37 | <&McMartin> | (boost::optional became std::optional in C++17, but support for C++17's standard library lags behind support for its language features.) |
23:37 | <&McMartin> | more complicated relationships between types, including expression-parsing-and-evaluation for what are essentially functions executed in the type space at compile time. |
23:38 | <~Vornicus> | iirc anything that's templated, you need to put the whole thing in headers because it can't compile it without knowing what the template types resolve to |
23:38 | < catalyst> | pretty much |
23:39 | < catalyst> | I'm fairly sure this is a consequence of being single pass |
23:40 | <&McMartin> | I think without that you wouldn't be able to arrange separate compilation |
23:40 | | * McMartin nods at catalyst |
23:40 | < catalyst> | I wonder what modules will do for that |
23:40 | < Yossarian> | I like the way you're thinking right now. |
23:40 | < catalyst> | I'm pretty sure they're in C++20 |
23:43 | <&McMartin> | I haven't really been paying attention to the evolution of the language past C++14, tbh |
23:43 | < catalyst> | I'm not as clued in as I used to be |
23:43 | <&McMartin> | (A side effect of consumer software, really. For iOS, using C++17 library features means your minimum deployment target is iOS 12, and that's not something we can get away with) |
23:44 | < catalyst> | fair |
--- Log closed Wed Sep 25 00:00:08 2019 |