[This is a cleaned-up version of the notes from my Glasgow.pm tech talk last night. The central example is lifted wholesale from apenwarr's excellent README for redo; any errors are of course my own.]
( Read more... )
( Read more... )
Tags:
In git, the natural thing to pull is a branch (an ordered list of commits, each of which is assumed to depend on those before it); in darcs, the natural thing to pull is a patch (a named change whose dependencies are calculated optimistically by the system).Stephen's use-case is this: you're a release manager, and one of your hackers has written some code you want to pull in. However, you don't want all their code. Suppose the change is nicely isolated into a single commit. In darcs, you can pull in just that commit (and a minimal set of prior commits required for it to apply cleanly). This is as far as my thinking had got, but Stephen points out that the interesting part of the story is what happens next: if you subsequently pull in other changes that depend on that commit, then darcs will note that it's already in your repository and all will be well. This is true in git if the developer has helpfully isolated that change into a branch: you can pull that branch, and subsequent merges will take account of the fact that you've done so. However, if the developer hasn't been so considerate, then you're potentially in trouble: you can cherry-pick that commit (creating a new commit with the same effect), but if you subsequently pull a branch containing it then git will not take account of your having cherry-picked it earlier. If either of you have changed any of the lines affected by that diff, then you'll get conflicts.
git-cherry-pick
is a low-level, hackish tool, only really intended for use in drastic situations or in the privacy of your own local repo. If you want something semantically meaningful, only pull branches.darcs commit --ask-deps
, then you're potentially going to be spending a lot of time tracking down semantic dependencies by hand. Having been a release manager under neither system, I don't have any intuition for which is worse - can anyone here shed any light?That is, a long subroutine with different sections separated out by vertical whitespace.sub doStuff { # do this code code code more code # do that code code code code more code # do t'other code code code code }
If you are ever tempted to insert vertical whitespace in the middle of a subroutine to separate out different sections, just put the sections in their own freaking subroutines already.The usual reasons to strive for short subroutines apply:
proof
, data
, using
, idiom
, params
, namespace
, module
, import
, export
, inline
, where
, partial
, syntax
, lazy
, infix
, infixl
, infixr
, do
, refl
, if
, then
, else
, let
, in
, return
, include
, exists
, and with
- suggesting Edwin's added a module system and possibly even a syntax-extension mechanism since writing the tutorial...). "But so what?" I thought. "You can treat types as values, and implement Haskell's Eq
as a function from a type to its equality function." So saying, I wrote this:eqFun : {a:Set} -> a -> a -> Bool;
eqFun String = strEq;
eqFun Char = charEq;
eqFun Int = (==);
I loaded it into the interpreter, and got the response eqs.idr:2:Can't unify Set -> Bool and String -> String -> Bool
Bah. Still, it could be worse: when working on the cat
fragment on Day 3, I got the message user error (EPIC FAIL)
. Protip: don't give any of your programs the name io.idr
(or any of the other names used by the standard library) - it looks like "." is an early part of the library search path.cat
in Idris:You'll notice that the file to catenate is hard-coded: I haven't yet worked out how to access your program's command-line arguments.eachLine : (String -> IO ()) -> File -> IO (); eachLine f file = do { finished <- feof file; if finished then return II -- II is the sole element of the unit type () else do { line <- fread file; f line; eachLine f file; }; }; main : IO (); main = do { file <- fopen "fred" "r"; eachLine putStrLn file; };
android:screenOrientation="portrait"
to the activity
element in your manifest. This tip came from this StackOverflow post: I tried the more complicated "add a configChanges
attribute and override onConfigurationChanged
" approach described there, but that resulted in the LED wedging in whatever state it was in when you rotated the phone and not accepting any further changes. God knows what was going on there.git add -p
much? I tried the "edit this hunk" feature a couple of times, but it told me that it my patch wouldn't apply cleanly, and then rejected the whole thing. Also, I'm having trouble uploading files to GitHub's "download" section.jd
outputs JSON, as it should really have done all along. It's now an even thinner wrapper around Makamaka Hannyaharamitu's excellent JSON module :-)jf
now has a -p
option that pretty-prints its output directly.jf
can now handle several field specifiers at once, and preserves enough of the structure of the input to contain them all. Here's an example:$ curl -s -upozorvlak:<my password here> http://api.twitter.com/1/statuses/mentions.json \ | jf -p user/name user/screen_name text [ { "text" : "@pozorvlak I have to admit that if you have polymorphism then things like +. are particularly pointless.", "user" : { "name" : "Christopher Yocum", "screen_name" : "cyocum" } }, { "text" : "@pozorvlak Huh, I still like the safety that static typing gives you.", "user" : { "name" : "Christopher Yocum", "screen_name" : "cyocum" } } ... etc ... ]The XPathy syntax is due to Leon Timmermans.
jf
for. I could certainly document the programs better. For now, though, I think I'll email Makamaka and ask if he'd be interested in including jf
in the JSON.pm distribution.git reset --hard
, but that was before I knew about the reflog, and I've always been able to recover "lost" work in every other case. And then there's the rest: cheap local branching², the index, the raw speed, git-bisect
, git-gui
and gitk
(which has rapidly become an indispensable part of my development toolchain)³.drop
ped a spoon littledan GC'ed every object in memory. My friend Mark said that he saw a Factor programmer totally uppercut some kid just because the kid opened a gl-window.git clone
their repository right now or they will chop your head off!!! It's an easy choice, if you ask me..bash_profile
, all of which arose because I had to do something lots of times. Often, these scripts and aliases call other ones which I wrote earlier, as I spot higher-level patterns in what I'm doing. But every time, I have to fight against the False Laziness that tells me not to bother, I'll only have to do it once or twice more, and it's not worth the effort of doing it right..bash_profile
:alias viprof="vim ~/.bash_profile && source ~/.bash_profile"We'll see how it works out.