--- Log opened Sat Apr 17 00:00:00 2010 |
--- Day changed Sat Apr 17 2010 |
00:00 | < Namegduf> | Convenient for patchsets, you can get something designed specifically for patchsets on hg, but it's an extension I don't know how to use. |
00:00 | <@ToxicFrog> | As far as I recall, msysgit comes with its own git install, but I'm not sure because I just use git from cygwin. |
00:00 | <@jerith> | It does all the usual VCS stuff, and it does it well, but everything's coloured by its design philosophy of "make it possible to manage eleventy bajillion branches". |
00:00 | < Namegduf> | I've never found anything that felt coloured in that way. |
00:00 | <@jerith> | Namegduf: Rebase is a fantastic operation. |
00:00 | <@ToxicFrog> | I am given to understand that as far as graphical tools go, TortoiseGit and SmartGit are both very good, but I believe they both rely on msysgit. |
00:00 | <@ToxicFrog> | git rebase -i <3 |
00:00 | <@McMartin> | Hm. Tortoise tends to add Pageantry. |
00:01 | <@jerith> | Namegduf: Probably because you didn't come from one of the other tools. You're coloured by it as well. :-) |
00:01 | | * ToxicFrog used that to solve a problem where he accidentally committed thirty commits worth of copyright infringement~ |
00:01 | < Namegduf> | jerith: Or, alternatively, not coloured by expectations of the UI. |
00:01 | <@jerith> | Namegduf: Which is a different way of saying the same thing, more or less. |
00:02 | <@ToxicFrog> | The general impression I get on git vs hg is that git is more flexible and has more features, but hg is more polished and much better structured internally. |
00:02 | < Namegduf> | Mercurial polish for me is ruined by hg backout |
00:02 | <@ToxicFrog> | hg backout? |
00:02 | < Namegduf> | Reverting someone else's change. |
00:03 | <@ToxicFrog> | How does it differ from git revert? |
00:03 | < Namegduf> | It involves two commits, one of which is a merge you best *pray* goes smoothly in history. |
00:03 | < Namegduf> | Except... Merc's merging feels stupider, and I've had it fail on me a lot. |
00:03 | <@jerith> | This is where I adore darcs. |
00:03 | < Namegduf> | ToxicFrog: Basically, it creates a new head based on the change being reverted, and a reverse patch. Then you do a manual merge. |
00:03 | <@jerith> | It has a lot of warts and horrid UI decisions, but it's mathematics made concrete. |
00:04 | <@ToxicFrog> | o.O |
00:04 | <@jerith> | Patch calculus for the win. |
00:04 | <@ToxicFrog> | Why does that require a merge? Why can't it just record a new commit? |
00:04 | < Namegduf> | Because the reverse patch on the original change might not apply to the current source perfectly |
00:05 | <@ToxicFrog> | ...right, but to me that doesn't imply a merge, it just implies that you need to edit before you commit. It's not combining two different changesets. |
00:05 | <@jerith> | ToxicFrog: You're wanting to revert commit N-3, but not N-2. |
00:05 | <@ToxicFrog> | Yes. |
00:05 | <@ToxicFrog> | That's what git revert does, too. |
00:05 | < Namegduf> | ToxicFrog: Then it's because it's stupid in the approach it uses. |
00:05 | <@jerith> | If N-2 depends on stuff in N-3, spiders and woe ensue. |
00:06 | < Namegduf> | What you're describing is what git revert does; what it does is revert it and then do the merge in a separate step to merge the two new heads. |
00:06 | <@McMartin> | As it turns out, MSYSGit can be connected to Pageant. |
00:06 | < Namegduf> | I consider this, as part of something people like to call "more polished", unacceptable |
00:06 | < Namegduf> | McMartin: Whoo! |
00:06 | < Namegduf> | Well, no, I say unacceptable, I'm being too dramatic. |
00:06 | < Namegduf> | I mean "bad". |
00:06 | < Namegduf> | I still use it. |
00:06 | <@McMartin> | So, the next question is whether it will accept my version of MSYS/MinGW, or if it will insist on its own. |
00:07 | <@ToxicFrog> | What is Pageant? |
00:07 | <@McMartin> | Pageant is the SSH key manager that I use. |
00:07 | <@McMartin> | It's part of PuTTY's full distribution. |
00:07 | <@jerith> | ToxicFrog: ssh-agent for PuTTY. |
00:07 | <@ToxicFrog> | Aah. |
00:08 | < Namegduf> | jerith: Anyways, my view is basically that no one has managed to highlight a single part of the UI which is clearly focused around branching more in git than SVN in a way that isn't just "It's different", and I don't agree that the different idea of what the word "revert" is referring to the reverting of to qualify. |
00:09 | | You're now known as TheWatcher[T-2] |
00:11 | < Namegduf> | It has a different focus, but it seems a clean superset, and the branching functions feel orthagonal in a similar manner, except that they actually are useful. |
00:11 | | You're now known as TheWatcher[zZzZ] |
00:11 | < Namegduf> | (Okay, more usable. :P) |
00:11 | | Derakon [Derakon@Nightstar-5abd3ac9.ca.comcast.net] has joined #code |
00:11 | | mode/#code [+o Derakon] by Reiver |
00:11 | <@jerith> | Namegduf: It's lots of trivial things, which all add up to "this isn't comfortable". |
00:12 | < Namegduf> | Comfort seems to me to be more related to familiarity than "better" interface in general. |
00:12 | <@jerith> | Oh, absolutely. |
00:14 | <@jerith> | But "familiarity" comes from using tools designed to do something different from what git was designed to do. |
00:14 | <@Derakon> | Use Mercurial instead~ |
00:14 | < Namegduf> | I guess. |
00:15 | | * Namegduf secretly just aliases hg to a thin wrapper on git and hopes no one notices |
00:15 | <@Derakon> | Heh. |
00:16 | <@jerith> | Modern VCS tools are probably closer to "branch management" than "linear file versioning", but there's a lot of history that won't just disappear. |
00:16 | < Namegduf> | I use both, because different stuff I use uses different ones upstream. |
00:16 | <@jerith> | The really fantastic thing about git? The "porcelain" can be swapped out independently of the backend. |
00:17 | < Namegduf> | I don't use SVN or CVS or similar regularly simply because I either need a quick and lazy repo here for a tiny project, or a need a workflow they can't do. |
00:17 | <@jerith> | Don't like the UI? Replace it with a different one. |
00:17 | < Namegduf> | Sure, git's architecturally interesting, but I've never had to... okay, I lie. |
00:17 | < Namegduf> | I had to look at below-the-normal-level git commands once: |
00:17 | < Namegduf> | When restricting SSH keys to only be able to pull/push to a repo. |
00:18 | < Namegduf> | I had to get the command it internally executed for each and allow it. |
00:18 | < Namegduf> | I had to do something similar for Merc and I suspect SVN would require a similar lookup. |
00:18 | <@jerith> | Except the only one that is currently useful is the standard one, because it's the one the Linux kernel guys (who are the git developers) care about. |
00:19 | <@ToxicFrog> | Namegduf: or you could just use Gitosis. |
00:20 | < Namegduf> | I suppose I could, but it's a private repo and the SSH keys were already doing other things. |
00:20 | <@jerith> | You may have noticed that all the repo translation tools are based on the git import/export stuff. |
00:21 | <@jerith> | This is not coincidental. |
00:21 | < Namegduf> | I don't think I looked inside them too much. |
00:21 | <@ToxicFrog> | What do you mean by "already doing other things"? |
00:21 | < Namegduf> | Doesn't surprise me, though. |
00:22 | <@ToxicFrog> | (the idea with gitosis is: key file for each user, config file dictating what repos each user can access and what they can do to them. They log in as "git" with their keypair and it constrains them to only the operations you permitted in the config file.) |
00:22 | < Namegduf> | The keys are used for DB synchronisation and automatic SSH tunnels. |
00:22 | < Namegduf> | (Which are a hack around the lack of SSL for some stuff) |
00:23 | < Namegduf> | Well, not hack, but architectual complexity. |
00:23 | <@jerith> | Personally, I think git is by far the best of the available revision control systems. I just haven't put in the time to learn it properly because (a) I've never needed to and (b) launchpad is an *incredibly* compelling reason to use bzr. |
00:25 | < Namegduf> | I like git the most, found svn clunky the little I've had to use it, Mercurial "okay" and nearly identical to git with some random command changes and some things not available easily, and have never looked at CVS, BZR, or DARCS because no project I've looked at used them. |
00:25 | < Namegduf> | Of them, I have an ew impression of CVS just by word of mouth that I consider sufficiently backed up to not care about much; at a certain level, "it's the old one" justifies not caring about it when everyone else seems to agree it's pretty unredeemable. |
00:26 | <@jerith> | darcs will never be mainstream. |
00:26 | <@jerith> | CVS is antiquated and must go somewhere to die quietly. |
00:26 | <@ToxicFrog> | Namegduf: spot on re: CVS; SVN is an improvement over it in every way. |
00:26 | <@ToxicFrog> | And SVN is pretty bad. |
00:26 | <@jerith> | svn was written specifically as CVS, only better. |
00:26 | < Namegduf> | Yeah. |
00:27 | < Namegduf> | I remember. |
00:27 | <@McMartin> | CVS did go somewhere to die quietly. It's called "SVN"~ |
00:28 | <@McMartin> | Likewise, RCS and SCCS went somewhere to die quietly and it was called "CVS". |
00:28 | <@jerith> | It's suceeded a little too well, because its focus on easing the migration from CVS has limited its flexibility and kept it in the iron age. |
00:29 | < Namegduf> | Git people seem to think that SVN was a fundamentally bad approach, because there's was no such thing as "CVS Done Right". |
00:29 | < Namegduf> | But that can readily be answered by "For your usecase" and isn't something I particularly share. |
00:30 | < Namegduf> | I find it an amusing piece of commentary from the time, though. |
00:30 | <@jerith> | git was a complete rethink of what such a tool needed to do, and it incorporated only what it thought was good and useful. |
00:30 | <@jerith> | CVS (and, by extension, svn) are built on some truly abysmal premises. |
00:31 | <@jerith> | But these make a lot more sense given the history. |
00:31 | < Namegduf> | Or even, from what I recall, a very simple, linear and centralised development model. |
00:31 | <@jerith> | IIRC, RCS versioned individual files. Separately. |
00:32 | < Namegduf> | Sounds like what someone mentioned last time I heard of it. |
00:32 | < Namegduf> | But that was probably here. |
00:32 | <@jerith> | SCCS was a hack around it to try connect RCS-managed files into some greater whole. |
00:33 | <@McMartin> | Yeah. |
00:33 | <@jerith> | Both of these were built on the assumption that the files belonged to one person, who was the only one who touched them. |
00:33 | <@McMartin> | CVS then extended it so that you only checked out the files during a commit. |
00:33 | <@McMartin> | CVS was originally a wrapper around them that did checkout-apply changes-check in as a single move. |
00:33 | < Namegduf> | Wow. |
00:34 | <@McMartin> | Like I said |
00:34 | <@McMartin> | Though more obliquely before |
00:34 | <@McMartin> | As bad as RCS are now, they're all enormous improvements |
00:34 | <@McMartin> | The reason I want to learn git or Hg is so that I can properly join the 21st century (svn was juuuust at the end of the 20th) |
00:34 | < Namegduf> | My only real issue with git is "Can you make the merging even *more* psychic?" |
00:35 | < Namegduf> | Mercurial, more like "Can you steal git's approach to merging?" |
00:35 | <@jerith> | It should be noted that we're all ignoring the commercial tools. This is because they're unavailable in general. |
00:35 | < Namegduf> | Haha. |
00:35 | < Namegduf> | Are any of them relevant? |
00:35 | <@jerith> | Perforce does some cool stuff. |
00:35 | <@Derakon> | I used Perforce awhile back. |
00:35 | <@Derakon> | But I never tried to do anything particularly complicated with it. |
00:35 | <@McMartin> | ClearCase is popular at some companies. |
00:36 | <@jerith> | It's even more glued to the central server than svn is, though. |
00:36 | < Namegduf> | Ah. |
00:36 | <@McMartin> | (We use SVN here and are considering shifting to a Proper DVCS of some kind; part of my motivation here is to learn the basics of the tech before I have to for my job) |
00:36 | <@jerith> | MSVSS is a VCS only because it's marketed as one. |
00:37 | < Namegduf> | Haha. |
00:37 | < Namegduf> | I've heard of VSS, and heard people swearing at it. |
00:37 | < Namegduf> | I hope never to work with it. |
00:39 | <@jerith> | I've used it, and I am not exaggerating the tiniest amount when I say that it's a worse solution in every way than "old_code.zip, new_code.zip, new_code_from_bob.zip, code_yesterday.zip, probably_last_week_but_with_a_cool_feature.zip" and such. |
00:40 | < Namegduf> | Haha. |
00:40 | < Namegduf> | Wow. |
00:40 | < Namegduf> | That's bad. |
00:40 | <@jerith> | The latter is less likely to be completely trashed by db corruption, probably has semi-useful timestamps /somewhere/, can be extracted and diffed using actual tools, doesn't let someone hard-lock a file and the go on holiday, etc. etc. etc. |
00:41 | <@jerith> | Oh, perforce has my favourite VCS operation name of all time. |
00:41 | <@ToxicFrog> | Perforce is ok, but as far as concepts go it is, based on my experience, very much SVN Only Better |
00:42 | <@ToxicFrog> | I tend to use p4git to talk to it at work~ |
00:42 | <@jerith> | You can remove a branch or something completely and irrevocably with "obliterate". |
00:42 | < Namegduf> | Haha. |
00:43 | <@jerith> | I should have been asleep three hours ago. |
00:44 | <@jerith> | I need to be awake for the beer festival "tomorrow". |
00:44 | < Namegduf> | Have fun. |
00:45 | <@jerith> | I've greatly enjoyed this discussion. I hope you found it as useful as I found it entertaining. :-) |
00:45 | <@jerith> | G'night all. |
00:45 | < Namegduf> | I did. |
00:45 | < Namegduf> | Sleep well. |
00:57 | <@McMartin> | I do have a soft spot for "cvs blame" |
00:57 | <@McMartin> | And am amused that not only did svn keep it, it also allows "praise" as a synonym~ |
00:58 | <@McMartin> | (both are synonyms for "annotate" - showing which checkin/dev is responsible for each line) |
00:58 | < Namegduf> | XD |
01:28 | <@McMartin> | OK, here we go. http://git-scm.com/course/svn.html |
01:28 | <@McMartin> | AKA "I haven't paid attention to VCS systems for ten years, how I mine for repos" |
01:34 | <@McMartin> | Aha |
01:35 | <@McMartin> | It would appear that the equivalent to "svn revert" is in fact "git checkout" |
01:35 | <@McMartin> | That's just spiteful. =P |
01:35 | <@Derakon> | Um... |
01:35 | <@Derakon> | It really depends on what you mean by "revert". |
01:35 | <@Derakon> | At least with Mercurial, "revert" means "revert to the last version at the local repo". |
01:35 | <@McMartin> | Derakon: "checkout" is another svn command, that means something else different. |
01:36 | <@Derakon> | Yes, I got that. |
01:36 | <@McMartin> | You missed the part before about how git revert meant something other than svn revert, and this was annoying. |
01:37 | <@McMartin> | I'm marveling at how the verb git uses to resolve this collision produces another one |
01:37 | <@Derakon> | Ahh. |
01:42 | | Attilla [Attilla@FBC920.3488E2.03ED7E.3EC87F] has quit [Client closed the connection] |
01:44 | | AnnoDomini [annodomini@Nightstar-6be0f4b4.adsl.tpnet.pl] has quit [[NS] Quit: Way past my bedtime.] |
02:23 | | Derakon is now known as Derakon[AFK] |
03:12 | | Orth [orthianz@Nightstar-78fe5c6e.xnet.co.nz] has joined #code |
03:13 | | Orthia [orthianz@Nightstar-7de495fb.xnet.co.nz] has quit [Ping timeout: 121 seconds] |
03:19 | | gnolam [lenin@Nightstar-38637aa0.priv.bahnhof.se] has quit [[NS] Quit: Z?] |
03:29 | | Serah [Z@26ECB6.A4B64C.298B52.D80DA0] has quit [Ping timeout: 121 seconds] |
04:00 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has joined #code |
04:09 | <@Kazriko> | Checkout means download a remote repository. Revert means replace the local version of the file with the last version you checked out from the remote repository. |
04:10 | <@Kazriko> | Update of course means to resync your local copy to the remote server for an already checked out repository. |
04:21 | <@McMartin> | Kazriko: Every single one of those is false in Git~ |
04:21 | <@McMartin> | That said, it turns out Git integrates the best with the development system whose source and products I'm actually trying to version control, so it now wins. |
04:48 | | cpux [Moo@Nightstar-20a84089.dyn.optonline.net] has quit [Client closed the connection] |
04:50 | | cpux [Moo@Nightstar-20a84089.dyn.optonline.net] has joined #code |
05:09 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has quit [Ping timeout: 121 seconds] |
05:37 | < Tarinaky> | <McMartin> Kazriko: Every single one of those is false in Git~ << That's mostly because git automatically forks. |
05:38 | < Tarinaky> | So 'checkout' simply doesn't mean what it used to in the metaphor anyway. |
05:38 | < Tarinaky> | At least, that's what I was told. |
05:38 | < Tarinaky> | I have no idea what half the buttons do. I just push them and hope it does what I want. |
05:38 | < Tarinaky> | Not the best system >.> |
05:40 | <@McMartin> | Checkout is vaguely sensible |
05:40 | <@McMartin> | As a distributed VCS, everyone has their own repo |
05:40 | <@McMartin> | checkout in git means to checkout from your own, local repo. |
05:41 | <@McMartin> | It thus also does double duty with svn switch. |
05:41 | <@McMartin> | Because switch and revert have suddenly become roughly equivalent operations |
05:41 | < Tarinaky> | Yeah, exactly what I was trying to say :x |
05:42 | < Tarinaky> | Automatically forks wrt 'pull'. |
05:42 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has left #code [] |
05:43 | <@McMartin> | Yeah, I'm still wrapping my head around that part |
05:43 | <@McMartin> | Especially since I'm trying to synthesize a workflow similar to the SVN Master Repo with clients working alone |
05:43 | <@McMartin> | Or maybe sharing and having better local data |
05:43 | < Tarinaky> | Heh. I'm lucky in that I never learned SVN or CVS. |
05:43 | <@McMartin> | But the Master Repo is what maintains the true material. |
05:43 | < Tarinaky> | I just went straight to git. |
05:44 | <@McMartin> | Yeah, I've been using SVN and/or CVS since... 1998 at the absolute latest. |
05:44 | < Tarinaky> | So I don't have anything to unlearn. |
05:44 | | * Tarinaky picked git because he thought there was more/better documentation >.> |
05:45 | < Tarinaky> | Anyway. I'm going to try going back to sleep I think. I'm totally out of it. |
05:45 | < Tarinaky> | Later. |
05:53 | | Chi [omegaboot@Nightstar-7ff8f4eb.il.comcast.net] has quit [[NS] Quit: ] |
06:00 | | * Rhamphoryncus wonders how much functional programming uses different styles that just aren't doable in a non-functional language, how much it uses the same styles, and how much it uses the same style but thinks about it in a very different way |
06:01 | < Rhamphoryncus> | map(foo, seq) is a bit different to think about, but map(lambda (i): ..., seq) is a lot closer to for i in seq: ... |
06:02 | < Rhamphoryncus> | And I haven't seen a reason to think for-each in a pure functional language uses a different mental model than for-each in an imperative language |
06:05 | <@ToxicFrog> | Map is a list transform, foreach is an iteration. |
06:06 | <@ToxicFrog> | Even if they're implemented the same way, they're different things. |
06:06 | < Rhamphoryncus> | and I firmly believe a for-each is state, even if it's a pure language that creates a new context with a new variable, rather than modifying the variable in the old state |
06:07 | < Rhamphoryncus> | ToxicFrog: ruby does this (hopefully I get the syntax right): seq.each { |i| ... } |
06:07 | <@ToxicFrog> | Yes, but ruby is a crime against god and man~ |
06:07 | <@McMartin> | That's an iterator |
06:07 | < Rhamphoryncus> | McMartin: it's map and lambda |
06:07 | < Rhamphoryncus> | Just with a cleaner syntax (heh) |
06:07 | <@McMartin> | Ahahahano to the latter |
06:08 | < Rhamphoryncus> | Okay, with less parenthesis |
06:08 | <@McMartin> | As to the former, "for i in seq" names i as a thing |
06:08 | <@McMartin> | It's being explicitly reassigned, etc |
06:08 | <@McMartin> | map (lambda(i)) etc uses no mechanic other than binding formals to actuals |
06:08 | < Rhamphoryncus> | yes, mechanic |
06:08 | < Rhamphoryncus> | But I'm talking about the programmer's mental model |
06:08 | <@McMartin> | In short, I think you have it backwards |
06:09 | <@ToxicFrog> | Rhamphoryncus: the programmer's mental model, at least for me, is completely different |
06:09 | <@McMartin> | The programmer's mental model of foreach is actually a discipline that lets him treat it as a map. |
06:09 | <@ToxicFrog> | Even when I implement map myself in terms of foreach. |
06:09 | <@McMartin> | This is illegal in Python, but it's perfectly legal in C, and it's completely insensate in terms of map: |
06:09 | <@McMartin> | int a = 0; for (int i = 0; i < 10; ++i) { a += i; ++i; } |
06:09 | <@McMartin> | That sums every even number less than 10 |
06:10 | < Rhamphoryncus> | McMartin: that's not for-each |
06:10 | <@McMartin> | No. Foreach, if it maintains all its own internal state, is a map, exactly. |
06:10 | < Rhamphoryncus> | and saying for-each is treated as map works just as well |
06:10 | <@McMartin> | If it does not, then you can hook into it and go i.next() |
06:11 | <@McMartin> | However, foreach is not what functional programming is, if you will, about. |
06:11 | <@McMartin> | Until you have actual closures, you're just doing preprocessing tricks on procedural code |
06:11 | <@McMartin> | And once you have closures, you're in a place where you can compile to and from OO. |
06:12 | <@McMartin> | Unless and until you get a completely different evaluation model, as per Haskell. |
06:12 | < Rhamphoryncus> | Closures feel like state to me too. Of course that's not the normal definition of state :/ |
06:12 | <@McMartin> | You're using "state" in an odd way. |
06:12 | < Rhamphoryncus> | yeah |
06:12 | <@McMartin> | I think the shortest position from where you are to the truth is... |
06:13 | <@McMartin> | "When other people say 'stateless' they really mean 'using nothing but static-single-assignment'" |
06:13 | < Rhamphoryncus> | Yeah, but that's not how they argue it.. |
06:13 | <@McMartin> | That's because they're using "state" in a more restricted form than you are. |
06:14 | <@McMartin> | If the semantics of something are explicitly stated as a single memory cell changing values over time, that's state. |
06:14 | <@McMartin> | If that (or something exactly equivalent to it) never comes up, it's stateless, even if a compiler will turn it into code for a stored-program computer that does in fact do that because of physics. |
06:15 | <@McMartin> | Trivial example: a tail recursive factorial function. |
06:15 | <@McMartin> | fact x r = if x < 2 then r else fact (x-1) (r*x) |
06:15 | < Rhamphoryncus> | I disagree, but I'm still on map vs for-each |
06:15 | <@McMartin> | I'm telling you, that's a red herring. |
06:16 | <@McMartin> | foreach is an explicit attempt to import functional programming into procedural languages. |
06:16 | < Rhamphoryncus> | I think the functional programming was procedural all along |
06:16 | <@McMartin> | Yeah, and you're wrong. |
06:16 | <@McMartin> | Or, rather, you're deliberately missing the point |
06:16 | <@McMartin> | Consistency requires you to consider that fact function up there to be stateful, for instance. |
06:16 | <@McMartin> | And it's not by any consensus definition. |
06:17 | <@McMartin> | And it isn't despite the fact that when compiled with the most basic of optimizations (tail call elimination), the machine code generated puts two words on the stack (x and r) and repeatedly reassigns them while operating in a goto-bound loop |
06:18 | <@McMartin> | (Which is to say, it's exactly the same code at the machine level as "while (x < 2) { r = r * x; x = x -1; } return r;" |
06:18 | <@McMartin> | By the standards you're using here, this means tail-recursive functions are stateful |
06:18 | < Rhamphoryncus> | yup |
06:18 | <@McMartin> | And that deprives the term of all meaning |
06:18 | < Rhamphoryncus> | yup |
06:18 | < Rhamphoryncus> | Thus my problem |
06:18 | <@McMartin> | Thus, you are wrong, as the term is not in fact meaningless. |
06:19 | < Rhamphoryncus> | Using the standard term leaves me to think a turing machine is stateless |
06:19 | < Rhamphoryncus> | Which is equally meaningless |
06:19 | <@McMartin> | Modeling the behavior of a stateless function does not require you to take time into account |
06:19 | <@McMartin> | Only environment |
06:19 | <@McMartin> | No, a turing machine changes over time, and time is an inextricable part of the model |
06:20 | <@McMartin> | You can produce a data structure representing the current state of a turing machine in a way that it can be transformed by stateless computations, thus simulating time. |
06:20 | <@McMartin> | You've hit the fact that it's hilariously easy to be Turing Complete and concluded that there are no meaningful differences between languages |
06:21 | < Rhamphoryncus> | What does transformation have to do with it? |
06:21 | <@McMartin> | Hm. |
06:21 | <@McMartin> | The standard metaphor here you have already more or less admitted won't work for you. |
06:21 | < Rhamphoryncus> | Ditto being implemented on machine code. That's a big red herring |
06:22 | <@McMartin> | When designing a stateless program, you are essentially defining a gigantic formula whose value is to be computed. |
06:22 | <@McMartin> | To the extent that time is important, this is encoded within the formula as dependencies between the terms. |
06:22 | <@McMartin> | When designing a stateful program, you are writing a recipe. |
06:22 | <@McMartin> | If you were trying to actually compute anything, the recipe's steps involve taking the steps to do so and you direct the action by hand. |
06:23 | <@McMartin> | So, the difference between map and foreach is... |
06:23 | <@McMartin> | a = [1, 2, 3]; b = map(square, a) |
06:23 | < Rhamphoryncus> | But it seems to me that any sort of variable context is state. That implies any function called more than once (unless with identical arguments) has state. This in turn implies the point of purity is NOT the lack of state, but rather the avoidance of side effects |
06:24 | <@McMartin> | Your "that implies" is flawed. |
06:24 | < Rhamphoryncus> | Which means a for-each, even if explicitly mutating a local variable, is pure (so long as closures do not exist) |
06:25 | <@McMartin> | Conceptually, map(square, a) means "compute the list in which each element is the square of the corresponding element in a" |
06:25 | <@McMartin> | to put that in foreach, you have to first preallocate a result and then fill each cell in with your foreach |
06:25 | <@McMartin> | for i in a: b.append(square(i)), say. |
06:26 | < Rhamphoryncus> | No, you don't |
06:26 | <@McMartin> | This is a wholly different focus. You're openly commanding that memory be allocated and linked together in a certain way. |
06:26 | < Rhamphoryncus> | That's a specific implementation |
06:26 | <@McMartin> | You cannot write a foreach that behaves like a map |
06:26 | < Rhamphoryncus> | b = [square(i) for i in a] is the same conceptually whether pure or impure |
06:26 | <@McMartin> | That's a map. |
06:27 | <@McMartin> | List comprehensions are maps, not iterations. |
06:27 | < Rhamphoryncus> | pot, meet kettle ;) |
06:27 | <@McMartin> | No. |
06:27 | < Rhamphoryncus> | I never saw for-each as any different from that |
06:27 | <@McMartin> | Oh? |
06:27 | < Rhamphoryncus> | Even in C I wanted a for-each like that |
06:27 | <@McMartin> | What does for i in a return? |
06:27 | <@McMartin> | map returns a list. |
06:27 | < Rhamphoryncus> | It's just "obvious" |
06:27 | <@McMartin> | list comprehensions return a list. |
06:27 | <@McMartin> | what does for return? |
06:28 | < Rhamphoryncus> | It depends :P |
06:28 | <@McMartin> | for doesn't return anything, because it's not a function. |
06:28 | <@McMartin> | You can use a for loop to build up a value which you then return, as part of a function |
06:28 | < Rhamphoryncus> | It's often just a reorganized map or reduce |
06:28 | <@McMartin> | The reorganization changes, at a fundamental level, what your core computation model is. |
06:29 | < Rhamphoryncus> | Not my mental model |
06:29 | < Rhamphoryncus> | Just the language's implementation |
06:29 | <@McMartin> | You're translating under the hood and not noticing. |
06:29 | <@McMartin> | The language's implementation is the same even when the computation model is different; that was the whole point of the factorial example. |
06:29 | < Rhamphoryncus> | Would you accept a for-each if it had a hidden list, appended locally, and not accessible until the loop was done? |
06:29 | <@McMartin> | Uh |
06:30 | <@McMartin> | That is incoherent as stated |
06:30 | <@McMartin> | foreach is "here is a chunk of code, execute it with each element of this sequence in order" |
06:30 | < Rhamphoryncus> | so the b = [square(i) for i in a] was translated to for i in a to b: append square(i) |
06:30 | <@McMartin> | Yes, that is a translation from a functional to a procedural model. |
06:30 | <@Vornicus> | foreach can be map, or reduce, or just "each" |
06:31 | <@Vornicus> | (that reduce can be, well, anything, is a different matter) |
06:31 | <@McMartin> | Your sticking point appears to be "I can implement maps and reduces in a procedural language: therefore, functional programming doesn't do anything" |
06:31 | < Rhamphoryncus> | McMartin: more like "I do that every day and think about it (seemingly, to me) in the same way. What's the big deal?" |
06:32 | <@McMartin> | It's twofold, mainly. |
06:33 | <@McMartin> | (a) You've done the equivalent of asking "what does a = b+c; get you over MOV A, B; ADD B, C;?" |
06:33 | <@McMartin> | Which is to say, map, filter, and fold are important primitives in functional languages, but they aren't the selling point of them per se |
06:34 | < Rhamphoryncus> | Not quite. I'm claiming they're both a = b+c. You're insisting I'm using MOV A, B; ADD B, C; |
06:34 | <@McMartin> | They *are* both a = b+c. |
06:34 | <@McMartin> | One of them's in assembler, one of them's in an HLL |
06:35 | <@McMartin> | The HLL, however, can also automatically handle algebraic formulae of arbitrary complexity, and assembler can't. |
06:35 | < Rhamphoryncus> | Python's pretty high level |
06:35 | <@McMartin> | Now, as it happens, list comprehensions are the equivalent of algebra in this metaphor. |
06:35 | | * ToxicFrog blinks |
06:35 | < Rhamphoryncus> | (and there's a symbolic math lib, although it's third party, hehe) |
06:35 | <@McMartin> | List comprehensions were copied outright into Python from Haskell. |
06:35 | <@ToxicFrog> | Rhamphoryncus, you seem to be arguing that semantic equivalence implies conceptual equivalece. |
06:36 | <@McMartin> | They are screamingly functional, and they are so because it turns out that anything that can be implemented with bounded loops can be done statelessly with nothing but map, filter, and fold. |
06:36 | <@McMartin> | Which is to say, with a single list comprehension that is then accumulated with some accumulation function. |
06:37 | < Rhamphoryncus> | ToxicFrog: I know the concepts I use for python. My opening question was that maybe I misunderstood the concepts used by functional programming. So far.. no |
06:37 | <@McMartin> | Which brings us to (b) - functional, procedural, OO, and logical programming, despite all being able to solve exactly the same set of problems, decompose them differently. Each can be implemented in terms of any of the others. |
06:38 | <@Vornicus> | when you say "bounded loops", do I have to know before I enter the loop how many things I'll need to do, in some sense or another? |
06:38 | <@McMartin> | Yes. Pascal for. |
06:38 | <@McMartin> | You don't get while. |
06:39 | <@McMartin> | That gives you all... recursively enumerable functions, I believe. |
06:39 | <@McMartin> | While adding while gives you all partial general recursive functions. |
06:40 | <@McMartin> | Which is to say, you then become Turing-Complete. |
06:41 | <@McMartin> | Rhamphoryncus, you seem to be hung up on "functional == stateless", when it should be "functional = higher-order functions", which, frex, C does not have. |
06:41 | <@Vornicus> | Hooray lambda |
06:41 | <@Vornicus> | (and __call__, when I'm feeling /that/ crazy) |
06:41 | < Rhamphoryncus> | Maybe I'm just too casual to translating to imperative languages when mentally I'm solving the problem in a functional fashion |
06:42 | | Derakon[AFK] is now known as Derakon |
06:42 | <@McMartin> | Every procedural language more complex than an assembler has functional components. |
06:42 | <@McMartin> | Python actually makes this much easier, because it officially keeps the dichotomy. |
06:43 | < Rhamphoryncus> | Oh I'd do it in assembler too :P |
06:43 | <@McMartin> | list comprehensions are expressions. |
06:43 | <@McMartin> | foreach is a statement. |
06:43 | < Rhamphoryncus> | I don't need expressions |
06:43 | <@ToxicFrog> | |
06:44 | < Rhamphoryncus> | it's sure nice. C has some vile syntax limitations |
06:44 | <@McMartin> | No, assembler does not have functional components except to the extent it extends the machine code. |
06:44 | <@McMartin> | Um |
06:44 | <@McMartin> | Quick quiz |
06:44 | <@McMartin> | Difference between an expression and a statement |
06:44 | < Rhamphoryncus> | I know the difference :P |
06:44 | <@Vornicus> | Oooh! Ooh me! |
06:44 | | * Vornicus waves his hand around |
06:44 | <@McMartin> | You're not acting like you know the difference. |
06:44 | < Rhamphoryncus> | I'm talking about how I mentally solve the problem |
06:45 | <@McMartin> | The question is how you organize the code to do whatever the work is. |
06:45 | <@McMartin> | Are are setting up a series of steps to build the answer out of the parameters? It's procedural. |
06:46 | <@McMartin> | Are you transforming one value into another one by computing a gigantic expression, or (for daemon-style processes) transforming a stream of them? You're pure functional. |
06:47 | <@McMartin> | Are you building it up but wielding verbs as if they were nouns? You're impure functional or OO, which differ only in syntax (which is why Python blocks most impure-functional tricks). |
06:47 | <@McMartin> | Are you specifying conditions that need to hold for the answer to be true and then relying on the runtime to resolve the constraints? Logic programming. |
06:47 | <@McMartin> | You seem to be asking for a "magic bullet" for functional/OO/whatever programming |
06:48 | < Rhamphoryncus> | huh? |
06:48 | <@McMartin> | But if it has if and either goto + reassignable variables or function calls, it can express every program that it is philosophically possible to specify. |
06:48 | <@McMartin> | You're asking "what does functional programming give me that procedural programming does not" |
06:49 | <@McMartin> | And the answer is "they're both Turing complete because that is pathetically easy." |
06:50 | <@McMartin> | I'd say about half to three-quarters of OO philosophy involves structured use of lambda expressions when dealing with large-scale simulation or data processing. |
06:50 | <@McMartin> | Functional languages tend to have as their niche programs that take an input, give an output, and stop |
06:50 | <@McMartin> | Which is to say, the program is a function, and you invoke it to evaluate that function. |
06:51 | <@McMartin> | Now, I have a functional bias |
06:52 | < Rhamphoryncus> | Finally something I won't argue ;) |
06:52 | <@McMartin> | You don't even recognize what I'm saying here. |
06:52 | < Rhamphoryncus> | Likewise |
06:52 | <@McMartin> | I'm saying that given a problem, I will tend to turn it into a map/reduce problem. |
06:52 | <@McMartin> | You're saying that when you do map/reduce problems you more or less automatically compile them into something procedural |
06:53 | <@McMartin> | And that implies that you're either missing the forest for the trees or you're completely unaware that the map/reduce design space even exists. I can't tell which from here. |
06:54 | < Rhamphoryncus> | Given my original question I'm guessing the latter |
06:55 | <@McMartin> | For one that's just a chain of maps |
06:55 | < Rhamphoryncus> | I've never seen a map-reduce that couldn't be more easily understood as a for-each. However, I also hang out with mostly procedural programmers |
06:55 | <@McMartin> | Compilation is not, in fact, more easily understood as a foreach. |
06:56 | <@McMartin> | string -> token stream -> syntax tree -> "foreach" metaphor fails. |
06:56 | < Rhamphoryncus> | No, at that I'd say for-each vs reduce is irrelevant |
06:57 | < Rhamphoryncus> | The string is broken down into tokens, which are grouped into a syntax tree, which is then processed.. |
06:59 | < Rhamphoryncus> | And tokenizing has to be done sequentially. There's context involved |
06:59 | <@McMartin> | Function calls are superb at context; this is why ignoring the call stack is called being "context-insensitive" |
07:00 | <@McMartin> | You're again assuming that functional = stateless = throwing away anything resembling information |
07:00 | <@McMartin> | None of those equivalences are true |
07:01 | <@McMartin> | That said, the stateless version of your statement is "tokenizing is dependent not an individual character, but also on some number of characters before it" |
07:01 | <@McMartin> | Writing a pure-functional tokenizer is absolutely trivial, first-week stuff |
07:01 | <@Kazriko> | McMartin, I was only referring to svn. I've only marginally used Git, and found the whole concept interesting but flawed. It seems to rely on a single maintainer and single person in charge of maintaining the official code. Probably because that's how the Linux kernel works, but none of my projects ever work that way, and I use SVN partially for its offsite backup capabilities. |
07:02 | <@ToxicFrog> | Kazriko: um, what? |
07:02 | < Rhamphoryncus> | pure function is no action-at-a-distance? |
07:02 | <@Kazriko> | (Replying to something about a dozen pages back. ;) |
07:02 | < Rhamphoryncus> | Wait, I already made that argument |
07:02 | <@McMartin> | Kazriko: I kind of figured, but as noted I've been using SVN or CVS for over a decade. |
07:02 | <@ToxicFrog> | Yeah, the bit I'm whatting at is "It seems to rely on a single maintainer and single person in charge of maintaining the official code", which is not remotely true |
07:02 | <@McMartin> | ToxicFrog: The Git docs, which I have just perused, heavily favor that as the second most "normal" use |
07:03 | <@McMartin> | Their actual first most normal use involves all the end users trading commits randomly with one another in total anarchy |
07:03 | <@McMartin> | This is why it took me the better part of four hours to get Git into a situation where it looked like a client/server model but with the smarter clientele |
07:03 | <@ToxicFrog> | While those may be the "most normal" uses, from the point of view of the developers, it in no way relies on that |
07:03 | <@Kazriko> | I do like the idea of a local repository in addition to the central repository. |
07:04 | <@ToxicFrog> | And if you want an SVN-style client-server model with lots of people commiting to a central repository, this is trivial |
07:04 | <@ToxicFrog> | ...four hours? |
07:04 | <@McMartin> | TF: yeah, it wasn't so hard in the end |
07:04 | <@McMartin> | TF: The documentation was incredibly bad about this and I kept trying to get useful data out of the tutorials instead of looking at the "instead of using git-cvsdaemon, try this" stuff. |
07:05 | <@Kazriko> | As a broader way of doing open source, the anarchy model does have some value. |
07:05 | <@McMartin> | Not that kind. There's no way to designate an official release |
07:05 | <@ToxicFrog> | McMartin: the answer is in fact "use gitosis" |
07:05 | <@McMartin> | ToxicFrog: I have never heard of this program. |
07:05 | < Rhamphoryncus> | Well, I really should get to bed. Thanks for the conversation |
07:05 | <@Vornicus> | hooray, open source documentation. |
07:06 | <@Kazriko> | The lack of something like Tortoise SVN makes it pretty hard to recommend at my job though. |
07:06 | <@Kazriko> | It's hard enough to get the other people in the office to understand tortoise. |
07:06 | <@ToxicFrog> | Kazriko: what, you mean like SmartGit or TortoiseGit? |
07:06 | <@McMartin> | Kazriko: ... TortoiseGit exists. I haven't tested it, but it does exist. |
07:06 | <@McMartin> | It's not official, though, and I get the sinking feeling that all the shell extensions suck |
07:06 | <@Kazriko> | Interesting. Didn't exist when I was playing around with Git. |
07:06 | <@McMartin> | I have not in fact yet confirmed that Astatine will even run Git without trashing my Code::Blocks install |
07:06 | <@ToxicFrog> | McMartin: from the end user's perspective, you give your public key to the admin, and then clone/push/pull git@server:repo.git |
07:07 | | Rhamphoryncus [rhamph@Nightstar-8931f88f.abhsia.telus.net] has quit [Client exited] |
07:07 | <@Kazriko> | I guess that's my problem. I always try something out before it's really ready... I did the same thing with Ruby and it soured me on the language. |
07:07 | < Tarinaky> | Does a Windows version of git exist then? |
07:07 | <@McMartin> | I'm not only the end user, TF, I'm the repo admin. |
07:07 | <@McMartin> | It was the "be a repo admin" part that is the trick. |
07:07 | <@ToxicFrog> | From the admin's perspective, you put all those public keys in a directory and edit a config file to indicate who's allowed to access which repositories. |
07:07 | <@McMartin> | Yeah, I don't need any of that because only I get access to my repo. |
07:07 | <@ToxicFrog> | Oh. |
07:07 | <@ToxicFrog> | In that case just make sure you can ssh into the machine the repo is on and you're good. |
07:08 | <@McMartin> | So I needed to figure out svn URLs instead of git ones, and that Iodine has to git init --bare, and then someone else has to push the actual data in. |
07:08 | | * Kazriko goes back to playing the new sam and max. |
07:08 | <@McMartin> | Er |
07:08 | <@McMartin> | ssh URLs |
07:08 | <@McMartin> | Which don't work the way SVN's do |
07:08 | <@ToxicFrog> | gitosis is really for managing stuff where you have a team that all need read/write access to the repo, but you don't want to set up yet another daemon or give them full shell access. |
07:09 | <@McMartin> | Anyway, the documentation for the various commands you need are scattered hither and yon throughout the git docs, because their default use case models are (a) four or five developers who have cloned a base repository and thenceforth directly pull from each other's cloned repositories and (b) the Linux kernel model |
07:09 | <@McMartin> | Now, in the end, it is all there in the docs. |
07:10 | <@McMartin> | But it's not in the "crash course for CVS/SVN experts" part of the docs. =P |
07:10 | | * Vornicus declares bedtime. |
07:10 | < Tarinaky> | In git's defence it was written to solve a very specific problem quickly~ |
07:10 | <@ToxicFrog> | True. |
07:11 | <@ToxicFrog> | I would say that most of the git docs are useful only for reference, not for learning (and some are just unreservedly awful) |
07:11 | <@McMartin> | Now, as it turns out, one other advantage of Git is that it maintains all its metadata in a single centralized location, which means that development systems that use OS X bundles (like, oh, Interface Builder, or Inform 7) can actually now be properly version controlled. |
07:11 | <@ToxicFrog> | I got started using the git-tutorial and Git for Computer Scientists. |
07:12 | | * McMartin nods |
07:12 | <@McMartin> | At any rate, the four hours timing is from first hitting the Git home page. |
07:12 | <@McMartin> | To "my development history for my IF project on Carlsbad is now being hosted by a Git repository on Iodine that Carlsbad as re-cloned and can work with." |
07:14 | | * McMartin backs up his MinGW and MSYS directories before trying to install MSYS Git, which he does not trust. |
07:17 | <@ToxicFrog> | What's wrong with just using cygwin, incidentally? |
07:18 | < Tarinaky> | Isn't Cygwin massive |
07:18 | < Tarinaky> | Mind, last time I tried to install it I was on dial-up. |
07:19 | <@McMartin> | Cygwin and MSYS cannot coexist reliably |
07:19 | <@McMartin> | Cygwin binaries cannot be reliably distributed to people that haven't installed tens of gigs of shit |
07:20 | <@McMartin> | If I want a Linux machine I can run stuff on Iodine |
07:23 | < Tarinaky> | I'm having trouble googling Iodine. |
07:24 | < Tarinaky> | In part because I seem to have found at least two pieces of different software by that name. |
07:24 | < Tarinaky> | And also in part due to collision with the chemical. |
07:29 | <@ToxicFrog> | Tarinaky: it's the name of one of his computers. |
07:29 | < Tarinaky> | Oooooh. |
07:29 | < Tarinaky> | That'll explain my difficulty. |
07:30 | <@ToxicFrog> | McMartin: I have yet to have any coexistence problems on Durandal, which has hosted both Cygwin and MSYS since its construction. |
07:30 | < Tarinaky> | :/ Why can't you be normal and just use Greek mythology, gees. |
07:30 | < Tarinaky> | :p |
07:30 | <@ToxicFrog> | The problem with the binaries would be a problem if I were suggesting using it for builds, which I'm not, only version control. |
07:31 | <@ToxicFrog> | (indeed, before I switched to using a cross compiler my workflow for windows binaries was to develop everything using cygwin and then switch to msys for the release build) |
07:31 | | Derakon is now known as Derakon[AFK] |
07:41 | <@McMartin> | The other reason is because I want to continue to use Pageant, as we went over before |
07:42 | <@McMartin> | It turns out msysGit actually automatically detects it during install, so that's a good sign. |
07:44 | <@McMartin> | My resistance to Cygwin is both because I remember when it sucked, and because even now it's pretty all-or-nothing, and given the choice I'd rather do "nothing" - I'm no more uncomfortable in native Win32 than I am in native POSIX. |
07:44 | <@ToxicFrog> | Aah. |
07:45 | <@McMartin> | Now, as it happens, I now have two copies of MSYS installed, but they seem to be coexisting handily, so. |
07:45 | <@ToxicFrog> | (I find unadorned windows really awkward, and am of the opinion that while msys is fine as a dev toolchain, when it comes to making windows comfortable it doesn't go nearly far enough) |
07:46 | <@McMartin> | (Yeah, since I'm likely to hit up notepad++ / python before I'd ever do awk/sed/bash scripts, I can coexist a lot easier, I think) |
07:49 | <@McMartin> | OK, msysgit does what I need and seems to have customized its version of bash, too |
07:49 | < Tarinaky> | One of these days I need to learn awk/sed. |
07:50 | <@McMartin> | awk is superfluous these days |
07:50 | <@McMartin> | sed is only handy for horrible command lines of doom; otherwise you can use a real language |
07:50 | < Tarinaky> | TBH I can't remember whih one's which. |
07:50 | < Tarinaky> | But the stock Makefile I have saved and normally alter for my purposes has a line of sed in it. |
07:50 | <@McMartin> | sed is the one that lets you throw regex transforms as a stdin/stdout filter as part of some big commandline pipe |
07:51 | <@McMartin> | awk is like a tremendously stripped-down version of Perl |
07:51 | <@McMartin> | And any system that has awk on it these days will probably also have Perl |
07:51 | < Tarinaky> | "$(CXX) -MM $(CXXFLAGS) -c $< | sed 's,\($*\)\.o[ :]*,\1.o $@: ,g' > $@;" << I have no idea what the regexp does. |
07:51 | < Tarinaky> | Aside from Magic. |
07:52 | < Tarinaky> | Well, -MM is Magic. The regexp is More Magic. |
07:52 | | * Tarinaky copied it out of the manual >.> |
07:53 | <@McMartin> | That looks like it's probably used to build a dependency include? |
07:53 | < Tarinaky> | Yes. |
07:54 | < Tarinaky> | Apparently MM doesn't produce output in the right format or something :/ |
07:56 | <@McMartin> | Yay, GitGui links with TortoisePlink |
07:56 | <@McMartin> | That's even better than just linking to Pageant |
07:57 | <@McMartin> | It means it can hijack UI elements from TortoiseSVN too |
09:29 | <@McMartin> | Also, yay, my IF WIP is further along than I remembered |
09:29 | <@McMartin> | Too bad I haven't touched it in TWO YEARS TO THE DAY according to my changelogs |
09:33 | | You're now known as TheWatcher |
10:01 | | AnnoDomini [annodomini@Nightstar-6be0f4b4.adsl.tpnet.pl] has joined #code |
10:01 | | mode/#code [+o AnnoDomini] by Reiver |
10:15 | | Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has quit [Connection closed] |
11:05 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has joined #code |
11:37 | | Serah [Z@3A600C.A966FF.5BF32D.8E7ABA] has quit [Ping timeout: 121 seconds] |
11:46 | | Attilla [Attilla@FBC920.3488E2.03ED7E.3EC87F] has joined #code |
11:46 | | mode/#code [+o Attilla] by Reiver |
11:54 | | Serah [Z@5E691D.FC7C16.F8708C.3E343F] has joined #code |
12:01 | | Orth [orthianz@Nightstar-78fe5c6e.xnet.co.nz] has quit [Ping timeout: 121 seconds] |
12:07 | | Serah [Z@5E691D.FC7C16.F8708C.3E343F] has quit [Connection reset by peer] |
12:07 | | Serah [Z@5E691D.FC7C16.F8708C.3E343F] has joined #code |
12:22 | | AnnoDomini [annodomini@Nightstar-6be0f4b4.adsl.tpnet.pl] has quit [Ping timeout: 121 seconds] |
12:24 | | Serah [Z@5E691D.FC7C16.F8708C.3E343F] has quit [Ping timeout: 121 seconds] |
12:24 | | AnnoDomini [annodomini@Nightstar-a519dbfe.adsl.tpnet.pl] has joined #code |
12:25 | | mode/#code [+o AnnoDomini] by Reiver |
12:27 | | * AnnoDomini gets through NHibernate configuration and gets it sorta running. |
12:27 | <@AnnoDomini> | I'm trying to perform the equivalent of "select * from USER" and failing so far. |
12:35 | | gnolam [lenin@Nightstar-38637aa0.priv.bahnhof.se] has joined #code |
12:56 | < Tarinaky> | I managed to misread that as NHS and USSR. |
12:58 | <@AnnoDomini> | Achievement Unlocked: Illiteracy. |
12:58 | < Tarinaky> | One of these days I'll level up and remember to invest those two skill points. |
12:59 | < Tarinaky> | Mind, how I don't know since I can't read the charsheet. |
13:07 | < Namegduf> | You should... let me have your charsheet and a pen. |
13:07 | < Namegduf> | I'll do it for you! |
13:21 | < Tarinaky> | I don't trust you not to rob me of my gear. |
13:21 | < Namegduf> | I wasn't going to steal your gear. |
13:21 | < Namegduf> | I was just going to put the points into Knowledge, Agriculture. |
13:22 | <@AnnoDomini> | You suddenly grok crop rotation! |
13:26 | | * AnnoDomini manages to get the contents of a table. |
13:28 | | * AnnoDomini hurls obscenities, expletives, curses, ill-will, rocks, dooms and death at the makers of HQL. |
13:29 | <@AnnoDomini> | They made it case-insensitive. |
13:30 | <@AnnoDomini> | I have a table named USER. It just happens to occur that there's a keyword that matches the table name, without case-sensitivity. |
13:32 | < gnolam> | Arghl. I should sort my heaps of old code better. |
13:32 | | * gnolam goes hunting for his bloom filter code. |
13:34 | | * AnnoDomini fixes. |
13:35 | <@AnnoDomini> | Though I think I should redistribute blame, because whoever made up SQL is also to blame, as are the coders behind NConstruct Lite and the makers of SQL Server. |
--- Log closed Sat Apr 17 13:48:41 2010 |
--- Log opened Sat Apr 17 13:53:07 2010 |
13:53 | | TheWatcher [chris@Nightstar-b4529b0c.zen.co.uk] has joined #code |
13:53 | | Irssi: #code: Total of 19 nicks [8 ops, 0 halfops, 0 voices, 11 normal] |
13:53 | | mode/#code [+o TheWatcher] by Reiver |
13:53 | | Irssi: Join to #code was synced in 54 secs |
14:03 | <@jerith> | Yay bloom filters! |
14:05 | < Namegduf> | Dear god. |
14:05 | <@jerith> | Which one? |
14:05 | < Namegduf> | Java Serialization is the most horrible thing I've ever seen. |
14:05 | <@jerith> | I have been sacrificing to Bacchus today. |
14:06 | <@jerith> | Oh, that. I've seen worse, although I managed to mostly purge that. |
14:06 | < Namegduf> | They have an empty interface which things implement to mark themselves as serialisable- and if subclasses are, in fact, not serialisable, they're changed to throw an exception at runtime if you try. |
14:06 | <@jerith> | There's no better way to do it. |
14:07 | <@jerith> | Well, you could have a serializable() method in the interface which returns a boolean. |
14:07 | < gnolam> | jerith: This early? :o |
14:07 | <@jerith> | gnolam: 10h00 to 15h00. |
14:07 | < Namegduf> | You could not use an interface. |
14:08 | <@jerith> | http://www.southyeasters.co.za/index.php/SF2010 |
14:08 | <@jerith> | I sampled almost everything. |
14:08 | <@jerith> | The crowd that sell homebrew kits had a very limited supply, to I only got two of their six varieties. |
14:09 | <@jerith> | s/to I/so I/ |
14:16 | | Orthia [orthianz@Nightstar-8c87167c.xnet.co.nz] has joined #code |
14:45 | | Rhamphoryncus [rhamph@Nightstar-8931f88f.abhsia.telus.net] has joined #code |
15:11 | | * gnolam smacks himself. |
15:12 | | * jerith smacks gnolam. |
15:12 | < gnolam> | The reason I couldn't find my bloom code is that it was never on this computer. |
15:12 | <@jerith> | That would be a good reason. |
15:26 | < Rhamphoryncus> | blaaaaah |
15:26 | < Rhamphoryncus> | I hate arguments where I can't find any flaw in my own reasoning, but I'm vastly outnumbered. I'd (much) rather be wrong than to be stuck like that |
15:27 | <@AnnoDomini> | Is it the internets? |
15:27 | <@AnnoDomini> | Or IRL? |
15:28 | < Rhamphoryncus> | Actually the functional programming argument last night.. and other ones I've had before it. They usually end up the same way |
15:28 | < gnolam> | Rendering switched to floating-point buffers. Eagle, you are go for bloom. |
15:28 | <@AnnoDomini> | Rhamphoryncus: Democracy is not valid where competence or knowledge is required. |
15:29 | <@AnnoDomini> | This can be statistically shown. |
15:29 | < Rhamphoryncus> | AnnoDomini: sure |
15:29 | < Rhamphoryncus> | So I may be right. But I also may be wrong |
15:30 | <@AnnoDomini> | Was the argument theoretical, or something practical? |
15:30 | < Rhamphoryncus> | in between |
15:31 | <@AnnoDomini> | Does your approach produce proper results? |
15:31 | < Rhamphoryncus> | hmm? |
15:33 | <@AnnoDomini> | You must base your opinion on something. I assume that you aren't just pulling stuff out of a hat. |
15:34 | < Rhamphoryncus> | Yeah, but it's still ultimately an opinion |
15:34 | < Rhamphoryncus> | There's gaps that could be filled in by proper research, if I had a few million to blow, heh |
15:35 | < Tarinaky> | Anecdotes are a good basis for opinions. |
15:35 | <@AnnoDomini> | Then it's a matter of opinion and/or taste. De gustibus non disputandum est. |
15:35 | | celticminstrel [celticminstre@Nightstar-f8b608eb.cable.rogers.com] has joined #code |
15:37 | < Rhamphoryncus> | Opinion yes, but not taste. I think it's possible to come to an objective result, but neither party has the hard evidence to do so |
15:37 | <@AnnoDomini> | So you're effectively discussing whether God exists or not. |
15:37 | <@AnnoDomini> | Good luck with that. ;) |
15:37 | < Rhamphoryncus> | heh, I actually find that an easier discussion |
15:38 | < Rhamphoryncus> | I have confidence in my opinion there |
15:41 | < Rhamphoryncus> | At the risk of turning this from a meta-discussion back into the original discussion, do you know of any evidence that programmers think sequentially? a, then b, then c, rather than just.. stuff? |
15:41 | < Namegduf> | What kind of evidence are you thinking of? |
15:41 | < Namegduf> | I'm not sure how to gather evidence of that aside assertions. |
15:41 | <@AnnoDomini> | Rhamphoryncus: I have seen a study of how people who can be taught programming think significantly different from those who cannot. |
15:42 | < Rhamphoryncus> | AnnoDomini: yeah, I was thinking of that one |
15:42 | < Rhamphoryncus> | It's not directly studying that, and it may be biased towards procedural rather than functional programming (which is a BIG part of the issue), but it hints.. |
15:43 | | * gnolam stabs Linux desktops. |
15:43 | | * AnnoDomini doesn't know the first thing about functional programming. |
15:44 | < gnolam> | If you're busy and intending to lock up the machine for several seconds, /show it/. |
15:44 | < gnolam> | The hourglass cursor was invented for a reason. |
15:44 | < Rhamphoryncus> | AnnoDomini: I should have realized that. I'm not on fire yet ;) |
15:45 | < gnolam> | AnnoDomini: The camel has two humps? |
15:45 | <@AnnoDomini> | gnolam: Yes. |
15:45 | | Orthia [orthianz@Nightstar-8c87167c.xnet.co.nz] has quit [Ping timeout: 121 seconds] |
15:46 | <@AnnoDomini> | I don't know whether I agree with you or not, Rhamphoryncus. I don't really know how I think. |
15:46 | < Rhamphoryncus> | It seems to me that, even though map() isn't defined as operating sequentially, that the programmer is likely to think of it as if it did. Even if they don't it's the exception, while most of the surrounding code is sequential |
15:47 | < Rhamphoryncus> | AnnoDomini: that's fair |
15:49 | < Rhamphoryncus> | Concurrency research has more hinting that programmers *only* think sequentially |
15:50 | <@AnnoDomini> | Link? |
15:51 | < Rhamphoryncus> | I'd have to find some. I was reminded by this comment by Bruce Eckel though: http://www.haskell.org/pipermail/haskell-cafe/2008-September/047312.html |
15:53 | < Rhamphoryncus> | The actors model basically gives you isolated bits of sequential code. The key is the isolation |
15:57 | < Rhamphoryncus> | Hrm. Procedural programming is defined as sequential; it's not discussed separately because that's the entire point of being procedural. |
15:59 | < Rhamphoryncus> | Functional is declarative. It has no sense of time, it's just instantaneous |
16:01 | < Rhamphoryncus> | That may be the crux of the problem. Is functional programming as declarative as they claim? |
16:02 | <@AnnoDomini> | Do those programs get compiled to assembly? |
16:02 | < Rhamphoryncus> | They all do |
16:02 | < Rhamphoryncus> | but IMO that's irrelevant |
16:02 | < Rhamphoryncus> | The important thing is how the programmer understands them, not what's underneath |
16:10 | | * AnnoDomini likes how he can use his earlier LINQ to SQL code to have a convenient starting point at the NHibernate project. |
16:11 | <@AnnoDomini> | When I'm done, I'll have three half-arsed web forums. They're mostly identical, but they use OleDb, LINQ to SQL and NHibernate to connect to the database and do shit. |
16:11 | <@AnnoDomini> | Of those, I'll have to say that LINQ is my favourite. |
16:17 | < Rhamphoryncus> | Oooh two-line one-liners. My faaaaavourite! |
16:24 | <@AnnoDomini> | What? |
16:26 | < Rhamphoryncus> | Oh someone using a listcomp in python, split across two lines, as an example of functional code |
16:28 | < Rhamphoryncus> | I firmly believe it's harder to mentally parse than a for loop, but maybe it does get thought about more abstractly, declaratively... |
16:57 | | Derakon[AFK] is now known as Derakon |
17:12 | <@ToxicFrog> | Rhamphoryncus: I can tell you that at least in my case, I do think about them very differently. |
17:13 | <@ToxicFrog> | To use the map/foreach example, I think of foreach as a loop, a set of instructions: start at the beginning, go to the end, and do this at each step. |
17:13 | <@jerith> | I often write two or three line listcomps, but that's generally because there are a bunch of predicates or one of the expressions is big. |
17:14 | <@ToxicFrog> | I think of map as a transformation, a function mapping [a] -> [b] with no implication as to how it does it. |
17:14 | <@ToxicFrog> | Even though foreach can be implemented using map, and map can be implemented using allocate + foreach, the connotations are different even if the machine code is the same. |
17:15 | <@jerith> | I almost never use foreach. |
17:15 | <@ToxicFrog> | Yeah, same here. |
17:15 | <@jerith> | I'd rather use a listcomp (or map(), if it's more suitable) and throw away the result. |
17:16 | <@jerith> | I often write [dosomething(foo) for foo in foos] |
17:16 | <@ToxicFrog> | That tastes weird to me. |
17:17 | <@Derakon> | ...why would you do things that way? |
17:17 | <@Derakon> | I'm pretty sure there's no performance gain, and you're creating a list you don't need. |
17:17 | <@jerith> | Derakon: Because I think of it as a unit rather than a loop. |
17:18 | <@jerith> | It's the subtle difference between "do something with each of these" and "loop over this, doing something with each element". |
17:19 | < Namegduf> | I think of it as "For each of these, do this." |
17:19 | <@Derakon> | Y'know, there's a reason why list comprehensions use the same syntax as for loops for indicating what items to operate on. |
17:19 | <@jerith> | I'm pretty sure Erlang optimises the allocation away. |
17:20 | <@jerith> | Derakon: Only in Python. |
17:20 | < Namegduf> | Which fits the way I think well, because I don't like it mentally when an instruction can be completely parsed before it's done. |
17:20 | <@jerith> | Namegduf: Write some Haskell, it'll sure that. :-P |
17:20 | < Namegduf> | i.e. you can read "do something" on its own, but not "for each of these", in the latter case you're forced to read the whole instruction before you have a valid instruction. |
17:21 | <@jerith> | Namegduf: Which I why I treat the listcomp as a unit, not an iteration and an operation. |
17:21 | < Namegduf> | Well, really, the reason I comment is that it reminds me of Perl. |
17:22 | <@Derakon> | Ahh, yes. |
17:22 | <@Derakon> | $c++ if ($b); |
17:22 | < Namegduf> | Yep. |
17:22 | < Namegduf> | Which I find bad because it makes my brain have to backtrack. |
17:22 | <@Derakon> | die "Whoops!" unless (&func()); |
17:22 | <@jerith> | Perl's different, in that it's just the positioning of the flow control construct. |
17:22 | <@ToxicFrog> | Ow |
17:22 | <@ToxicFrog> | Don't do that, Der |
17:22 | < Namegduf> | I read it as "increment c-wait, only increment c if $b" |
17:22 | < Namegduf> | What Der did then was pretty idiomatic, I think |
17:23 | < Namegduf> | die... unless... I mean. |
17:23 | <@Derakon> | For the die example, it'd usually be written as &func() or die "Whoops!"; |
17:23 | <@jerith> | I found it useful occasionally in Ruby where the condition is true in the common case. |
17:23 | < Namegduf> | "&func() or" isn't so bad |
17:24 | < Namegduf> | I read it as "do X, if X fails, do y" |
17:24 | < Namegduf> | I tend to read code as a flow, at least. |
17:24 | <@Derakon> | Yeah, that's pretty standard taking advantage of boolean short-circuiting. |
17:24 | <@ToxicFrog> | Yeah, that's idiomatic in C/++, Lua and Bash as well. |
17:25 | < Rhamphoryncus> | jerith: what do you think of ruby's each? seq.each { |i| ... } |
17:25 | < Rhamphoryncus> | (hopefully I got the syntax right) |
17:25 | <@jerith> | Actually, I think I only ever did it with "unless", not "if". |
17:25 | < Namegduf> | I'm not sure what to make of the listcomp. |
17:26 | < Namegduf> | I don't think I can read it properly as a unit which is assigned to nothing. |
17:26 | <@jerith> | Rhamphoryncus: I prefer listcomps, but I'd like a better "function literal" syntax in pretty much all the languages I use. |
17:26 | < Namegduf> | Actually, on thought, it might be easier to read in real examples. |
17:27 | <@jerith> | Ruby's block syntax is about the cleanest I've seen, except it has nonobvious edge cases. |
17:27 | < Namegduf> | Written as "do something, for each x" I find my head hurts. "somefunc() per x" is easier to understand. |
17:27 | < Namegduf> | This is one case I actually like semicolons. |
17:27 | < Namegduf> | (Normally I just don't care) |
17:27 | <@jerith> | Namegduf: I don't like Python's listcomp syntax as much as I like Haskells. |
17:28 | < celticminstrel> | This sounds like a discussion of people not liking the grammatical structures of real languages being imposed on programming languages. :P |
17:28 | <@jerith> | [x*2 | x <- [1, 2, 3]] |
17:28 | <@Derakon> | Jerith: that seems needlessly mired in mathspeak. |
17:29 | < Rhamphoryncus> | jerith: doesn't that have everything in the same place as python's listcomp? It's just using symbols rather than keywords? |
17:29 | < Namegduf> | I would note that I consider mathematics to have the worst possible syntax possible. |
17:29 | <@Derakon> | Just replace | with "for" and <- with "in" |
17:29 | < Namegduf> | It's rather like someone took a programming language and just kept adding bits on and on. |
17:29 | < Namegduf> | And bits conflicted. |
17:29 | <@jerith> | Rhamphoryncus: Exactly. I prefer the symbols to the words. |
17:29 | < Namegduf> | So "look, it's like maths" doesn't tend to make me feel all happy inside. |
17:29 | <@Derakon> | Namegduf: well, seeing as mathematicians regularly invent new symbology for specific papers, that's how it works, yes. |
17:30 | < Rhamphoryncus> | Namegduf: I agree |
17:30 | <@Derakon> | Basically the symbology that is considered general mathematics is that which was featured in important proofs. |
17:30 | <@jerith> | The comma-separated clauses make more sense to me than keyword-separated clauses. |
17:31 | <@Derakon> | When glancing over code, keywords are easier for me to separate out than symbols. |
17:31 | <@jerith> | [x*y | x <- xs, y <- ys, x > y, x+y < 10] |
17:31 | < Rhamphoryncus> | .. what does that do? |
17:32 | <@Derakon> | Zip two lists xs and ys together, taking only pairs where x > y and their sum is less than 10, and create a list of x*y of those pairs. |
17:32 | <@Derakon> | I think. |
17:33 | <@jerith> | Not a zip, a cross product thing. |
17:33 | < Namegduf> | Oh, so... it's two assignments, followed by two conditionals. |
17:33 | < Namegduf> | I find the lack of distinction between those a little painful. |
17:34 | < Namegduf> | I suppose if I knew in advance I should expect an assignment per variable on the left side of the |, though, it'd be fairly readable. |
17:34 | <@jerith> | In Python, it would be [x*y for x in xs for y in ys if x > y if x+y < 10] |
17:34 | < Namegduf> | I'm convinced in Python, you would do it another way. |
17:34 | < Namegduf> | (Please) |
17:34 | | * Rhamphoryncus wants to burn that syntax at the stake |
17:35 | <@jerith> | Everything to the left of the "|" is "action". Everything to the right is generation and filtering. |
17:35 | < Rhamphoryncus> | [x*y for x,y in product(xs, ys) if x > y and x+y < 10] |
17:37 | < Rhamphoryncus> | Exact same character count btw... yours is missing an "and" in the filter part |
17:37 | <@jerith> | No and in the filter. Two filters is semantically equivalent. |
17:38 | <@Derakon> | But linguistically unfavorable. |
17:38 | < celticminstrel> | Wow. I didn't even know this about Python. |
17:38 | < Rhamphoryncus> | wtf o.O |
17:38 | < Rhamphoryncus> | I seriously thought it was a syntax error |
17:38 | < Rhamphoryncus> | Just what is the point of making the and optional? |
17:40 | | * jerith shall return momentarily. Switching machines. |
17:42 | <@jerith> | It isn't about making it optional, it's about allowing arbitrary generator and filter expressions. |
17:43 | <@Kazriko> | ` uyyyyyyyyyyyy---------- |
17:43 | <@Kazriko> | sorry, baby play=ing |
17:43 | <@Kazriko> | with the keyboard. |
17:43 | <@jerith> | I thought that wasn't very cattish. :-) |
17:44 | <@ToxicFrog> | Rhamphoryncus: I think I've figuted out part of why you were vastly outnumbered last night |
17:45 | <@ToxicFrog> | Please stop me if I misrepresent you |
17:45 | < Rhamphoryncus> | something about a baseball bat and a bees nest.. |
17:46 | <@ToxicFrog> | You start from the premise: you tend to instinctively translate problems into a procedural/sequence-of-instructions format, even if they're originally presented as functional/interdependent definitions. |
17:46 | <@ToxicFrog> | Yes? |
17:46 | < Rhamphoryncus> | jerith: python supports an arbitrary filter expression already. You can trivially chain subexpressions using "and". Why would you need two full expressions? Doesn't it just make the language more complicated? |
17:46 | <@jerith> | I don't have Haskell on here, so this is Erlang: |
17:46 | <@jerith> | 2> [X*Y || X <- [1, 2, 3, 4], X > 2, Y <- [X, 2*X, 3*X, 4*X], Y < 10]. |
17:46 | <@jerith> | [9,18,27,16,32] |
17:47 | | * Derakon eyes that. |
17:47 | < Rhamphoryncus> | ToxicFrog: that wasn't my intent. More the other way around, that I think of a for-each in an abstracted/functional sense |
17:47 | <@ToxicFrog> | That seems to directly contradict your earlier statements that programmers naturally think about things sequentially, though? |
17:47 | <@Derakon> | I'm having major problems parsing "Y comes from a list that is based on X" when X is only transiently defined. |
17:47 | <@jerith> | The ordering may or may not be changed for optimisation, but my intent is to filter out the Xs before I use them to make Ys. |
17:48 | <@ToxicFrog> | Which is part of what people were objecting to. |
17:48 | <@ToxicFrog> | Even if it wasn't your intent, what it looked like is that you were stating that premise, and then jumping to one or both of these: |
17:48 | < Rhamphoryncus> | ToxicFrog: sorta |
17:48 | <@ToxicFrog> | (2a) Therefore, everyone does it this way (which is demonstrably false just by talking to people in here who don't) |
17:49 | <@ToxicFrog> | (2b) Therefore, there is no useful/discernable difference between functional and procedural languages |
17:49 | <@ToxicFrog> | And neither of those conclusions follow from the premises at all. |
17:50 | <@jerith> | I must have missed this conversation. Sounds like fun, though. |
17:50 | <@ToxicFrog> | And then people get all atwitter because it looks like you're using faulty logic to attack either (a) the way they think about problems or (b) their favorite programming language. |
17:50 | | * Rhamphoryncus nods |
17:51 | < Rhamphoryncus> | The irony is I wanted them to point out the flaws in my logic, but that doesn't work if I can't articulate it properly :( |
17:51 | < Namegduf> | Clearly, the only way to go about programming is in a sequential, procedural fas-no, I probably shouldn't take that joke to completion. |
17:55 | < SmithKurosaki> | o.0 |
17:55 | < Rhamphoryncus> | I do need to further ponder if there is more distinction in listcomp vs foreach than I realized. Particularly in trivial listcomps, where they shine |
17:56 | <@jerith> | A listcomp is a map/filter chain. |
17:56 | < Namegduf> | Hmm. |
17:56 | < Rhamphoryncus> | But it's a lost more subtle than normally portrayed |
17:57 | < Rhamphoryncus> | ruby's foreach is both a map and a foreach. It's not just in the middle, but rather both extremes simultaneously |
17:57 | < SmithKurosaki> | Woah |
17:57 | < Namegduf> | mind.blown() == true |
17:58 | < Rhamphoryncus> | So at that level there is no conceptually distinction. Yet that doesn't mean there isn't a distinction at some slightly different level |
17:58 | < Namegduf> | Hmm. |
18:00 | < Rhamphoryncus> | That may be where my arguments fall apart. I can find a contradiction but not justify a new explanation without the contradiction |
18:01 | < Rhamphoryncus> | btw, were you two just sarcastic? |
18:01 | < Namegduf> | I was joking on the "Woah". |
18:01 | < Namegduf> | It sounds kinda interestingly generic. |
18:01 | < Namegduf> | Er, joking off the "Woah", rather. |
18:01 | < Rhamphoryncus> | That's what I thought |
18:02 | < Namegduf> | It does sound interesting, though. |
18:03 | < Rhamphoryncus> | I have the same feels about being "stateless". There's contradictions (turing machine in a pure functional language), so there must be some alternate definition.. but my alternate definition there leads to really upsetting conclusions ;) |
18:04 | < Namegduf> | I tend to switch how I reason about things based on circumstances. |
18:04 | <@jerith> | "stateless" depends very much on context. |
18:05 | < Namegduf> | I'm not good at functional reasoning, I think, though, just due to not having done much of any of it. |
18:05 | <@jerith> | I much prefer "idempotent", which is a little less vague. (And different, but usually closer to what people mean.) |
18:05 | < Namegduf> | I tend to reason sequentially, normally. |
18:06 | <@jerith> | I can reason functionally about very big and very small things. In the middle, it's hard. |
18:06 | < Rhamphoryncus> | jerith: I prefer isolated state, limited in scale. No actions at a distance |
18:06 | < Namegduf> | Actions at a distance are evil |
18:06 | < Rhamphoryncus> | Everybody agrees there :) |
18:07 | <@ToxicFrog> | Rhamphoryncus: as mentioned earlier, "stateless" when discussing functional programming means "nothing but static single assignment" |
18:07 | <@jerith> | I like "my state lives inside me, not you". |
18:07 | < Namegduf> | That's interesting. |
18:07 | <@ToxicFrog> | It doesn't mean "no state anywhere"; it means "all state is implicit in function parameters etc." |
18:07 | <@ToxicFrog> | And that = is definition, not reassignment |
18:07 | < Rhamphoryncus> | I've heard both :/ |
18:08 | < Namegduf> | No reassignment, basically? |
18:08 | <@jerith> | Which pretty much requires "you must be idempotent, otherwise you're storing my state". |
18:08 | <@ToxicFrog> | Namegduf: yeah. x = 5 in pure-functional defines x as 5, it doesn't create a variable x and set it to 5. |
18:08 | < Rhamphoryncus> | The arguments I've seen for the benefit of stateless tend to use "no state anywhere" |
18:08 | < Namegduf> | ToxicFrog: I've heard of that. |
18:08 | <@jerith> | "no state anywhere" means you're working in universal truths, not algortihms. |
18:08 | <@ToxicFrog> | This distinction means that something like: x = 5; x = 7; is illegal, because it binds two different values to x. |
18:08 | < Namegduf> | I've also heard people suggesting it for non-functional languages. |
18:09 | <@ToxicFrog> | It lets you do some brutal optimization and compile-time verification. |
18:09 | < Namegduf> | Yeah. |
18:09 | < Namegduf> | People were saying reassignment was always bad and that Go shouldn't have it. |
18:09 | < Namegduf> | I don't think the devs ever agreed. |
18:09 | <@jerith> | It was one of the things I expected to have trouble with in Erlang, but didn't. |
18:10 | < Namegduf> | ToxicFrog: But does that mean you can't alter variables, either? |
18:10 | <@jerith> | Namegduf: Correct. |
18:10 | < Namegduf> | i.e. no +=, no -=, no ++, and so forth? |
18:10 | < Namegduf> | Thought so. |
18:10 | <@ToxicFrog> | Namegduf: correct. No mutators. |
18:10 | | * Rhamphoryncus secretly redefines python's foreach as using SSA for the loop variable |
18:10 | <@jerith> | Because "variable" isn't a useful concept in such languages. |
18:10 | < Namegduf> | SSA? |
18:11 | < Rhamphoryncus> | single static assignment |
18:11 | < Namegduf> | I find it interesting as a concept. |
18:11 | < Rhamphoryncus> | yup. static single assignment has 23k hits. single static has 5k |
18:11 | < Namegduf> | It would *need* drastic optimisation to be fast. |
18:11 | <@jerith> | Not quite. |
18:12 | < Namegduf> | Or at least not fat on memory use due to all the alternative variables declared. |
18:12 | < Rhamphoryncus> | Languages like C are often translated into SSA by the compiler, for just those optimizations |
18:12 | < Namegduf> | As an alternative to mutators. |
18:12 | <@jerith> | Under the hood, it's translated/compiled into the machine code semantics we all know and love. |
18:13 | <@ToxicFrog> | Namegduf: uh, if you're "declaring lots of alternative variables as a replacement for mutators", you're writing procedural code in a pure-functional language |
18:13 | <@ToxicFrog> | Which is unlikely to go well |
18:13 | <@jerith> | You're not dealing with memory locations, you're dealing with names. |
18:13 | < Namegduf> | Hm. |
18:13 | < Namegduf> | The alternative is to write really really long definitions. |
18:13 | < Namegduf> | Instead of mutations in stages. |
18:13 | < Namegduf> | Unless I miss something? |
18:14 | <@jerith> | Very few of my Erlang or Haskell functions grew over about 5 lines long. |
18:14 | | * Rhamphoryncus goes and looks through his code to find violations of SSA |
18:14 | <@ToxicFrog> | The thing is, when using SSA, "variable" takes on its mathematical meaning as either "an input to a function" or "something with a single value that has not yet been computed", not the procedural definition of "something that changes over time" |
18:14 | <@ToxicFrog> | Namegduf: yes. Exactly. |
18:14 | < Rhamphoryncus> | newbitfield = self.bitfield & ~(mask << ventry.offset) |
18:14 | < Rhamphoryncus> | newbitfield |= 1 << (ventry.offset + ventry.bit_map[key]) |
18:14 | <@jerith> | Namegduf: You're thinking about it in the wrong way. |
18:14 | < Rhamphoryncus> | Technically a violation, but it'd be trivial to change it. It just reads better this way |
18:14 | <@ToxicFrog> | Functional programming is, IMO, about writing a definition for x such that computing x solves the problem. |
18:15 | <@ToxicFrog> | (Well, pure-functional, anyways) |
18:15 | <@ToxicFrog> | That said, you don't end up with really long definitions, you end up with lots of functions. |
18:15 | < Namegduf> | Hmm. |
18:15 | | Derakon [Derakon@Nightstar-5abd3ac9.ca.comcast.net] has quit [Ping timeout: 121 seconds] |
18:15 | < Namegduf> | Which is *like* the mutator way, but now they're separate functions. |
18:15 | <@jerith> | Erlang isn't pure-functional, but it's definitely on that side of the divide. |
18:16 | < Namegduf> | Instead of defining b, b2, b3 you define b in one function, c deriving from it in another calling the first, and d in another calling the second. |
18:16 | < Namegduf> | Right? |
18:16 | <@jerith> | Something like that. |
18:16 | < Rhamphoryncus> | I'd say probably 95% of my local variable assignments (maybe 99%) are single assignments |
18:16 | < Namegduf> | (Even if you were using mutators, you would, I hope, not REALLY use b, b2, b3) |
18:16 | < Namegduf> | That's interesting. |
18:17 | <@jerith> | I tend to use X and X1, Y and Y1, etc. when I'm modifying complex structures. |
18:17 | <@jerith> | In Haskell, I'd use x and x', y and y', etc. |
18:18 | < Namegduf> | Hmm. |
18:19 | <@jerith> | That isn't a common case, though. |
18:19 | < Rhamphoryncus> | The place where I really violate SSA is objects. Mutable and all that |
18:21 | <@jerith> | Namegduf: For the kind of case where you're mutating an object, you'd constuct a new one in a functional language. |
18:21 | < Namegduf> | Makes sense. |
18:21 | < Rhamphoryncus> | Heh, I'm dealing with object graphs |
18:22 | < Rhamphoryncus> | I like immutable objects, but some times you just can't do it |
18:22 | <@jerith> | Rather than appending an item to a list, you return a copy of the list with the new item on the end. |
18:23 | < Namegduf> | Right. |
18:23 | < Rhamphoryncus> | Or return a new item and let your caller append it |
18:23 | <@jerith> | (This is why functional algorithms *much* prefer prefixing. You're creating a node pointing to the original list rather than copying the whole list.) |
18:24 | < Namegduf> | And it's safe always because everything is immutable. |
18:24 | <@jerith> | Yes. |
18:26 | <@jerith> | Functional programming changes how you think about code. |
18:27 | <@jerith> | That sounds grandiose, but it's what happens. |
18:37 | < Rhamphoryncus> | How could functional programming solve my graph problems? |
18:38 | <@jerith> | Rhamphoryncus: Probably very ineffeciently. |
18:39 | <@jerith> | It isn't a silver bullet. |
18:39 | | * Rhamphoryncus nods |
18:39 | < Rhamphoryncus> | Doesn't that imply you don't want a pure language? |
18:40 | <@jerith> | But it's a different enough paradigm that it makes a bunch of problems more approachable. |
18:41 | <@jerith> | A pure language has a lot of benefits, but also a bunch of problems. |
18:41 | | * Rhamphoryncus nods |
18:42 | <@jerith> | Erlang's a reasonable compromise that way. |
18:42 | <@jerith> | You lose a lot of the guarantees purity gives you, but you can interface with a mutable universe in sane ways. |
18:44 | < Rhamphoryncus> | I'm pretty negative about erlang, hehe |
18:45 | <@jerith> | Why? |
18:46 | <@ToxicFrog> | I really should pick Erlang back up |
18:47 | <@ToxicFrog> | I used it a few years ago to brutalize my distributed systems course, but didn't stay in practice |
18:47 | <@jerith> | Erlang isn't a great language for most things, but it really shines in bit-level protocol stuff and certain kinds of concurrency. |
18:48 | <@jerith> | I should finish writing my IRCbot in it, actually. |
18:56 | < Rhamphoryncus> | jerith: that's pretty much it. Good at certain things but not in general |
18:56 | <@jerith> | Rhamphoryncus: That's what it says on the tin. Where's the problem? |
18:57 | < Rhamphoryncus> | When doing those certain things you have to do a lot of general things too |
18:58 | <@jerith> | It wouldn't be my first choice for text processing, for example. |
18:59 | <@jerith> | But it's passable for building log messages and stuff. |
19:06 | < Rhamphoryncus> | heh, I didn't mention my graphs are cyclic |
19:20 | | Rhamphoryncus [rhamph@Nightstar-8931f88f.abhsia.telus.net] has quit [Client exited] |
19:32 | | Derakon [Derakon@Nightstar-5abd3ac9.ca.comcast.net] has joined #code |
19:33 | | mode/#code [+o Derakon] by Reiver |
20:03 | | cpux- [Moo@Nightstar-20a84089.dyn.optonline.net] has joined #code |
20:05 | | cpux [Moo@Nightstar-20a84089.dyn.optonline.net] has quit [Ping timeout: 121 seconds] |
20:05 | | cpux- is now known as cpux |
20:06 | | * gnolam ponders making a game with a constant soft lens effect. |
20:06 | < gnolam> | It would be wonderfully annoying. |
20:42 | | Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has joined #code |
20:59 | | * gnolam leaves it in for now. |
22:28 | | * gnolam stabs Java with something rusty and tetanus-encrusted. |
22:39 | < gnolam> | God, the Sun RTE is a POS. |
22:49 | <@McMartin> | gnolam: Now add a cheesy 70s porn soundtrack~ |
23:10 | | * AnnoDomini really tries to understand how inner joins work in HQL but fails. |
23:10 | | RichardBarrell [mycatverbs@Nightstar-16573ac5.bb.sky.com] has joined #code |
23:14 | | cpux [Moo@Nightstar-20a84089.dyn.optonline.net] has quit [[NS] Quit: ChatZilla 0.9.86 [Firefox 3.6.3/20100401080539]] |
23:15 | | RichardBarrell [mycatverbs@Nightstar-16573ac5.bb.sky.com] has quit [Client closed the connection] |
23:15 | | RichardBarrell [mycatverbs@Nightstar-16573ac5.bb.sky.com] has joined #code |
23:22 | <@McMartin> | For the record, msysGit *is* more branch-happy to the newbie than Mac or Linux is. |
23:22 | <@McMartin> | For reasons I don't fully yet grasp, "git pull" doesn't work in stock msysGit |
23:22 | < Namegduf> | ...what? |
23:22 | <@McMartin> | You have to say "git pull origin master" |
23:22 | < Namegduf> | That's very screwy |
23:22 | <@McMartin> | If you know how to make that stop, I'd love to know ^_^ |
23:22 | < Namegduf> | Er, give me a sec |
23:22 | < Namegduf> | Okay. |
23:23 | < Namegduf> | Open .git/config in a text editor of your choice. |
23:23 | <@McMartin> | At any rate, if that was true before, it could very easily be the source of that earlier misimpression one of the other guys got |
23:23 | < Namegduf> | If there's a section for [branch "master"] or something, does it have a "remote" line in it? |
23:24 | <@McMartin> | Hm. There isn't, but there's a [remote "origin"]. |
23:24 | < Namegduf> | Bingo. |
23:24 | < Namegduf> | Wait, there's no section for [branch "master"]? |
23:24 | <@McMartin> | Nope |
23:24 | < Namegduf> | Weird. Try adding one that looks like: |
23:24 | < Namegduf> | [branch "private"] |
23:24 | < Namegduf> | remote = origin |
23:25 | < Namegduf> | merge = refs/heads/master |
23:25 | < Namegduf> | Er |
23:25 | < Namegduf> | s/private/master/ |
23:25 | <@McMartin> | Aha. That *is* in the Mac one. |
23:26 | <@McMartin> | Success! |
23:26 | <@McMartin> | Thanks. |
23:26 | < Namegduf> | No problem. |
23:26 | <@McMartin> | I was looking in the global config |
23:26 | < Namegduf> | It's a little buggy of it not to have that. |
23:27 | <@McMartin> | It's version 1.7.0.2.msysgit.0 instead of 1.7.0.3 like my other ones. |
23:27 | <@McMartin> | Could be a bug in .0.2 or it could be one they introduced in their fork |
23:27 | <@McMartin> | The existence of it explains a lot of the confusion I saw when I asked though, I suspect |
23:28 | < Namegduf> | Could be, yeah. |
23:30 | | * AnnoDomini tries to think of a way to make a custom IList or something, that could contain the output of a query with several inner joins. |
23:44 | <@AnnoDomini> | NHibernate pretty much prevents me from doing this by an overly large WHERE statement, since I'd need to parametrize entire collections for that to work - if that's even supported. |
23:44 | <@AnnoDomini> | What I'm getting doesn't work, but somehow goes through the parser okay. |
23:45 | | Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has quit [Connection closed] |
23:50 | <@AnnoDomini> | I'm getting a list of some sort, through .List() but I don't know how to access the data that should be in there. |
23:52 | <@AnnoDomini> | Seems I'm getting an Object[] or something like that. I don't know what to do with this. |
23:56 | | Thaqui [Thaqui@27B34E.D54D49.F53FA1.6A113C] has joined #code |
23:58 | <@AnnoDomini> | Seriously. What the hell am I supposed to do with an Object array? |
23:58 | <@Derakon> | Cast it to something? |
23:59 | <@AnnoDomini> | Uh, like what? I'd love to, but the collection doesn't fit any data structure I have. |
--- Log closed Sun Apr 18 00:00:33 2010 |