--- Log opened Thu Apr 15 00:00:58 2010 |
00:05 | | Alek [omegaboot@Nightstar-7ff8f4eb.il.comcast.net] has joined #code |
00:25 | | Kazriko [kaz@Nightstar-e09690fa.client.bresnan.net] has joined #code |
00:25 | | mode/#code [+o Kazriko] by Reiver |
00:34 | | Vornicus-Latens [vorn@Nightstar-ea436f58.wlfrct.sbcglobal.net] has joined #code |
00:34 | | mode/#code [+o Vornicus-Latens] by Reiver |
00:34 | | Vornicus-Latens is now known as Vornicus |
00:35 | | You're now known as TheWatcher[T-2] |
00:37 | | You're now known as TheWatcher[zZzZ] |
00:42 | | Derakon[AFK] is now known as Derakon |
00:45 | <@McMartin> | Hm. Buying a personal set of fully professional quality dev tools would cost me 1.5 PS3s. |
00:46 | <@Derakon> | vim~ |
00:47 | | Orth [orthianz@Nightstar-11b736db.xnet.co.nz] has joined #code |
00:48 | < Namegduf> | That's a price of about ten thousand jaffa cakes. |
00:48 | < Namegduf> | HOrrible. |
00:49 | | Orthia [orthianz@Nightstar-3da45429.xnet.co.nz] has quit [Ping timeout: 121 seconds] |
00:50 | < Namegduf> | Alternatively, roughly ?150 Standardised Bags of Marshmellow |
00:50 | < Namegduf> | Er, just 150. |
00:51 | < Namegduf> | I use said bags as the main unit for budgeting, I find it puts things in perspective. |
00:51 | < Namegduf> | "Would I rather have 3G internet for my netbook... or two bags of marshmellows a week?" |
00:51 | < Namegduf> | (I picked the marshmellows) |
00:57 | <@McMartin> | Heh |
00:57 | <@McMartin> | Yeah |
00:57 | <@McMartin> | Derakon: vim is not a compiler, and does not result in, e.g., installable W7 drivers~ |
00:58 | <@McMartin> | This is where the "do I actually need fully professional quality tools" kicks in, and the answer is almost certainly "no" |
00:58 | <@McMartin> | But the number of it is high enough that I do have to make choices |
00:59 | <@McMartin> | Speaking of possibly having to pay money for dev tools and not wanting to, a friend of mine is considering getting into Flash development and isn't sure where to begin, and in particular if he can without purchasing/pirating stuff. |
00:59 | <@McMartin> | I have no experience in this domain, but ISTR we have a few Flash developers here. |
01:04 | <@Derakon> | McM: use binary mode~ |
01:21 | | Attilla [Attilla@FBC920.482E2D.971EED.6317D6] has quit [Connection reset by peer] |
01:21 | <@TheWatcher[zZzZ]> | McM: There are some tools that will export flash, and have vaguely similar workflows (Serif DrawPlus/MoviePlus for example), however I know of no free/very low cost systems that can produce flash in any useful manner |
01:22 | | * McMartin nods |
01:22 | <@TheWatcher[zZzZ]> | AFAICT, Adobe had the flash market sewn up tight. I could be missing some, but I have to deal with the stuff daily in work and if he manages to find a decent alternative, I'd like to know - I certainly haven't :/ |
01:24 | <@McMartin> | Right. |
01:25 | <@McMartin> | Basically, he's looking to do some easily-deployable game prototyping/development and he already knows JS; so "Flash" looks like an initially-reasonable system for his work, since all other options begin with "learn programming language X" |
01:25 | <@Derakon> | Doesn't Flash have its own programming language? |
01:25 | <@McMartin> | But if seriously doing this means he has to drop $500 or so, going Pygame or even C/SDL/OpenGL might be worth it. |
01:25 | <@McMartin> | ActionScript is a close cousin to JS; IIRC they're both instantiations of ECMAScript. |
01:26 | <@Derakon> | Ahh. |
01:26 | <@ToxicFrog> | Love2d is also a strong contender. |
01:26 | <@Derakon> | I suggest Pygame way before trying the C route. |
01:26 | <@McMartin> | Yeah. |
01:26 | <@McMartin> | Love2d I have not heard of. Link? |
01:26 | <@Vornicus> | Having played briefly with ActionScript, everything I know about ActionScript is precisely identical to the parallels in Javascript. |
01:26 | <@Derakon> | Since if he's never programmed in C then there's all kinds of things to learn. |
01:27 | <@ToxicFrog> | love2d.org |
01:27 | <@ToxicFrog> | Basically, pygame, except (1) as a stand alone program (which can be used to run seperate games, or combined with them to create a standalone binary), and (2) Lua rather than Python. |
01:27 | <@McMartin> | Heh. Enceladus'd? |
01:28 | <@McMartin> | Also, it looks like Dev-C++ is dead |
01:28 | <@ToxicFrog> | Pretty much |
01:28 | <@McMartin> | Is Code::Blocks the new hotness in "not raw MinGW"? |
01:29 | <@ToxicFrog> | No idea; I use a cross-compiler these days. |
01:31 | <@McMartin> | Oh look, Code::Blocks doesn't work on any OS newer than XP. |
01:31 | <@McMartin> | :bravo: |
01:31 | <@McMartin> | But I can make a combined install out of MinGW builds. |
01:32 | <@ToxicFrog> | (specifically, I do all of my coding in jedit, and then if I need to generate windows binaries Orias has a linux-host, windows-target gcc installed.) |
01:46 | <@McMartin> | (That *is* raw MinGW~) |
01:56 | <@ToxicFrog> | (yes) |
01:56 | <@ToxicFrog> | (my point was that I don't know what the new hotness for "not raw mingw" is, because I use raw mingw) |
01:57 | <@McMartin> | Right |
01:57 | <@McMartin> | Wiki's list of IDEs shows Code::Blocks as the only thing I'd consider a credible IDE |
01:57 | <@McMartin> | The only other thing that comes close is Qt Creator, which, well, no. |
01:58 | <@McMartin> | The subsidiary tools are fantastic, but Creator itself? |
02:23 | | Rhamphoryncus [rhamph@Nightstar-8931f88f.abhsia.telus.net] has quit [Client exited] |
02:27 | < gnolam> | McMartin: Huh? I ran C::B just fine under Vista... |
02:28 | <@McMartin> | gnolam: The download page says that the version of C::B that comes with a bundled MinGW doesn't work right under Vista because of MinGW issues, and that one should manually upgrade said copy of MinGW. |
02:28 | <@McMartin> | The IDE part presumably works fine. |
02:29 | < gnolam> | Yes. That's because MinGW ceased updating years ago, and had an... interesting... sense of priorities for years even before that. |
02:29 | < gnolam> | Not Code::Blocks's fault. |
02:29 | <@McMartin> | Er |
02:29 | <@McMartin> | No, if what they say is true, the fact that C::B has not regenerated their installer is their fault. |
02:30 | <@McMartin> | Perhaps I can fix this issue for them, if they're using sensible build systems. |
02:30 | <@McMartin> | We'll see. |
02:30 | <@McMartin> | I'm just trying to get SVAF back up to speed again. |
02:30 | | * gnolam checks the page. |
02:31 | <@McMartin> | If I read it right, if I do a full GCC 4 MinGW setup and then link C::B to it, I win |
02:31 | < gnolam> | "NOTE: The compiler included in codeblocks-8.02mingw-setup.exe does not work reliable on Windows Vista" <- sounds like they're just stuck with bundling the official MinGW build. Which is broken in oh so many ways. |
02:31 | <@McMartin> | Keep going |
02:31 | < gnolam> | Then again, I tend to install compilers and IDE's separately (except for Visual Studio). |
02:31 | <@McMartin> | "Please do not use it and install a more recent one from MinGW. That is because at the time Code::Blocks was released there was no working GCC for Windows Vista available. Meanwhile there is." |
02:32 | <@McMartin> | Yeah |
02:32 | <@McMartin> | What you're doing is what they're saying you should do |
02:32 | <@McMartin> | What I don't understand is why they haven't done it themselves in the meantime with a point release on the installer |
02:35 | | gnolam [lenin@Nightstar-38637aa0.priv.bahnhof.se] has quit [[NS] Quit: Z?] |
02:35 | <@McMartin> | But yeah, MinGW 5.1.6 and 5.1.4 have both come out since C::B did. |
02:38 | | Serah [Z@26ECB6.A4B64C.298B52.D80DA0] has quit [Ping timeout: 121 seconds] |
03:08 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has joined #code |
03:56 | | Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has quit [Connection closed] |
04:43 | | Kazriko [kaz@Nightstar-e09690fa.client.bresnan.net] has quit [Connection closed] |
05:00 | | Kazriko [kaz@Nightstar-e09690fa.client.bresnan.net] has joined #code |
05:00 | | mode/#code [+o Kazriko] by Reiver |
05:06 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has quit [Ping timeout: 121 seconds] |
05:08 | | Kazriko [kaz@Nightstar-e09690fa.client.bresnan.net] has quit [Ping timeout: 121 seconds] |
05:36 | | cpux is now known as shade_of_cpux |
05:40 | | Kazriko [kaz@Nightstar-e09690fa.client.bresnan.net] has joined #code |
05:40 | | mode/#code [+o Kazriko] by Reiver |
05:46 | | Syloqs-AFH [Syloq@NetworkAdministrator.Nightstar.Net] has quit [Connection reset by peer] |
05:51 | | Syloqs_AFH [Syloq@NetworkAdministrator.Nightstar.Net] has joined #code |
05:52 | | Syloqs_AFH is now known as Syloqs-AFH |
06:24 | | AnnoDomini [annodomini@Nightstar-c384f9e4.adsl.tpnet.pl] has joined #code |
06:24 | | mode/#code [+o AnnoDomini] by Reiver |
06:25 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has quit [[NS] Quit: *hums* Can't stay now!] |
06:29 | | * McMartin gets Code::Blocks working. http://hkn.eecs.berkeley.edu/~mcmartin/CCA.zip |
06:36 | | Derakon is now known as Derakon[AFK] |
07:05 | | Orthia [orthianz@Nightstar-fdc77178.xnet.co.nz] has joined #code |
07:07 | | Orth [orthianz@Nightstar-11b736db.xnet.co.nz] has quit [Ping timeout: 121 seconds] |
07:55 | | Chi [omegaboot@Nightstar-7ff8f4eb.il.comcast.net] has joined #code |
07:55 | | Alek [omegaboot@Nightstar-7ff8f4eb.il.comcast.net] has quit [Client closed the connection] |
08:18 | | shade_of_cpux [Moo@Nightstar-20a84089.dyn.optonline.net] has quit [Client closed the connection] |
08:52 | | Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has joined #code |
09:40 | | You're now known as TheWatcher |
09:47 | | Kazriko [kaz@Nightstar-e09690fa.client.bresnan.net] has quit [Ping timeout: 121 seconds] |
09:56 | | Kazriko [kaz@Nightstar-e09690fa.client.bresnan.net] has joined #code |
09:56 | | mode/#code [+o Kazriko] by Reiver |
10:14 | | Attilla [Attilla@FBC920.482E2D.971EED.6317D6] has joined #code |
10:14 | | mode/#code [+o Attilla] by Reiver |
10:25 | | Attilla [Attilla@FBC920.482E2D.971EED.6317D6] has quit [Client closed the connection] |
10:25 | | Attilla_ [Attilla@FBC920.482E2D.971EED.6317D6] has joined #code |
10:37 | | Rhamphoryncus [rhamph@Nightstar-8931f88f.abhsia.telus.net] has joined #code |
10:40 | | Attilla_ [Attilla@FBC920.482E2D.971EED.6317D6] has quit [Client closed the connection] |
10:40 | | Attilla [Attilla@FBC920.482E2D.971EED.6317D6] has joined #code |
10:40 | | mode/#code [+o Attilla] by Reiver |
11:23 | | Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has quit [Client closed the connection] |
12:23 | | AnnoDomini [annodomini@Nightstar-c384f9e4.adsl.tpnet.pl] has quit [Ping timeout: 121 seconds] |
12:25 | | AnnoDomini [annodomini@Nightstar-ef91445b.adsl.tpnet.pl] has joined #code |
12:25 | | mode/#code [+o AnnoDomini] by Reiver |
12:47 | <@AnnoDomini> | Now that's weird. |
12:47 | <@AnnoDomini> | I'm coding a MIDlet in Java ME, and am trying to get the current time. |
12:48 | <@AnnoDomini> | Date succeeds, but Calendar thinks it's 1970. |
13:45 | <@AnnoDomini> | Hmmm. Now I have the problem in that I need to refresh this regularly. |
14:07 | < Tarinaky> | I understand there's an atexit() function which calls functions when the program terminates normally. Does anyone know of something that will call functions even if the program terminates abnormally? |
14:08 | < Tarinaky> | Specifically to ensure that ncurses 'cleans up' and resets the terminal to how it found it even if the program crashes. |
14:09 | < Namegduf> | I don't believe you can. |
14:11 | < Tarinaky> | I should clarify I'm writing primarily in C++. |
14:12 | < Tarinaky> | Hmm. Would set_terminate be what I'm looking for? |
14:12 | < Tarinaky> | Or would this only work for a subset of errors? |
14:15 | < Tarinaky> | I suppose what I'm asking is: will segfaults throw exceptions? |
14:15 | < Namegduf> | I believe not. |
14:15 | < Namegduf> | You can have a signal handler for segfaults, though. |
14:15 | < Namegduf> | SIGKILL is the bigger issue. |
14:17 | < Tarinaky> | Aye. That as well. |
14:20 | | gnolam [lenin@Nightstar-38637aa0.priv.bahnhof.se] has joined #code |
14:26 | < Tarinaky> | So. Recommendation is to direct SIGSEGV and SIGTERM to my 'clean up and die' function then direct unhandled interrupts at it too? |
14:44 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has joined #code |
14:49 | < gnolam> | ... so, the reason we're using Word is apparently that that's what the recipient /wants/. |
14:49 | < gnolam> | Madness! |
14:49 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has joined #code |
14:54 | < gnolam> | .doc is not a publishing format, dammit. |
14:55 | < gnolam> | And that's beside the whole issue of proprietary programs and standards being used by government organizations. |
15:09 | <@ToxicFrog> | Tarinaky: pretty much. Maybe SIGHUP and SIGINT as well, depending on how you want to handle those. |
15:09 | <@ToxicFrog> | (man 7 signal for a complete list of signals and default behaviour for each) |
15:36 | < Tarinaky> | As I understand SIGHUP that's when I close the terminal I'm using? So I don't need to 'release' it. |
15:37 | < Tarinaky> | What's Sigint though? It just says "Interrupt from keyboard" |
15:38 | < celticminstrel> | Sigint is Ctrl-C. |
15:38 | < celticminstrel> | It's what the user presses to abort the program. |
15:38 | < celticminstrel> | (Though they can type Ctrl-\, Sigquit, as well.) |
15:39 | < celticminstrel> | I dunno what Sighup really is, but I don know the shell terminates upon receipt of it. |
15:39 | < Tarinaky> | I think it's Signal Hang Up. |
15:40 | < celticminstrel> | Hang Up, yes, but I'm not sure what it means in practice, or what causes it... |
15:40 | < celticminstrel> | ^do know |
15:40 | < Tarinaky> | celticminstrel: Closing the terminal... |
15:41 | < celticminstrel> | Does it? |
15:41 | < Tarinaky> | When you press that big 'x' to the top-right of your xterm/rxvt/whatever session. |
15:41 | < celticminstrel> | Okay then, whatever. |
15:41 | < celticminstrel> | (It's top-left, though. <_< ) |
15:41 | < Tarinaky> | Not on my computer :p |
15:42 | < Tarinaky> | Although it's not an 'x' on my computer. |
15:43 | < Tarinaky> | I'll want to do something with sigint though, thanks for pointing it out. |
15:43 | < celticminstrel> | What're you doing? |
15:43 | < Tarinaky> | Going back to making a roguelike. |
15:43 | < celticminstrel> | Oh. |
15:43 | < Rhamphoryncus> | nice modem here: http://en.wikipedia.org/wiki/SIGHUP |
15:44 | < celticminstrel> | I suppose you're already handling SIGQUIT? |
15:45 | | * TheWatcher eyes that |
15:45 | <@TheWatcher> | ... good gods, I feel old. I've actually used one like that. |
15:45 | < Rhamphoryncus> | I saw one like that in a movie once ;) |
15:46 | < Rhamphoryncus> | Released.. umm.. the year I was born |
15:46 | < Tarinaky> | celticminstrel: I'm not, at present, handling anything. |
15:48 | < celticminstrel> | <_< |
15:49 | < Tarinaky> | I suspect I shall have to revisit this topic later. |
15:50 | < celticminstrel> | I think if you're using curses you can set it up so that Ctrl-C does not send sigint... |
15:50 | < celticminstrel> | ...well, you can probably do it without curses too, but that's beside the point. |
15:51 | < Tarinaky> | Aye. I find it handy to leave it unblocked though. |
16:08 | < Chi> | and there's also Ctrl-Break. same functionality as Ctrl-C, but I dunno if it's the same interrupt - I've had programs where one but not the other worked. |
16:08 | < Chi> | (huh. I didn't even know about Ctrl-\) |
16:21 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has quit [Client closed the connection] |
16:21 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has joined #code |
16:41 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has quit [Ping timeout: 121 seconds] |
16:44 | < Tarinaky> | Oh crap. Exams are sooner than I thought :/ |
16:44 | | * Tarinaky uses this as an excuse to stop working on the current problem and go back to being boring >.> |
16:45 | < celticminstrel> | I'd suspect Ctrl-Break is SIGTERM, but I honestly have no idea. |
16:46 | < celticminstrel> | But many computers don't even have a Break key. |
16:46 | < Tarinaky> | You mean laptops? |
16:46 | < celticminstrel> | No. |
16:47 | < Tarinaky> | I've never seen a nonlaptop that didn't have a break key. |
16:47 | < Chi> | um. |
16:48 | < Chi> | every single standard keyboard sold these days STILL has a pause/break key. |
16:48 | < Tarinaky> | Unless we count where some vandal had physically removed and stolen the key. |
16:48 | < celticminstrel> | Okay then, Macs and laptops. |
16:49 | < Chi> | macs never had it, I think. |
16:49 | < Chi> | they don't have Ctrl either. >_> |
16:49 | <@jerith> | They do. |
16:49 | < Chi> | oh. must be new. <_< |
16:49 | < celticminstrel> | Um, yes they do. Macs have always had Ctrl. |
16:50 | <@jerith> | They don't have "alt" or "meta", but "option" usually substitutes for those. |
16:50 | < Tarinaky> | They label it with a 'celtic knot' don't they? |
16:50 | < celticminstrel> | Option is now labelled alt. |
16:50 | < celticminstrel> | No, that's the Command key. |
16:50 | < Chi> | thought they had command, not control. >_> |
16:50 | < celticminstrel> | They have three modifiers: Control, Option/Alt, and Command/Apple. |
16:50 | < Tarinaky> | I thought Command was the Mac Control key. |
16:50 | < celticminstrel> | They have both... |
16:50 | < Chi> | huh. |
16:50 | < Tarinaky> | celticminstrel: No shift? |
16:51 | < celticminstrel> | XD Of course. |
16:51 | < celticminstrel> | They have shift too. |
16:51 | <@jerith> | Command is typically used on the mac for things you'd use Control for on a PC. |
16:51 | < celticminstrel> | Yes. |
16:51 | < Chi> | well. windows have shift, ctrl, alt, win, and context. :P |
16:51 | <@jerith> | Context? |
16:51 | < Chi> | it has the same functionality as right-clicking. |
16:51 | < Tarinaky> | That's not a modifier. |
16:51 | < celticminstrel> | But Control still exists. It's used for accessing contextual menus, an artifact from the time when Macs still had one-button mice. |
16:52 | <@jerith> | Oh, "menu". |
16:52 | < Chi> | lol |
16:52 | < celticminstrel> | Yeah, Chi, Windows key and Context key aren't modifiers for the most part. |
16:52 | <@jerith> | celticminstrel: My mac has a one-button "mouse". |
16:52 | < celticminstrel> | Windows key can be used as a modifier though. |
16:52 | < celticminstrel> | Jerith: Huh? Why the quotes? |
16:53 | <@jerith> | "Windows" is a modifier that can do a thing if it's released without modifying anything. |
16:53 | <@jerith> | celticminstrel: It's a trackpad. :-) |
16:53 | < celticminstrel> | So is Alt on Windows. |
16:53 | < celticminstrel> | As far as I know, though, the Windows key is intercepted by the OS, so a program can never see it. |
16:53 | <@jerith> | Typically, Command gets mapped to Windows. |
16:53 | < celticminstrel> | Yes. |
16:53 | <@jerith> | Or the other way around. |
16:53 | < Chi> | yeah. alt generally activates the menu bar. :P |
16:54 | | * Chi thumbs twiddles. |
16:54 | < Tarinaky> | celticminstrel: Should I point out that Linux doesn't intercept it~ |
16:54 | < Chi> | I should go eat. |
16:54 | <@jerith> | Both of them get mapped to Super on Linux boxen, generally. |
16:54 | < celticminstrel> | But yeah, the context menu key is not a modifier, just like my volume-up, volume-down, mute, and eject keys are not modifiers. << |
16:54 | < celticminstrel> | ^ <_< |
16:54 | < celticminstrel> | What's "Super"? |
16:54 | <@jerith> | Mac OS annoys me by actually using all the modifier keys. |
16:55 | < celticminstrel> | ...what? |
16:55 | < Tarinaky> | celticminstrel: The xconfig files call it Meta4. |
16:55 | < Tarinaky> | *X config files |
16:55 | <@jerith> | celticminstrel: "Control", "Alt", "Meta", "Super" and "Hyper" were the original modifiers. |
16:55 | < celticminstrel> | ...okay... |
16:55 | <@jerith> | Typically, the "Alt" key generates a "meta". |
16:56 | < Tarinaky> | ...I thought AltGr was Super? |
16:56 | <@jerith> | On Linux, I can bind whatever I like to "Super+<whatever>" and know I won't conflict with anything. |
16:57 | <@jerith> | Tarinaky: I think it's "alt" or something, actually. I've always mapped it to "meta", because that's what I use. |
16:57 | < celticminstrel> | Well, Mac doesn't use the function keys for much, so I could bind any combination of modifier and function key to do something. Then again, there is some possibility of conflict, though it's low. |
16:58 | < celticminstrel> | In particular, the first four function keys might be mapped to undo/cut/copy/paste in some programs. |
16:58 | <@jerith> | On Mac OS, for any given <whatever>, there's probably *something* that uses {Option,Command,Control}+<whatever> already. |
16:58 | < celticminstrel> | Well, except for F13 through F16. <_< |
16:58 | < celticminstrel> | I don't think anything uses those. |
16:59 | <@jerith> | Very few keyboard have them. |
16:59 | <@jerith> | +s |
16:59 | < celticminstrel> | Well, the standard Mac ones did. I don't remember if the new standard Mac ones do. |
16:59 | < celticminstrel> | And <anything>+Help never seems to be used. |
16:59 | <@jerith> | I tend to use Command+Control for most of my custom stuff, but even that's not entirely "safe". |
17:00 | < celticminstrel> | ....wait. Why does Ctrl-Help paste my name? :/ |
17:00 | <@jerith> | My MBP doesn't have f13+ |
17:00 | < celticminstrel> | Because it's a laptop. |
17:00 | < celticminstrel> | My Mac Pro keyboard has it. |
17:01 | <@jerith> | I tend not to use function keys because they're too far away. |
17:01 | < celticminstrel> | Is your custom stuff generally system-wide shortcuts? |
17:01 | <@jerith> | Usually. |
17:01 | <@jerith> | Super+{Z,X,C,V,B} controls my music player in Linux. |
17:02 | < celticminstrel> | Ah, apparently I actually added a key binding to make Ctrl-Help paste my name. >_> Fixed now. |
17:02 | < celticminstrel> | How do you set your custom shortcuts on Mac? |
17:03 | <@jerith> | I can't do that on Mac OS, so I use Command+Control+{Z,X,C,V,B} to do it. |
17:03 | <@jerith> | celticminstrel: QuickSilver. |
17:03 | <@jerith> | If a suitable plugin doesn't exist, you can call a shell script or AppleScript or something. |
17:04 | <@jerith> | Setting up "give me a terminal window on this bloody workspace whether iTerm is currently running or not" was about a month's worth of effort. |
17:05 | < celticminstrel> | ...I dunno what that even means. |
17:05 | <@jerith> | iTerm is an alternative to Terminal.app. |
17:05 | <@jerith> | I prefer it for a variety of reasons, but a lot of people hate it. |
17:06 | <@jerith> | I do about 90% of my work in an editor or a terminal windows. |
17:06 | <@jerith> | -s |
17:06 | <@jerith> | I split tasks up onto different workspaces. What Mac OS calls "Spaces". |
17:07 | < celticminstrel> | Oh, those. |
17:07 | <@jerith> | The default Mac OS thing is to keep all the windows belonging to an application together in one workspace. |
17:08 | <@jerith> | Unfortunately, "iTerm" is a single application and that means all its windows get yanked over to the first workspace it started on. |
17:09 | <@jerith> | Fixing that required twiddling a bunch of non-obvious settings. |
17:09 | < celticminstrel> | What sorts of settings? |
17:09 | <@jerith> | I forget the details, but most of them are in the Spaces config. |
17:10 | < Tarinaky> | There's a similar app to Quicksilver called Gnome-Do. |
17:10 | <@jerith> | Tarinaky: They overlap, but not really for what I use QuickSilver for. |
17:11 | <@jerith> | (Also, when I tried Gnome-Do it *really* didn't work very well. Not being in Gnome probably had a lot to do with it.) |
17:11 | < Tarinaky> | Eh. I'm not in gnome and it worked fine for me :/ |
17:11 | < Tarinaky> | There were a couple of issues with the first major version but nothing was a show-stopper. |
17:12 | <@jerith> | I *did* last try it about two or three years ago. |
17:12 | <@jerith> | I couldn't get it to run in the background and listen, so I had to start it every time. |
17:13 | < Tarinaky> | Never had that problem :/ |
17:13 | <@jerith> | Then it took 15 seconds to index the universe before appearing. |
17:13 | <@jerith> | It's quite possible that I was Doing It Wrong, but all the available information assumed that Gnome would be around. |
17:15 | <@jerith> | I'm atypical enough in my interface requirements that I run into that kind of thing regularly. |
17:15 | | * Tarinaky doesn't use a DE... that's pretty atypical. |
17:16 | <@jerith> | Combine my ADD and its associated Very Low Frustration Threshold with a strong streak of perfectionism... |
17:17 | <@jerith> | DE? As in IDE? |
17:17 | <@jerith> | If so, I have a very good DE that isn't really an IDE. |
17:17 | | Serah [Z@26ECB6.A4B64C.298B52.D80DA0] has joined #code |
17:17 | <@jerith> | It's emacs and a bunch of terminals. |
17:17 | < Tarinaky> | DE as in Gnome or KDE. |
17:17 | <@jerith> | Ah. |
17:18 | < Tarinaky> | My IDE is similar except replacing emacs with vim. |
17:18 | <@jerith> | Fluxbox for me, and it still has stuff I'd rather it didn't have. |
17:18 | < Tarinaky> | Heh <3 Fluxbox. |
17:18 | <@jerith> | Except these days I live almost entirely within Mac OS, because it makes sense for work. |
17:18 | < Tarinaky> | I've set up compiz to behave like fluxbox. |
17:18 | < Tarinaky> | Except with eyecandy. |
17:19 | <@jerith> | I hate eyecandy. It distracts. |
17:19 | < Tarinaky> | Only when it's over done. |
17:19 | <@jerith> | (Useful visual effects are not eyecandy, but there are very few of those.) |
17:20 | < Tarinaky> | Just a little bit of polish to make it look slick. |
17:20 | <@TheWatcher> | e16, damnit >.> |
17:20 | <@jerith> | One of the things that still regularly breaks me is the "changing Spaces" animation in Mac OS. |
17:20 | <@jerith> | AND I CAN'T TURN THE FUCKING THING OFF! |
17:20 | <@jerith> | (Sorry.) |
17:21 | | * TheWatcher nocomments on some of OSX's 'features' |
17:21 | <@jerith> | When I push "take me to the workspace where I'm hacking on this week's stupid validation crap", I want to be there immediately. |
17:22 | < Tarinaky> | http://tinypic.com/r/15qexvt/5 |
17:22 | <@jerith> | I don't want the web browser with a cat picture in it to fly past on the way, because that triggers my brain's "throw all your state on the floor and become a gibbering wreck" feature. |
17:23 | | * TheWatcher sometimes suspects that Apple is the Square Enix of OS developers, and OSX is the Final Fantasy of OSes, honestly. |
17:23 | <@jerith> | Having never played FF, I'm failing to follow. |
17:23 | <@TheWatcher> | Few years from now, starting an application is going to involve waiting for a 20 minute cutscene to play out, each time |
17:24 | < Tarinaky> | Is this before or after they add GFs and the Junction system to Office? |
17:24 | <@jerith> | Interesting 7chan channels you have open there, Tarinaky. >.> |
17:24 | < Namegduf> | XD |
17:25 | < Tarinaky> | What? Are you implying there's anything wrong with my sexuality? |
17:25 | < Tarinaky> | :p |
17:26 | < Serah> | Yes. |
17:26 | <@TheWatcher> | jerith: as the FF series has added sequel after sequel, things like fights have involved longer and longer (sometimes unskippable) animated sequences as you summon some Big Thing to assist you, usually taking several minutes all for a 1 second effect in game |
17:26 | < Namegduf> | I'm more looking at #cd, because I think I may have just heard enough to know what that is. :P |
17:26 | < Serah> | If you're in doubt the answer is probably negative. |
17:26 | <@jerith> | Nope, just that it's an interesting way to discover it. :-) |
17:27 | < Namegduf> | Hehe. |
17:27 | | * Tarinaky shrugs. |
17:29 | <@jerith> | (I live in Cape Town, where only about half my friends have "typical" sexuality.) |
17:29 | | * Tarinaky inserts a joke about how it's a good thing too given he spends all his time talking about physics and computers~ |
17:30 | < Namegduf> | XD |
17:30 | < Namegduf> | You can't use IRC without bumping into people of all preferences.. |
17:31 | < Tarinaky> | Statistically it's something like 1 in 10. With this in mind, anyone want to speculate on who the other one is? :p |
17:31 | < Namegduf> | I'm willing to bet it's way better than that. |
17:32 | < Serah> | I know where Namegduf is from. |
17:32 | < Serah> | :p |
17:32 | < Serah> | Otoh: It's probably not him. |
17:33 | < Namegduf> | Hehe. XD |
17:34 | | * jerith is /mostly/ heterosexual. |
17:34 | <@jerith> | I'm attracted to women more than men, but why let the shape of one's genitals get in the way of either a good time or true love? |
17:34 | < Namegduf> | Haha. |
17:35 | < Namegduf> | Sounds similar to my philosophy. :P |
17:35 | | * TheWatcher args, keeps pressint Ctrl+x, o and wondering why the cursor isn't switching to the other emacs instance running on another machine >.< |
17:35 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has left #code [] |
17:35 | < Namegduf> | celticminstrel ran away |
17:35 | < Tarinaky> | TheWatcher: There's probably a way of linking them up. |
17:36 | <@TheWatcher> | Probably, this is emacs afterall |
17:36 | | * jerith hugs TheWatcher. |
17:36 | <@jerith> | Do you screw up webforms by hitting C-e and having it not do what you expect? |
17:38 | <@TheWatcher> | And close tabs with C-w >.> |
17:40 | <@jerith> | At least on a Mac, Cmd-w means "close window". |
18:12 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has joined #code |
18:36 | | * gnolam is saved by his own documentation yet again! |
18:37 | <@jerith> | LIES! |
18:37 | <@jerith> | You read the source, didn't you? |
18:39 | < Namegduf> | Source is just machine-readable documentation |
18:40 | <@jerith> | Namegduf: Not some of the source I've had to read in my time... |
18:40 | < Namegduf> | XD |
18:43 | < gnolam> | jerith: Since this was content creation, the source didn't have much useful information. :) |
18:46 | <@jerith> | :-) |
18:48 | < Namegduf> | I present to you the worst question ever to be asked on the Go language mailing list: |
18:48 | < Namegduf> | "Does Go is following the POSIX standard?" |
18:49 | <@jerith> | There's a POSIX standard for an Oriental strategy game!? :-P |
18:49 | <@jerith> | (Yes, I know what Go is in this context.) |
18:49 | <@jerith> | (Stupid bloody name, though.) |
18:50 | < Namegduf> | The best reply was from one of the two lead devs, which was merely to comment that Go regrettably also doesn't yet follow ATM D2851-98(2009) either. |
18:50 | < Namegduf> | (With a link to http://www.astm.org/Standards/D2851.htm) |
18:51 | <@jerith> | The best thing about standards is that there are so many to choose from. |
18:51 | <@jerith> | My favourite (fictional) example is ISO tea vs ANSI tea. |
18:51 | < Namegduf> | Yeah. That in particular is an odd choice, though. |
18:52 | < Namegduf> | :P |
18:52 | <@jerith> | The former has milk in it. The latter has lemon. |
18:52 | < Namegduf> | Weird ANSI people. |
18:52 | <@jerith> | A cup of tea conforming to both would be vile. |
18:52 | < celticminstrel> | How do I remove a UNIX user? |
18:53 | <@jerith> | celticminstrel: With a cricket bat and a lime pit? |
18:53 | < celticminstrel> | <_< |
18:53 | <@jerith> | Which OS? |
18:53 | < Namegduf> | You tell them that you think UNIX stole everything from Windows |
18:53 | < celticminstrel> | Mac |
18:54 | <@jerith> | There's generally "userdel" and "deluser", one of which is a higher level wrapper for the other. |
18:54 | < Namegduf> | The latter. |
18:54 | < Namegduf> | (I had need for it recently) |
18:54 | <@jerith> | And on a mac, you do it through System Preferences. |
18:54 | < celticminstrel> | Man fails on those, and System Preferences only lists login users. |
18:54 | <@jerith> | Or, if it's a daemon user or something, you leave it there. |
18:55 | < celticminstrel> | ? |
18:56 | <@jerith> | Is it causing a problem? |
18:56 | <@jerith> | By "daemon user", I mean something like a "mysql" user or whatever. |
18:56 | < celticminstrel> | Yeah. |
18:57 | <@jerith> | What I'm trying to ask, very badly, is "what user and why?" |
18:57 | < celticminstrel> | Might not be necessary after all. |
18:58 | < celticminstrel> | I was reinstalling something. |
18:59 | < Tarinaky> | I'm currently having trouble working out what the best way of handling ncurses input system is. (C++ based Roguelike) :/ |
18:59 | < celticminstrel> | Ncurses is annoying. |
19:00 | < celticminstrel> | Annoying enough to make me want to write my own library to do effectively the same thing. <_< |
19:00 | < celticminstrel> | That doesn't mean I will though. >_> |
19:00 | < Tarinaky> | An incredibly large switch statement would be workable were it not for the fact that I'll need a character sheet and an inventory etc... |
19:01 | < Tarinaky> | All of which very quickly increase the level of complexity three-fold. |
19:01 | < celticminstrel> | You could have a map, mapping keys to functions. |
19:01 | < Tarinaky> | Aye. But the problem is - how do I distinguish between pressing KEY_UP to move and pressing the same key when the inventory is open... |
19:02 | < Tarinaky> | Or when talking to an NPC. |
19:02 | < Tarinaky> | Or selecting an attribute for a level up... etc... etc... |
19:02 | < Namegduf> | Well, presumably, somewhere you're storing state for what you're showing somewhere. |
19:02 | < celticminstrel> | I suppose you have a single event loop for everything? |
19:02 | < Tarinaky> | Even just sticking to the map - differentiating between movement and 'look' is a pain in the arse. |
19:02 | < Namegduf> | So I'd suggest looking at that. |
19:03 | < celticminstrel> | Then you'd just have to check where you are every time input is received. |
19:03 | < celticminstrel> | ...how would movement and look be confused, anyway? |
19:03 | < Tarinaky> | COnfused in terms of keeping the code neat and tidy. |
19:05 | < Tarinaky> | Anyway. So is the best solution to attach a map to every window/mode to resolve keys into the correct functor? |
19:10 | < Tarinaky> | It's just then I feel like I'm doing something wrong because a lot of the code feels redundant (since moving the character left is very similar as the other 7 directions... never mind that looking/aiming/whatever is exactly the same as those except you're moving a different variable) :/ |
19:11 | < Tarinaky> | Don't suppose anyone has any suggestions :/ |
19:13 | < Namegduf> | "Trying to avoid code duplication where the lines are not, in fact, the same, has always made code uglier and not that much shorter in my experience." |
19:26 | <@McMartin> | Actually, absorbing that kind of thing into a couple of objects that got to exploit inheritance actually made my binary smaller compared to the C version. o_O |
19:27 | < Tarinaky> | I'm not sure how I'd use inheritance against this problem. |
19:29 | <@McMartin> | Well, I was replying mainly to Namegduf's statement |
19:29 | <@McMartin> | Anyway, a pair of dx/dy variables might do what you want. |
19:29 | < Tarinaky> | Ah. |
19:29 | <@McMartin> | Set by the direction, then you check x+dx and y+dy. |
19:30 | < Tarinaky> | BRB, I need to restock on cola. |
19:30 | < Namegduf> | McMartin: I'm not sure how that disagrees. |
19:30 | < Namegduf> | I didn't said it didn't get shorter. |
19:31 | <@McMartin> | Oh. Just not that much shorter. |
19:31 | <@McMartin> | Fair enough~ |
19:31 | < Namegduf> | Yeah. |
19:31 | <@McMartin> | (It also made it prettier though because the shift from functions to objects let me get rid of a bunch of s->blah by replacing them with implicit "this->"s~) |
19:43 | < Tarinaky> | Bk. |
19:44 | < Tarinaky> | Just my luck. I go to the store when there's a drunk mouthing off at the security ;/ |
19:47 | < Tarinaky> | Anyway. I'm not sure about how I'd set the dx and dy variables then add them. Don't the functors in the map need the same calling prototype? |
19:55 | <@AnnoDomini> | How is maskable interrupt numbering done? |
19:55 | < Namegduf> | Eurgh |
19:56 | | * Namegduf stabs people writing shitty Java and doing crappy SE, and telling other people they're wrong to tell them different |
19:56 | < Namegduf> | Writing many small, cohesive classes == Good |
19:57 | < Namegduf> | Writing very many small classes which each implement pretty much nothing at all == Bad |
19:57 | < Namegduf> | Right? |
19:57 | < Tarinaky> | Don't look at me for confirmation - I'm a terrible coder. |
19:57 | < celticminstrel> | Well, it sounds bad... |
19:59 | < Namegduf> | Let me quote the original complaint from someone else: "However, NetDataPacket is a class that does literally nothing but extend NetPacket, and NetPacket implements NetSendable anyway. NetSendable does nothing by itself either!" |
19:59 | < Namegduf> | So far as the explanation goes, apparantly they exist entirely for conceptual design reasons based on their names. |
20:00 | < Namegduf> | "NetPacket implements NetSendable which indicates the packet can be |
20:00 | < celticminstrel> | Well, NetSendable is an interface. It's not supposed to do anything. |
20:00 | < Namegduf> | serialized." <-- Because a packet which *cannot* be serialized makes sense. |
20:00 | < Namegduf> | *really* |
20:00 | < celticminstrel> | Oh, well that sounds silly then. |
20:02 | < Namegduf> | I would need to go check, but I'd bet there's no other implementations of NetSendable, either. |
20:02 | < Namegduf> | Because this is a really small, simple, stupid thing. |
20:08 | | * AnnoDomini mails someone vaguely annoying a 30 MB attachment as help. |
20:16 | <@McMartin> | Namegduf: You are largely right. Refactoring is now easy enough that "we should leave it in the ontology now in case we want to extend it later" no longer holds water. |
20:16 | <@McMartin> | The only reason to have do-nothing classes is because they are actually your abstract superclass that everyone uses. |
20:16 | < Namegduf> | Yeah. |
20:16 | <@McMartin> | That said, if someone has a functional programming accent, they might be tempted to do this just as a way of having tagged data. |
20:17 | <@McMartin> | In which case you slap them and blame Java or C++ for having really crappy RTTI >_> |
20:17 | <@McMartin> | But the slapping is for their own good! |
20:18 | <@McMartin> | I guess if they somehow came to Java via Eiffel that could happen too |
20:18 | < Namegduf> | There's a part at the start of their reply I didn't quote where they basically criticised the person criticising their do-nothing classes for wanting low cohesion code, which I really find irritating |
20:18 | <@McMartin> | Basically, any language with a rapid typeswitch |
20:18 | <@McMartin> | Oy |
20:18 | <@McMartin> | Oh wait, I thought of a counterexample to my earlier claim |
20:19 | <@McMartin> | A do-nothing NullNode implementation for a tree where you have RealNode, LeafNode, NullNode, &c, that's OK too |
20:19 | < Namegduf> | I'm right in thinking that a class which does nothing but inherit from another class by definition is as low cohesion as you can get? |
20:19 | <@McMartin> | I've never even heard the word "cohesion" in this context |
20:19 | < Namegduf> | Ah. |
20:20 | < Namegduf> | Let me quote "The student advocates low cohesion code i.e. to code everything in a big class rather than lots of little classes. He doesn't see value in abstracting a problem into lots of little classes with very small amounts of code for a specific purpose." |
20:20 | < Namegduf> | This isn't me they're speaking to, but I *am* going to have to deal with their code |
20:20 | | * McMartin ponders |
20:20 | | * McMartin digs out a Weapon |
20:21 | <@McMartin> | Let me see if there's an AntiPattern that can be deployed against him. |
20:21 | < Namegduf> | Oh, that could be fun |
20:21 | < Namegduf> | I *can* reply to the discussion. |
20:21 | <@McMartin> | He's trying to invoke one himself, and in some sense could be right depending on the code. |
20:21 | <@McMartin> | If you have a single TheApplication class that does *everything* you are in fact doing it wrong. |
20:22 | < Namegduf> | Hmm |
20:22 | < Namegduf> | These people talk about coupling |
20:22 | < Namegduf> | As a desirably low thing |
20:22 | <@McMartin> | Mmm. Yes, but that's why you *have* abstract superclasses |
20:22 | < Namegduf> | I suppose so. |
20:23 | <@McMartin> | My little CCA thing has un-awesomely high levels of coupling because my 2D array state updater also carries around a bunch of SDL routines. |
20:23 | < Namegduf> | Wanting classes to actually have a significant purpose is not "wanting low cohesion", though. |
20:23 | <@McMartin> | I've merged model and view, if you will, and this is normally bad. |
20:23 | < Namegduf> | Ah. |
20:23 | <@McMartin> | Yeah |
20:23 | <@McMartin> | This *might* be Poltergeists. |
20:24 | < Namegduf> | This is why Systems Engineering is a dismal failure. |
20:24 | <@McMartin> | "Poltergeists are classes with limited responsibilities and roles to play in the system; therefore, their effective life cycle is quite brief. Poltergeists clutter software designs, creating unnecessary abstractions; they are excessively complex, hared to understand, and hard to maintain." |
20:25 | <@McMartin> | "This Antipattern is typical in cases where designers familiar with process modeling but new to object-oriented design define architectures." |
20:25 | < Namegduf> | Everyone who sticks around to be a teaching assistant for it is apparantly incapable of holding more than a significantly limited subset of the concerns in their head at once, just like everyone else, but unlike everyone else, they don't seem to temper them with "common sense". |
20:25 | <@McMartin> | That said, this is specificially for the case of classes whose instances appear "oly briefly to initiate some action in another more permanent class" |
20:25 | < Namegduf> | (For Systems Engineering) |
20:25 | < Namegduf> | Yeah. |
20:26 | < Namegduf> | I've heard it called "Making a system to boil the oceans when you want to make a cup of tea." |
20:26 | < Namegduf> | I've heard lots of implicit and explicit statements, especially in C++, that overly complex inheritance hierarchies are bad. |
20:26 | < Namegduf> | But I don't know an obvious thing to show. |
20:27 | <@McMartin> | Making a system to boil the oceans when you want a cup of tea is "Swiss Army Knife" |
20:27 | <@McMartin> | Spaghetti Inheritance is something else. |
20:28 | < Namegduf> | Yeah. |
20:28 | | * Rhamphoryncus pokes his head in |
20:29 | < Rhamphoryncus> | IMO, attempts to avoid "code duplication" are usually misguided. Moving some logic out into a separate function can make the code more readable even without removing any duplication |
20:31 | <@McMartin> | So, they don't have a name for it in this book, but the usual objection is that the class structure should model the computation, not analyses of the problem |
20:31 | < Namegduf> | Ah. |
20:31 | < Rhamphoryncus> | I'm pretty iffy on classes and inheritance too. The whole approach seems overcomplicated for what it's trying to do. The liskov substitution principle in particular has nothing do with real programming, where the whole point of a subclass is to *change* the parent's semantics |
20:31 | <@McMartin> | Rhamphoryncus: It's a structured application of function pointers |
20:32 | < Rhamphoryncus> | McMartin: ie a convenient bit of namespacing. That much I agree with |
20:32 | < Rhamphoryncus> | which is why you can do OO in C, heh |
20:32 | <@McMartin> | Not quite what I meant. |
20:32 | < Namegduf> | I dislike OO in general, really. |
20:32 | < Namegduf> | I like interfaces, dislike OO. |
20:32 | < Namegduf> | http://pastebin.com/rrrvVtdE <-- Full quote of the two posts, by the way. |
20:33 | <@McMartin> | I tend to be mirror-universe OO, which is to say I vastly prefer functional-style data-directed programming where you're doing something like a typeswitch. |
20:33 | < Namegduf> | There's some additional complaints and a "I want to just rewrite it" that gets a "That's shitty SE" response that's a little more justifiable. |
20:33 | < Rhamphoryncus> | I've never seen a good explanation of why namespaces are good. The strongest argument I've seen has been documentation, but that doesn't require a dedicated mechanism |
20:33 | < Namegduf> | Although I feel like quoting their own slides about how refactoring is good back at them. |
20:34 | <@McMartin> | Rhamphoryncus: Namespaces are good so that things can keep having short names. |
20:34 | <@jerith> | Rhamphoryncus: Namespaces are good to prevent nomenclature collision. |
20:34 | < Rhamphoryncus> | McMartin: I consider name prefixes to be a form of namespaces |
20:34 | <@McMartin> | Yes, and they suck |
20:34 | < Rhamphoryncus> | jerith: agreed |
20:34 | <@jerith> | "zip" could mean several things. |
20:35 | < Rhamphoryncus> | McMartin: a shitty form, yes, but a form none the less |
20:35 | <@McMartin> | Proper namespaces are a non-shitty form of namespaces. |
20:35 | <@McMartin> | Anyway, OO, and, specifically, virtual function semantics, is a way of getting polymorphism, which is good because it means that master control programs can be much simpler. |
20:36 | <@McMartin> | There are other ways of getting polymorphism but OO is a widely-taught and fairly-easy-to-reason-about discipline to get them. |
20:36 | < Namegduf> | Yeah. |
20:37 | < Namegduf> | I like interfaces, personally |
20:37 | <@McMartin> | Yeah, that's a lot of what I'm thinking of here |
20:37 | <@McMartin> | And the way they're compiled turns out to be both more code- and memory-efficient than the "obvious" way of doing it in C. |
20:37 | <@jerith> | I like the idea of interfaces, but none of the implementations I've seen. |
20:37 | < Rhamphoryncus> | I think there's a difference between objects and object-oriented |
20:37 | <@jerith> | Java's, in particular, are utterly, utterly horrible. |
20:37 | <@McMartin> | By 'interface' here, jerith, we really just mean "abstract superclass". |
20:38 | < Namegduf> | Well, they're the same thing at the end of the day. |
20:38 | <@McMartin> | As in, "To draw my scene, I call 'render()' on all these objects of different types" |
20:38 | < Namegduf> | Well, no |
20:38 | <@McMartin> | Yeah, not remotely |
20:38 | < Rhamphoryncus> | In a statically typed language I'd love interfaces. However, in python they're just redundant |
20:38 | < Namegduf> | They're parts of different conceptual models (although for some reason, no one finds interfaces complex enough to call them a whole "model") that do the same job. |
20:38 | < Namegduf> | What's wrong with Java's, by the way? |
20:39 | <@jerith> | Rhamphoryncus: I disagree. |
20:39 | <@McMartin> | jerith: Any time multiple inheritance in any form rears its head, the doom spiders awaken. |
20:39 | <@jerith> | zope.interface is about as close as anything I've seen to what I actually want. |
20:39 | <@McMartin> | They're fundamentally conceptually incoherent |
20:39 | < Rhamphoryncus> | jerith: what for? |
20:40 | <@jerith> | Namegduf: Like a lot of Java's "features", they're too restrictive to be really useful. |
20:40 | < Namegduf> | Ah. |
20:40 | <@jerith> | No static methods or constructors, for example. |
20:40 | < Namegduf> | Well... they're interfaces. |
20:40 | < Namegduf> | Not classes. |
20:40 | < Rhamphoryncus> | McMartin: my conclusion, after studying how python actually does super calls and overrides, is that what we should have is per-method single inheritance. That is one class can override .foo(), and another can override .bar(), but if they both override .foo() it should be an error |
20:41 | < Namegduf> | All they're defined to do is say "This object provides these functions" |
20:41 | <@jerith> | Rhamphoryncus: Mostly as a way to tag an object with a particular set of semantics. |
20:41 | < Rhamphoryncus> | jerith: tag for what purpose? |
20:41 | <@McMartin> | Namegduf: That still doesn't really properly solve the namespace collision problem, alas. |
20:41 | < Namegduf> | Namespace collision problem? |
20:41 | <@McMartin> | This is why I prefer what I believe are called "view objects" |
20:41 | <@McMartin> | If you want interface A and B and they both have a method "foo" |
20:41 | <@jerith> | And assert that this is valid (or, at least, asserted) programmatically. |
20:41 | <@McMartin> | Implementing both is well-defined but almost certainly not what you want |
20:42 | < Rhamphoryncus> | jerith: assertions are good, but accomplish nothing in a program that's already correct |
20:42 | <@McMartin> | The "best" answer when this happens is for your purported subclass C implements A, B actually not implement either but have methods "A asA()" and "B asB()" |
20:42 | <@McMartin> | I say best from a "clean semantics" standpoint |
20:42 | <@McMartin> | This is rarely the best from an efficiency standpoint, as one might imagine |
20:43 | <@jerith> | Rhamphoryncus: Programming is mostly about making it easier to write correct code and harder to write incorrect code. |
20:43 | <@McMartin> | Although thinking about it, there might be some ways to cache stuff for speed... Hm. |
20:44 | < Rhamphoryncus> | jerith: I think you'd do better with standard unit test suits. Ensure your file object obeys normal invariants, or your hashable object, or.. |
20:44 | <@jerith> | z.i lets me tag other peoples' things with my own interfaces if they happen to have suitable behaviour. It also lets me register adapters, which is nice, but a little too much like "magic" for me to be entirely comfortable with. |
20:45 | <@jerith> | Rhamphoryncus: Consider plugin objects. |
20:46 | <@jerith> | It's useful to attach interfaces that assert that they are, indeed, the right kind of thing for my app to treat as a plugin. |
20:47 | < Rhamphoryncus> | I agree it's useful, I just think the end benefit is minor |
20:47 | <@jerith> | The only guarantee is that the author asserted this to be true, but that's still a useful guarantee. |
20:47 | < Rhamphoryncus> | For instance, it's common to stub out required methods but have them raise NotImplementedError instead. How is this better than not providing the method? |
20:48 | <@jerith> | It isn't, but that's not really what I want the interface for. |
20:50 | <@jerith> | I want them so that I can programmatically reason about intended semantics in a clean way. |
20:50 | < Rhamphoryncus> | I find the idea of registering handlers for third-party objects to be a "harder" use, but not one typically done with interfaces. By this I mean you define your own API for something, say a particular serialization interface, then add handlers for builtin types and your own types. Third party code may then register their own handlers with you |
20:51 | <@jerith> | Something like that, yes. |
20:52 | < Rhamphoryncus> | In practise that ends up with two distinct APIs: one for hardcoded (builtin) types, another for third-party extensions |
20:52 | <@jerith> | I have a "resource store" app for $dayjob that supports a bunch of different file storage backends. |
20:54 | <@jerith> | I want an interface for "this is a thing I can use as a resource backend" so that the app can barf appropriately if it's told to use something that isn't one. |
20:57 | < Rhamphoryncus> | Wouldn't a unit test suite tell you far more? |
20:57 | < Rhamphoryncus> | You could even have a formal list of methods if you wanted |
20:59 | <@jerith> | Rhamphoryncus: A unit test wouldn't help if the config said "store this kind of file in String" instead of "store this kind of file in LocalDirectoryRepository". |
21:00 | < Rhamphoryncus> | hmm? |
21:00 | <@jerith> | Well, this is in Java so everything's extra-painful. |
21:01 | <@jerith> | But when I construct the thing by reflection from reading the class name out of the config file, I can cast it to the interface and have it work. |
21:02 | <@jerith> | If I were doing it in Python, I'd want to at least assert that the thing I've just created claims to be what I'm expecting to treat it as. |
21:02 | < Rhamphoryncus> | So it's also a class-lookup mechanism |
21:02 | <@jerith> | Not really. |
21:03 | <@jerith> | It's a way for a class to assert that it implements certain semantics. |
21:04 | <@jerith> | There's no clean way to distinguish a "string-like" object from a "list-like" object in Python, for example. |
21:04 | <@jerith> | Because strings are also a kind of list. |
21:05 | < Rhamphoryncus> | Is this some generic format like json which can't imply what type you're expecting at a certain point? |
21:05 | < Rhamphoryncus> | A kind of iterable, but yeah |
21:06 | <@jerith> | A generic config. |
21:07 | <@jerith> | The point is that information only available at runtime is used to determine what kind of object I'm getting. |
21:07 | <@jerith> | So I need a way to assert, at runtime, that I'm getting a kind of object I can use. |
21:08 | <@jerith> | It's a similar problem to plugins, but more limited in scope. |
21:08 | < Rhamphoryncus> | Seems necessary in java |
21:08 | <@jerith> | It isn't really possible to do in Java. |
21:08 | | Orthia [orthianz@Nightstar-fdc77178.xnet.co.nz] has quit [Client closed the connection] |
21:09 | < Rhamphoryncus> | hmm? |
21:09 | <@jerith> | The best I can hope for is a ClassCastException on the object I've created using the reflection API. |
21:10 | <@jerith> | And I'm not entirely confident there's enough information available at runtime to assert what I'm trying to assert. |
21:10 | <@jerith> | It might be possible. Meh. |
21:10 | <@jerith> | I remember that there were a bunch of things I ended up having to just assume. |
21:14 | <@jerith> | But anyway, consider a hypothetical system that had that limited kind of "plugin" that needed to 'append' or 'remove' things from the object it was configured to use. |
21:14 | <@jerith> | Lots of objects have those two methods, so duck typing fails. |
21:15 | <@jerith> | Someone might configure it to use a list, and it would be perfectly happy except that nothing ever gets persisted or whatever. |
21:16 | <@jerith> | Maybe the semantics it's expecting are "end application" and "move again". |
21:16 | < Rhamphoryncus> | I think a list is perfectly valid. Not the semantics you expect, but works within the API |
21:16 | <@jerith> | Stupid and contrived, but a demonstration. |
21:16 | | Orthia [orthianz@Nightstar-fdc77178.xnet.co.nz] has joined #code |
21:17 | < Rhamphoryncus> | My instinct for deserializing is to test for an expected type at the point of deserialization, not after. Might not be practical though |
21:17 | <@jerith> | If I can tag all the classes that implement the semantics I want with an assertion about those semantics, I can write a more robust application. |
21:18 | <@jerith> | Oh, this isn't about serialisation. |
21:18 | <@jerith> | That's a different issue entirely. :-) |
21:19 | <@jerith> | This is about making sure that the thing I'm writing this file to is actually a thing that stores files and not a thing that processes credit card transactions. |
21:19 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has left #code [] |
21:20 | < Rhamphoryncus> | hrm. That's a namespace issue. You want to write file_append rather than creditcard_append, but without being that verbose |
21:20 | <@jerith> | Because then I've just accidentally purchased a cheezburger instead of increasing my ad revenue through additional content on my website. |
21:20 | <@jerith> | Namespaces are about syntax and nomenclature. |
21:21 | <@jerith> | Interfaces are about asserting semantics. |
21:21 | <@jerith> | I /could/ use the first eight characters of my class name as the "interface tag". |
21:22 | <@jerith> | It would meet most of my requirements. |
21:22 | <@jerith> | I could also use baroque method names or whatever and then duck-type on those. |
21:22 | < Rhamphoryncus> | Interfaces don't test semantics though. You need unit tests for that |
21:23 | < Rhamphoryncus> | All interfaces give you is a superficial claim that it supports the interface |
21:23 | <@jerith> | Correct. |
21:24 | <@jerith> | But there's no way of programmatically testing semantics short of comprehensive test coverage. |
21:24 | < Rhamphoryncus> | yup |
21:24 | <@jerith> | The unit tests assert that this class, which I have tagged with this interface, implements the correct semantics. |
21:24 | < Namegduf> | I wonder if there's a way in Java to test "everything implementing this interface". |
21:24 | < Namegduf> | Separately, I mean. |
21:25 | < Rhamphoryncus> | Or at least the subset of the semantics you can easily test for |
21:25 | <@jerith> | The interface lets me reason about the semantics a class claims to implement in a useful way. |
21:25 | | * Namegduf wrote an abstract "InterfaceTest" and inherited it into "ImplTest", for each Implementation. |
21:25 | < Rhamphoryncus> | I think there's a tendency to only implement ad-hoc subsets of an interface |
21:26 | <@jerith> | Namegduf: I don't think there is. |
21:26 | < Namegduf> | Pity. |
21:26 | < Rhamphoryncus> | such as adding a .write() method so you can pass your object around as a file. Very little needs anything else |
21:27 | < Namegduf> | Go encourages very minimalistic interfaces for that reason. |
21:27 | < Namegduf> | One-method interfaces are common, Writer for write() and such. |
21:27 | <@jerith> | That's a useful sematic. |
21:27 | <@jerith> | *semantic |
21:28 | < Rhamphoryncus> | Or at another extreme there's python's __getitem__ and friends. The only thing the interface could assert is the method signature, not the behaviour |
21:28 | < Namegduf> | Yeah. |
21:28 | <@jerith> | Because it distinguishes between File.write() and AINovelAuthor.write(). |
21:28 | < Rhamphoryncus> | Namegduf: that just seems silly. It's not the interface you want, it's the lack of anything else |
21:29 | < Namegduf> | Hmm? |
21:29 | < Namegduf> | You need more than one method for an I/O interface/ |
21:29 | < Rhamphoryncus> | You declare your variables as being Writer type, which means you can't accidentally use another method |
21:29 | < Namegduf> | I guess. |
21:30 | < Namegduf> | I don't understand why you're declaring your variables that way, instead of receiving them that way through, say, a function parameter. |
21:31 | < Rhamphoryncus> | Declare the function argument as a Writer then |
21:31 | < Namegduf> | Right. |
21:31 | < Namegduf> | In which case, I'm not sure why a one-method interface for "thingToWriteTo" is a bad idea. |
21:32 | < Namegduf> | (Which is really what that interface is for) |
21:32 | <@jerith> | Or, using zope.interface, IWriter(something) which will raise an exception or give you an object implementing IWriter(). |
21:32 | < Rhamphoryncus> | it would be interesting to allow namespaces, ie iostuff::write, then make Writer a function that does an arbitrary test for compatibility |
21:33 | < Namegduf> | Hmm. |
21:33 | < Namegduf> | At runtime? |
21:33 | < Namegduf> | That'd fail static type checking |
21:33 | <@jerith> | If the object implements IWriter, it'll be returned. If there's an adapter to turn it into something that does, that will be returned. |
21:33 | < Rhamphoryncus> | Namegduf: funny that ;) |
21:33 | | Orthia [orthianz@Nightstar-fdc77178.xnet.co.nz] has quit [Client closed the connection] |
21:33 | < Namegduf> | That's kinda interesting. |
21:35 | < Rhamphoryncus> | I often argue that static typing has far more cost than people claim. It excludes all sorts of interesting options like that |
21:35 | < Namegduf> | I don't see how. |
21:36 | < Rhamphoryncus> | hmm? |
21:36 | < Namegduf> | Why can't "does type X implement interface I, or have an adapter for I" be resolved at compile time? |
21:36 | <@jerith> | Static typing can be more useful than costly if it's done the way something like Haskell does it. |
21:36 | < Namegduf> | (Indeed, the only difference between that and how Go works is that Go doesn't have 'adapters') |
21:36 | < Rhamphoryncus> | Namegduf: you can't make it an arbitrary function to do the check. The semantics have to be hardcoded into the typing system |
21:37 | <@jerith> | Adapters are *really* useful for interacting with third-party libraries. |
21:37 | < Rhamphoryncus> | jerith: that's pretty subjective |
21:38 | <@jerith> | Rhamphoryncus: In my experience, Haskell's type system provides more benefit than cost. |
21:38 | < Namegduf> | Rhamphoryncus: Or the function run during the compile |
21:38 | < Namegduf> | My opinion is "It is hard enough to validate that this string is formatted validly. I do not want to have to verify myself, and then dealing with *testing the manual verification*, that the code handles a number being fed in instead." |
21:39 | < Rhamphoryncus> | Namegduf: aye, although that'll lead to people deferring to a runtime check.. which is a better compromise IMO |
21:39 | <@jerith> | Java's type system, while being very costly, completely fails to provide the compile-time guarantees it promises. |
21:39 | < Namegduf> | Why would "running the function during compile" cause people to defer to a runtime check? |
21:39 | < Rhamphoryncus> | jerith: I tend to think of functional languages as incredibly costly. Their type systems require entire extra stages of analysis |
21:39 | < Namegduf> | (What you're basically describing seems to be a more complex typing system, but one checked at runtime for ome reason) |
21:40 | < Namegduf> | (My issue is "What is it doing at runtime that cannot be done at compile time?") |
21:40 | < Rhamphoryncus> | Namegduf: It wouldn't cause them to so much as probably allow |
21:40 | <@jerith> | Rhamphoryncus: I'm not counting machine-cycle cost. I'm counting headspace and flexibility cost. |
21:40 | < Rhamphoryncus> | Namegduf: ie your compile-time function sets up a hook for a run-time function |
21:41 | <@jerith> | Haskell's type system requires an upfront investment to grok, but is fine thereafter. |
21:41 | < Rhamphoryncus> | jerith: so am I |
21:41 | <@jerith> | For everything I've used, at least. |
21:41 | | Orthia [orthianz@Nightstar-fdc77178.xnet.co.nz] has joined #code |
21:41 | <@jerith> | Which is admittedly not all that extensive. |
21:41 | < Namegduf> | I'm fond of the compiler doing as much of the "testing" process for me as possible. |
21:41 | < Namegduf> | If it can statically prove that I'm never being fed a number where I'm expecting a string, then that's something I don't have to test or write code for. |
21:41 | <@jerith> | Namegduf: That doesn't provide enough of a benefit. |
21:42 | < Namegduf> | That's an opinion. |
21:42 | < Namegduf> | I disagree. |
21:42 | < Rhamphoryncus> | Namegduf: with static typing you just did write the code to test for it. It's just spread out |
21:42 | < Namegduf> | No I didn't. |
21:42 | <@jerith> | You still have to deal with getting null or the wrong kind of string or whatever. |
21:42 | < Namegduf> | I do, yes. |
21:43 | < Rhamphoryncus> | Actually, that's a good argument for runtime checker functions |
21:43 | < Namegduf> | I've however limited it to being a string of some kind, which I find makes the mental evaluation of "For any input, is this safe" |
21:43 | < Namegduf> | Much, much easier. |
21:43 | <@jerith> | And while you're doing that, you get to deal with juggling three different types because you're using libraries that do similar things in different ways. |
21:43 | < Rhamphoryncus> | They could ensure a string is properly formatted, not just that it is a string |
21:43 | < Namegduf> | Why would I be using three libraries doing similar things in different ways? |
21:43 | < Namegduf> | That's just terrible design. |
21:44 | <@jerith> | Because you're talking to different backends providing the same kind of service. |
21:44 | <@jerith> | Or you're reading from one and writing to the other. |
21:44 | <@jerith> | Or you're using both JPEGs and PNGs. |
21:44 | < Namegduf> | Additionally, you're assuming that each one provides their own types. |
21:44 | <@jerith> | Or whatever. |
21:44 | < Namegduf> | Which only seems realistic if they're throwing different data structures at me. |
21:45 | < Namegduf> | And if they're doing that, then it's not the type system forcing me to deal with "three different similar things". |
21:45 | <@jerith> | I've been bitten by that several times in the real world. |
21:45 | < Namegduf> | It's a part of the problem. |
21:45 | <@jerith> | Oh, the type system doesn't cause the problem. |
21:45 | <@jerith> | It just makes it much harder to deal with. |
21:45 | < Namegduf> | At any rate, I find the ability to effectively have "Works validly when fed every type except the expected one" mental reasoning *and* testing taken out of my concern. |
21:46 | < Namegduf> | Really, really worth it. |
21:46 | < Rhamphoryncus> | In my mind the type is just part of the value. Why should I have assertions of only one part of the value? |
21:46 | < Namegduf> | I'd love to have assertions about the *entire* value. |
21:47 | < Namegduf> | Type systems just can't do that (well) |
21:47 | < Rhamphoryncus> | I could imagine "assert Writer.check(f)"... |
21:47 | <@jerith> | In my experience, "accepts the right type" is often treated as "works for all input of the right type". |
21:48 | < Namegduf> | I would probably have read what you saw as that as "didn't bother doing validation at all" |
21:48 | < Namegduf> | Which tends to be true for bad code regardless of type systems |
21:48 | <@jerith> | Namegduf: As soon as you're dealing with assertions about semantics, there's no way other than comprehensive unit tests to prove correctness. |
21:49 | < Namegduf> | You know the meaning of "prove" better than to say that,a nd it's not a... semantic difference. |
21:49 | < Namegduf> | There's no better way than comphrensive unit tests to be as sure of correctness as you can be, yes. |
21:49 | <@jerith> | Sorry, I did misuse "prove" there. |
21:49 | < Namegduf> | I do basically agree. |
21:50 | < Namegduf> | In that unit testing is the only way to prove the semantics are right. |
21:50 | <@jerith> | And it is a semantic difference, because it depends on the semantics of what you're doing with the input. |
21:50 | <@jerith> | The reason you need to assert that this value is not zero is that you're about to divide by it. |
21:51 | <@jerith> | The reason you're asserting that this string has a particular form is that you want to treat it as a date. |
21:51 | < Namegduf> | I think you misunderstood when I said "it's not a semantic diffferent", I was meaning my point that testing is imperfect and it matters. |
21:51 | < Namegduf> | s/and it// |
21:51 | < Namegduf> | Not so much to this, anyway. |
21:52 | <@jerith> | Ah. |
21:52 | | * jerith isn't really tracking well enough at the moment to be coherent in this conversation. :-/ |
21:52 | < Namegduf> | I think we really only have one disagreement, and that is that I find "reduces the range of values I need to reason about" mentally helpful enough to be worth it, and you don't. |
21:53 | < Namegduf> | I just inhertently find it easier to reason about sets of strings than sets of strings, numbers, and arbitrary data structures. |
21:53 | <@jerith> | Oh, it's a useful thing to have. No doubt about that. |
21:53 | < Namegduf> | I find it easier to know that I can pass the should-be-a-string straight to "get length of string" in doing my validation without worrying about whether said function will throw up if it isn't a string. |
21:54 | <@jerith> | I think we're disagreeing on the magnitude of the cost more than the benefit. |
21:54 | < Namegduf> | That's a poor example, the answer is probably "it will" there, but when null enters the game, things get nastier for that. |
21:54 | < Namegduf> | (Which is always possible for strings in most languages, but not so for numbers) |
21:54 | < Namegduf> | That's possible too. |
21:55 | <@jerith> | Stupid Java Trick That Saves 2am Debugging: Always test STRING_CONSTANT.equals(stringVar), not the other way around. |
21:55 | < Namegduf> | I find types to fairly readily represent what I'm thinking when shuffling stuff around; "I'm expecting a string in date format from this, then I'm passing it to this", so marking it as a string doesn't hurt me much. |
21:55 | < Namegduf> | Oh, I hate that. |
21:56 | < Namegduf> | I'm actually conflicted on Java's type system. |
21:56 | <@jerith> | I think it succeeds admirably at its designed purpose. |
21:56 | < Namegduf> | They make it "safe". With lots of nasty cases. But it's really, really painful. |
21:57 | <@jerith> | Which is to allow large armies of mediocre programmers to build something that actually works. |
21:57 | < Namegduf> | Aha. So that's why industry loves it. |
21:57 | <@jerith> | Java's type system is not safe, because it lets you escape. |
21:57 | <@jerith> | Look at the reflection APIs. |
21:57 | < Namegduf> | Okay, that's true. |
21:57 | < Namegduf> | Although I opt not to. |
21:57 | < Namegduf> | :P |
21:57 | < Namegduf> | The heavy OO makes it worse because it leads to many, many types... and it stutters. |
21:58 | <@jerith> | They're horrible, horrible things that I'd almost rather switch to Ruby to avoid. |
21:58 | <@jerith> | (But not quite.) |
21:58 | < Namegduf> | I refuse to work in a language where 5.times() { } is an idiomatic looping construct. |
21:59 | < Namegduf> | It looks like a method call, but isn't. |
21:59 | <@jerith> | It is a method call. |
22:00 | < Namegduf> | ...okay, that's... better, but the syntax for the way it's somehow accepting the block as something makes me ill. |
22:00 | <@jerith> | times() is a method on Integer that accepts a block parameter and calls that block however many times it needs to. |
22:00 | <@jerith> | Block syntax is one of the things I occasionally want elsewhere. |
22:00 | < Namegduf> | My issue is that the OO knowledge I have kinda screams and tries to kill me when I see times() as a method of Integer |
22:00 | <@ToxicFrog> | Namegduf: this is just passing a lambda to a method on number. What's the problem here? |
22:01 | <@jerith> | If only because it's a better lambda than most languages have. |
22:01 | | * jerith glares at Python for this. |
22:01 | <@ToxicFrog> | I mean, apart from times being a method on integer ;.; |
22:01 | < Namegduf> | Primarily that it is neither mutating, nor operating on or "doing things with" a number. |
22:01 | < Namegduf> | And thus has no business being a method on one. |
22:01 | <@ToxicFrog> | Well, yes |
22:02 | <@jerith> | Oh, if you think that's bad... |
22:02 | < Namegduf> | The number is more of a modifier to the behaviour than anything else and would make more sense as times(5) |
22:02 | < Namegduf> | 1.upTo(10) disgusts me worse |
22:02 | <@jerith> | 3.days.after tomorrow |
22:02 | <@ToxicFrog> | I agree that's bad, but what you said you have a problem with is passing a block into it |
22:02 | < Namegduf> | Because 1 and 10 are *equal* in their impact. |
22:02 | < Namegduf> | But one is parameter and one isn't. |
22:02 | < Namegduf> | And it's argh. |
22:02 | <@ToxicFrog> | Which is one of the few parts of ruby I'd like to see elsewhere |
22:02 | <@jerith> | I *think* that's in the Ruby on Rails hackery. |
22:02 | <@ToxicFrog> | How do you figure? What if it curries? |
22:02 | < Namegduf> | Yeah, it is, jerith. |
22:03 | < Namegduf> | Wait, " tomorrow"? |
22:03 | < Namegduf> | That bit I missed. |
22:03 | <@jerith> | That's a variable. |
22:03 | < Namegduf> | I knew 3.days.ago |
22:03 | < Namegduf> | ToxicFrog: The part I don't like is that the only indication the block has anything to do with the function is that it's on the same line, I guess |
22:03 | <@jerith> | I'm probably inventing .after(), but it's entirely reasonable. |
22:04 | <@jerith> | Namegduf: If it were an explicit parameter? |
22:04 | < Namegduf> | It's a parameter, but it's outside the parens, and they've done nothing but make it look vaguely like a method definition. |
22:04 | <@ToxicFrog> | That's not how it's written anyways |
22:04 | <@ToxicFrog> | 5.times { code } |
22:04 | <@ToxicFrog> | Which (I hope and pray) is sugar for 5.times( {code} ) |
22:05 | < Namegduf> | Parens resolve that. |
22:05 | <@jerith> | Blocks aren't really syntactic sugar, because the scoping is /weird/, but you can think of them as such and be okay most of the time. |
22:05 | < Namegduf> | So my issue then is just the "why the hell is this a method on an immutable" |
22:05 | < Namegduf> | I dislike "foo".something(), but am willing to tolerate it as necessary syntactical stuff to avoid a String.foo("something" |
22:05 | < Namegduf> | Er, String.something("foo", |
22:06 | <@ToxicFrog> | Because it's Ruby, which is like Perl only worse. |
22:06 | < Namegduf> | But 5.times is just... doing it on *purpose* |
22:06 | < Namegduf> | For no reason |
22:06 | < Namegduf> | Then calling it idiomatic |
22:06 | < Namegduf> | Which is very Perl. |
22:06 | <@jerith> | def myblock(param); somecode; end; 5.times(&myblock) <=> 5.times { |param| somecode } |
22:06 | <@jerith> | I may be wrong on the &, though. |
22:07 | <@jerith> | That might only be for defining a method that takes a block parameter. |
22:07 | < Namegduf> | Anyways, my big issue with Java is the ridiculous type names, which I like namespacing for improving. |
22:09 | < Namegduf> | I also wish it had just a *taste* of type inference. |
22:09 | < Namegduf> | foo := new SomeStupidLongType(); as shorthand for |
22:09 | < Namegduf> | SomeStupidLongType foo = new SomeStupidLongType(); |
22:09 | < Namegduf> | Would have made things so much less ugly on its own. |
22:10 | <@jerith> | But then you wouldn't get Map<String, Foo> myMap = new HashMap<String, Foo>(); |
22:10 | < Namegduf> | You could |
22:10 | < Namegduf> | A) Do that anyway |
22:10 | <@jerith> | And how would it know which of the myriad superclasses or interfaces you wanted to treat it as? |
22:11 | < Namegduf> | B) Why the hell are you using methods long enough that you really really need to take panes to make sure you're using variables right? |
22:11 | < Namegduf> | Er... |
22:11 | < Namegduf> | You know that you can pass SubClass as SuperClass in Java without casting, right? |
22:11 | < Namegduf> | It knows which to treat it as by the type of parameter the function is expecting |
22:11 | <@jerith> | Yes. |
22:11 | | Attilla [Attilla@FBC920.482E2D.971EED.6317D6] has quit [Ping timeout: 121 seconds] |
22:11 | < Namegduf> | Interfaces are similar. |
22:11 | <@jerith> | But you want to explicitly disallow stuff that only SubClass has. |
22:11 | < Namegduf> | *take pains |
22:12 | < Namegduf> | Why? |
22:12 | < Namegduf> | This is the allocation point. |
22:12 | < Namegduf> | If you're doing stuff with stuff it only has, it's like 10 lines from where you allocated it |
22:12 | < Namegduf> | If you change what type it is, you can change that at the same time |
22:12 | <@jerith> | Because hey, let's make everything private and final to screw over the person who really wants to tweak the behaviour of one method in his own code. |
22:13 | < Namegduf> | By the time it gets out of the method, it's been cast to whatever you want it to be. |
22:13 | < Namegduf> | If your method is a hundred or more lines long, it's an uglyass method, and any troubles with using things appropriately should probably be taken care of by fixing tha.t |
22:14 | < Namegduf> | If it's a proper length method, then altering its implementation when you change its local variables shouldn't be hard, nor should using them as you're intending to. |
22:14 | < Namegduf> | But if you really must have a type cast to another type on creation, then you could always specify it explicitly. |
22:15 | <@jerith> | If I see anyone using 'private' or 'final' in any Java code that I'll have to touch, they'd better give me a bloody good reason or the cricket bat comes out. |
22:15 | < Namegduf> | You're not fond of private? |
22:15 | <@jerith> | Not in the slightest. |
22:15 | < Namegduf> | (Final I can understand, it's like a bit... "no, you can't extend this") |
22:16 | < Namegduf> | *big |
22:16 | <@jerith> | Correct. |
22:16 | | Orthia [orthianz@Nightstar-fdc77178.xnet.co.nz] has quit [Client closed the connection] |
22:16 | <@jerith> | Except sometimes it means something else. |
22:16 | < Namegduf> | Oh yes. |
22:16 | < Namegduf> | Because few words > clear meaning of a single word |
22:17 | <@jerith> | I think it means "this is immutable" in method params or something. |
22:17 | < Namegduf> | Variable declaration in general |
22:17 | < Namegduf> | Yeah. |
22:17 | < Namegduf> | (Noting that for member variables, immutable means "can't be altered after the constructor") |
22:17 | <@jerith> | I haven't been able to think of a single good reason to use "final" classes. |
22:18 | <@TheWatcher> | Because *handwave* OO! |
22:18 | <@TheWatcher> | ~ |
22:18 | < Namegduf> | I used final methods in my test code because I very explicitly did want to say "No, you're not allowed to alter the implementation of the methods testing it meets the interface, in your subclass to test a specific implementation" |
22:19 | < Namegduf> | But that was a specialish kind of case that can probably be done another way better. |
22:20 | <@jerith> | There are some specific performance-related uses of final classes that (a) almost certainly no longer apply and (b) if you actually understand what they are, should be adding bytecode hacks to get the same effect rather than using a keyword. |
22:21 | < Namegduf> | Ah. |
22:21 | | Attilla [Attilla@FBC920.3488E2.03ED7E.3EC87F] has joined #code |
22:21 | | mode/#code [+o Attilla] by Reiver |
22:22 | < Namegduf> | I guess my real issue with some OO kinda stems from that. |
22:22 | <@jerith> | In practice, 'final class Whatever' means "I'm an arrogant fucktard who is well enough hidden that the people using my code can't hunt me down and feed me my own spleen". |
22:22 | < Namegduf> | Haha. |
22:24 | | * Rhamphoryncus undistracts himself |
22:24 | <@jerith> | Are we the distraction or the thing you were distracted from? |
22:25 | < Rhamphoryncus> | I find Java's Runnable is reason enough to burn the language |
22:25 | < Rhamphoryncus> | Thing you were distracted from ;) |
22:25 | | Derakon [Derakon@Nightstar-1ffd02e6.ucsf.edu] has joined #code |
22:25 | | mode/#code [+o Derakon] by Reiver |
22:25 | <@jerith> | No, the thing I was distracted from was the months-overdue documentation I was supposed to write. |
22:25 | < Namegduf> | I find the idea of passing objects in place of function (pointers), always, disturbing. |
22:25 | < Namegduf> | The thing I'm being distracted from is actually writing Java. |
22:26 | < Namegduf> | I'm having trouble mustering care. |
22:26 | <@Derakon> | What's wrong with passing (references to) objects around? |
22:26 | < Namegduf> | The boilerplate of doing it in place of passing *any* reference to a function. |
22:26 | <@Derakon> | (The thing I'm being distracted from is figuring out what to do after spending most of the day debugging a faulty camera) |
22:26 | < Namegduf> | Rhamphoryncus mentioned Runnabe. |
22:26 | < Namegduf> | *Runnable |
22:26 | < Rhamphoryncus> | And the thing about lambda in python is there's very few problems it's GOOD at solving. This goes for a hypothetical less sucky function-expression syntax. Most complaints are just "well, I was doing my 387 character reduce one-liner and..." |
22:26 | < Namegduf> | I wonder if I can avoid it by only having one method passed per object |
22:27 | < Namegduf> | And always making it a public run() method |
22:27 | < Rhamphoryncus> | Namegduf: I find it disturbing that a function is not an object |
22:27 | < Namegduf> | And having it pass "this" |
22:27 | < Namegduf> | :D |
22:27 | < Namegduf> | Rhamphoryncus: Ah. |
22:27 | <@Derakon> | Rhamph: how about registerEvent(ONCLICK, lambda event: pass) |
22:28 | <@Derakon> | I've seen it happen! |
22:28 | <@Derakon> | Well, not for oncilck, but onpaint or other similar mandatory events that the user doesn't want to do anything about. |
22:28 | <@jerith> | Rhamphoryncus: I write Python in a somewhat functional idiom at times. |
22:28 | < Rhamphoryncus> | Derakon: yeah, that can be, but only for trivial cases |
22:28 | < Rhamphoryncus> | jerith: stop that, you'll blow the stack ;) |
22:28 | <@Derakon> | Heh. |
22:28 | <@jerith> | And it takes me three lines to define a function and pass it rather than one line if there was a good lambda syntax. |
22:29 | <@ToxicFrog> | Re: python lambdas: IMO the main problem with them is that they're expressions, not true anonymous functions |
22:29 | <@Derakon> | Conciseness is not inherently a virtue to the Python devs. |
22:29 | <@jerith> | Even Erlang's lambda syntax is clunky. |
22:29 | <@jerith> | It isn't the brevity I'm concerned about, it's clarity of intent. |
22:29 | < Rhamphoryncus> | I was actually thinking about how to add ruby-ish blocks to python. They'd work good for registerEvent and such. Wouldn't work at all for dispatch dicts though |
22:30 | < Rhamphoryncus> | ToxicFrog: being anonymous isn't considered a virtue either. Naming helps stacktraces |
22:30 | <@jerith> | I find map(lambda x: 2*x, my_list) to be far clearer than spending two lines defining a doubler and then passing that to map(). |
22:30 | <@ToxicFrog> | 4: in <lambda defined at filename:23>: |
22:31 | <@Derakon> | Jerith: [i * 2 for i in my_list] |
22:31 | < Rhamphoryncus> | jerith: [x*2 for x in my_list] |
22:31 | <@ToxicFrog> | Also, what jerith said. |
22:31 | <@jerith> | Yeah, yeah, I use comprehensions all the time. |
22:32 | <@jerith> | map() and a doubler are just things that are easy to type and explain. :-) |
22:32 | <@Derakon> | map() can be wholly replaced by list comprehensions, I'm pretty certain. |
22:32 | <@jerith> | Not entirely. |
22:32 | <@jerith> | It's sometimes useful to pass it to other functions. |
22:33 | <@jerith> | For the same reason the operator module exists. |
22:33 | <@ToxicFrog> | <3 higher-order functions |
22:33 | < Namegduf> | I 90% agree. |
22:33 | <@jerith> | <3 with lots of <3. |
22:33 | <@Derakon> | Pass map() itself to other functions? |
22:33 | < Namegduf> | The other 10% is based on some quite terrifying JavaScript. |
22:33 | <@jerith> | Sure. |
22:33 | <@Derakon> | Or pass map(lambda) as a curried function? |
22:33 | <@jerith> | That too. |
22:34 | <@jerith> | functools ftw. |
22:34 | <@Derakon> | Hmm...functools.partial does currying? |
22:35 | <@jerith> | Yes. |
22:35 | <@Derakon> | Awesome. |
22:35 | < Rhamphoryncus> | lambda my_list: [func(x) for x in my_list] |
22:36 | <@jerith> | I use functools.wraps() a lot. |
22:38 | | * Derakon eyes the functools.wraps example. |
22:38 | <@Derakon> | At http://docs.python.org/library/functools.html |
22:38 | <@Derakon> | What does "@wraps(f)" mean? |
22:38 | <@Derakon> | I'm not familiar with that syntax. |
22:39 | < Rhamphoryncus> | that's a decorator |
22:39 | <@jerith> | Decorators are syntactic sugar. |
22:39 | < Rhamphoryncus> | basically func = wraps(f)(func) |
22:40 | <@Derakon> | Err... |
22:41 | <@jerith> | Do you grok decorators? |
22:41 | | Searh [Z@26ECB6.A4B64C.298B52.D80DA0] has joined #code |
22:41 | <@Derakon> | I'm currently reading up on them. |
22:41 | <@jerith> | The general idea is that you're "doing something" to a function. |
22:41 | | Netsplit *.net <-> *.split quits: Namegduf, @Attilla, Serah, SmithKurosaki, @McMartin, Tarinaky, @Derakon[AFK], PinkFreud |
22:43 | <@Derakon> | ...bizarre. |
22:44 | | McMartin [mcmartin@Nightstar-3c130f1a.pltn13.sbcglobal.net] has joined #code |
22:44 | | mode/#code [+o McMartin] by Reiver |
22:44 | | Namegduf [namegduf@Nightstar-5c10d129.beshir.org] has joined #code |
22:45 | | Tarinaky [Tarinaky@Nightstar-83f5e5c6.adsl.virginmedia.net] has joined #code |
22:45 | | PinkFreud [WhyNot@NetworkAdministrator.Nightstar.Net] has joined #code |
22:46 | | SmithKurosaki [Smith@Nightstar-85fffd27.dsl.teksavvy.com] has joined #code |
22:46 | <@Derakon> | It seems like decoration should entail its own indentation level, somehow. |
22:46 | <@Derakon> | The fact that putting @foo on a line prior to the line defining a function changes what happens when you call that funciton seems off. |
22:46 | < Namegduf> | Dear god, not more indentation levels. |
22:46 | <@Derakon> | :p |
22:46 | < Namegduf> | You realise Java has two, before the code even starts? |
22:47 | < Namegduf> | Because everything is in a method in a class? |
22:47 | <@Derakon> | Yes, and Python does as well for non-static functions. |
22:47 | < Namegduf> | We can't take anymore. |
22:47 | <@Derakon> | You can't take any more. |
22:47 | < Namegduf> | I don't have a 21" monitor dedicated solely to representing indentation levels. |
22:48 | < Namegduf> | :P |
22:48 | < Rhamphoryncus> | Derakon: putting it inside the function, at the indentation of the code, was deemed too subtle |
22:48 | <@Derakon> | I do my programming on a 12" laptop. |
22:48 | <@Derakon> | Rhamph: I can see that...ehh. |
22:48 | <@Derakon> | Still seems weird. |
22:49 | | Attilla [Attilla@FBC920.3488E2.03ED7E.3EC87F] has joined #code |
22:49 | | mode/#code [+o Attilla] by Reiver |
22:49 | < Rhamphoryncus> | It is kinda. Not a normal way of doing it.. but there is no normal way of doing it |
22:49 | <@Derakon> | Well, I've learned something about Python now. |
22:50 | < Rhamphoryncus> | It's funny that the PEP's example of @synchronized(lock) is completely trumped by the with-statement |
22:50 | <@Derakon> | I guess that, not knowing about this before, I would have implemented the same functionality by explicitly calling a function that did the before- and after-logic, and handing it the function it needs to call. Basically identical to what decorators actually do, just explicit. |
22:50 | < Rhamphoryncus> | You mean each time you call it? |
22:51 | <@Derakon> | Instead of having |
22:51 | <@Derakon> | @sanityCheck |
22:51 | <@Derakon> | def foo(): |
22:51 | <@Derakon> | blah |
22:51 | <@Derakon> | I'd have: |
22:51 | <@Derakon> | def sanityCheck(func): |
22:51 | <@Derakon> | ... |
22:51 | <@Derakon> | func() |
22:51 | <@Derakon> | ... |
22:51 | <@Derakon> | sanityCheck(foo) |
22:51 | <@Derakon> | (also, apparently I'd use three-space indents?) |
22:52 | <@Derakon> | Er, insert a "foo()" line after the definition of foo. |
22:52 | <@Derakon> | You get what I mean. |
22:52 | < Rhamphoryncus> | That's not a 1:1 comparison though |
22:52 | <@Derakon> | Basically all that changes is that instead of just calling foo directly, I'd call sanityCheck(foo). |
22:52 | < Rhamphoryncus> | hrm |
22:53 | < Rhamphoryncus> | Okay, it technically is the same, but it's not what the primary intent is |
22:53 | < Rhamphoryncus> | The intent is for stuff like this: |
22:53 | < Rhamphoryncus> | def foo(): |
22:53 | < Rhamphoryncus> | ... |
22:53 | < Rhamphoryncus> | foo = staticmethod(foo) |
22:54 | | * Derakon looks up staticmethod. "Ahh, didn't know about that one." |
22:54 | < Rhamphoryncus> | This repeats the function's name 3 times and hides an important part of the function after the function body |
22:57 | | AnnoDomini [annodomini@Nightstar-ef91445b.adsl.tpnet.pl] has quit [[NS] Quit: DEATH.] |
22:58 | < Rhamphoryncus> | o.O ewwww. A couple people provided functions that let you do decorate(staticmethod) before the function, no new syntax at all, and they used diagnostic hooks to modify the definition that came next... |
22:58 | <@jerith> | ... |
22:58 | <@Derakon> | Fun. |
22:59 | | * jerith looks around frantically for a bucket to vomit into. |
23:02 | < Rhamphoryncus> | So yeah, the summary is that it was worth doing and that was the best approach they found |
23:16 | | Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has joined #code |
23:27 | | RichardBarrell [mycatverbs@Nightstar-58acb782.cable.virginmedia.com] has joined #code |
23:42 | <@McMartin> | Wow, scrollback. |
23:44 | | cpux [Moo@Nightstar-20a84089.dyn.optonline.net] has joined #code |
23:49 | | Netsplit *.net <-> *.split quits: PinkFreud |
23:50 | | Netsplit over, joins: PinkFreud |
23:53 | <@McMartin> | Haskell's type system is one of those things like currying that spoils you forever |
23:53 | | * McMartin is also firmly on the static analysis side of things. There's no such thing as truly comprehensive test coverage. |
23:57 | <@McMartin> | I could never use Ruby because 90% of its documentation was asserting that its worse-than-Perl syntax was wonderful and awesome and so intuitive that explanations were superfluous |
23:57 | <@Derakon> | Self-documenting language design? |
23:57 | <@McMartin> | final is messed up and fails at everything. It wasn't fully thought out, but then, neither was const. |
--- Log closed Fri Apr 16 00:00:44 2010 |