Hacker News new | ask | show | jobs
by jacobolus 5207 days ago
In some ways this is better, and in others it is much worse. Using named constants instead of magic numbers, and breaking up complex logic into simpler named parts is a huge win for readability/maintainability, as any programmer quickly learns. The big one liner would be a lot nicer in about 3-4 chunks.

I’d rewrite this example as something like:

  num.steps <- 1000
  num.walks <- 100
  step.std.dev <- 0.03
  start.value <- 15

  rand.row <- function() rnorm(num.steps, 1, step.std.dev)
  walk <- function () cumprod(rand.row()) * start.value
  all.walks <- t(replicate(100, walk()))
  plot(colMeans(all.walks), type = "l")
[I’m not an R guy, so that might not be the most typical style ever, but you get the idea...]
3 comments

Aside: One of the things that I really don’t like about R coming from a background in other programming languages is that a function is evaluated before its arguments; i.e. an expression passed as a parameter to a function is not a value but is an implicit lambda, to be evaluated multiple times somewhere inside the function.

For example:

  replicate(2, rnorm(2))
creates a 2x2 matrix of independent random values. Whereas:

  x <- rnorm(2)
  replicate(2, x)
Instead creates a 2x2 matrix with a single random value for each row, repeated across all columns. And so if you want to decompose it, you need to do:

  x <- function() rnorm(2)
  replicate(2, x())
Which will re-call x twice inside the replicate function.
R does have call-by-need semantics, like (an impure) Haskell, but that's not why replicate's second argument gets evaluated multiple times:

  replicate <- function (n, expr, simplify = TRUE) 
     sapply(integer(n), 
        eval.parent(
           substitute(function(...) expr)), 
      simplify = simplify)
The replicate function uses R's compute-on-the-language to construct a new function that has expr as its body.

A closure's argument will be evaluated at most once.

Nice! I think you found the happy medium between the OPs two methods. His first is too long which creates more dependency on being able to read the language and his second is too short which creates more dependence on knowing the functions he's working with. It's very interesting to me as I study readability quite a bit: both long and short coding styles aren't as good as medium.
You're absolutely on track here

The way he did it is nice and minimal, and in 2 months when you go back to change something you will have no idea what you did.

I've had to do a few things in R and I always dread revisiting my code. Half the time it's easier and faster to just rewrite everything.