HNHacker News
TopNewBestAskShowJobs

sandal

723 karma · joined August 3, 2008

submissionscomments
sandal··on The perils of programmer education in the bazaar
I'm the author of this essay. Happy to discuss this topic with anyone, even if they disagree with my points!
sandal··on Parsing: The Solved Problem That Isn't (2011)
If you want to just see an example of building a parser, you could check out "Parsing JSON the hard way", which uses Racc:

https://practicingruby.com/articles/parsing-json-the-hard-wa...

sandal··on Simulating the emergent behavior of ant colonies
This sounds very cool! The video you linked appears to be marked private, though, so I wasn't able to watch it.
sandal··on Simulating the emergent behavior of ant colonies
It would definitely be interesting to do that! I had originally started out wanting to do something as natural as possible, but got myself into all sorts of frustrating trouble with ants getting turned around or wandering off forever. I'm fairly sure these were just failures in implementation, but they forced me towards looking at slightly more artificial designs.

The Ruby-based simulator discussed in this article used Rich Hickey's Clojure ant simulator as a starting point: https://gist.github.com/spacemanaki/1093917

Hickey's simulator was perhaps a bit closer to what you are looking for. It only emits one type of pheremone, which it releases on a continuous basis.

In my simulation, I introduced two types of pheremones: one emitted when food was found, and another emitted when the home was found. In retrospect, I possibly could have continuously emitted the "food" pheremone when traveling outbound, and the "home" pheremone when traveling inbound. I can't remember if I tried that and ran into trouble, or just didn't think of the idea at the time I was building this.

I vaguely remember choosing to implement things this way because it eliminated the noise generated by ants wandering in circles endlessly, but I honestly can't remember why I decided to "improve upon" Hickey's simulator.

It's worth pointing out that though the behavior of the world is very artificial (the whole trail gets marked at once after a complete path is run), the behavior of the ants themselves still only relies on their immediate location. And because these ants don't know where "home" is, they're even dumber than real ants that actually do have some sense of direction.

Anyway, refinements on this simulator or links to other simulations that illustrate these ideas are absolutely welcome! I'd definitely update the article if we found a way to improve upon what I've done.

sandal··on Simulating the emergent behavior of ant colonies
I run practicingruby.com and wrote this article, happy to answer any questions!
sandal··on Ask HN: What do you use for PDF reports these days?
I'm Prawn's maintainer and I think the "fine control over rendering at the cost of having to finely control your renderer" is spot-on.

We are working on a long term solution to that problem by finally focusing on building an extension and components layer for Prawn, which would hopefully allow all sorts of other gems to fill in these gaps. But it's a ways off into the future.

If going to Asciidoc is an option, Asciidoctor is now Prawn based for PDF output, and might make sense for simple reports:

http://asciidoctor.org/

sandal··on Infrastructure automation by example
Hi, I'm the guy who runs Practicing Ruby. :-)

Thanks for the feedback, I've emailed Mathias to let him know about your suggestions.

Bug reports, suggestions for improvements, and pull requests related to the cookbook can also be filed directly here: https://github.com/elm-city-craftworks/practicing-ruby-cookb...

Since we've been seeing a lot of traffic from this article, I'd be happy to also answer questions here that HN folks might have about how Practicing Ruby works!

sandal··on TDD, Straw Men, and Rhetoric
The critical flaw in this post is that Gary is not refuting what DHH said.

Gary makes this claim:

> You finally get to see what's really going on. David's tests run in a few minutes, and he's fine with that.

> I'm not fine with that. A lot of other people are not fine with that.

But what DHH actually said is this:

> You might think, well, that's pretty fast for a whole suite, but I still wouldn't want to wait 80 seconds every time I make a single change to my model, and want to test that. Of course not! Why on earth would you run your entire test harness for every single line change in a particular model? If you have so little confidence in the locality of your changes, the tests are indeed telling you that the system has overly high coupling.

and this:

> These days I can run the entire test suite for our Person model — 52 cases, 111 assertions — in just under 4 seconds from start to finish. Plenty fast enough for a great feedback cycle!

Using a workflow like Gary's, there's an argument to be made that 4 seconds is not acceptable, and this is why we want single files that can run in a few milliseconds.

However, that's not the only possible way of running tests, and the difference between 4 seconds and 300ms for the feedback you're actually interested is massively different than 300ms vs "a few minutes".

For a post that calls DHH out on a strawman, this is in itself a great example of one.

sandal··on Big changes to Erlang
Not a direct answer to your question but Joe's "Programming Erlang" book has been fully updated, and includes a chapter on the new map feature.
sandal··on Practicing Ruby journal moves to open-access, 68 free articles already available
I am the guy who runs Practicing Ruby. It's not an academic publication, but it is more than just a blog -- most of these articles involve a lot of research and development work.

If you have any questions, I'd be happy to answer them!

sandal··on Make Your Own Celluloid Ruby Gem
I'm really glad to see more folks discussing Celluloid and actor-model based concurrency in Ruby, too!

If you liked this article, you may also enjoy "A gentle introduction to actor-based concurrency"(*), which shows how to solve the dining philosopher's problem using Ruby threading primitives, celluloid, and a made-from-scratch actor model similar to what is shown in this article:

https://practicingruby.com/articles/shared/plgjjonrkggl

Disclaimer: I am the editor for practicingruby.com, and this is one of our contributed articles (from Alberto Fernandez-Capel).

sandal··on Towards a Common Ruby definition
I'm the author of the article, but it's worth noting that I'm not involved in any implementation efforts. That said...

The overall way that Ruby is developed causes these issues to happen, because major language experimentation happens very close to feature freeze dates. Because MRI is the defacto-standard (and the ISO standard defines a Ruby which simply does not exist in reality), contention happens because of the lack of coordination between the core Ruby team and the alternative implementers.

So for example, something like refinements are controversial because they are very challenging to implement and create all sorts of additional complexity. Under the current way of doing things, alternative implementers would be forced to either implement this feature or to not be able to fully claim they are "compatible" with whatever Ruby version they're released in.

Matz is generally a good BDFL, and the alternative Ruby implementers are generally very reasonable as well. But the tight time cycles, informal arrangements, and the communication barriers between a Japanese-speaking and Japanese-cultured core team and a more globalized language community combined lead to a lot of heated debates and frequent turbulence.

But all that having been said, compromises are almost always made sooner or later and the community moves forward together. They just often come at a high cost, and I wish that cost were lower. After all, the list of things we agree on is miles longer than that which we disagree about.

sandal··on Kim Dotcom loses new domain in preemptive strike by Gabon government
Hmm, I'm kind of amazed that kitte.nz isn't taken :)
sandal··on Rocket Science and the Law of Demeter
Hi, I'm the author of the article, but keep in mind that the work is based on David Smyth's ideas, and I haven't tracked him down to verify my own interpretation of things. Instead, I was just hoping to start a conversation, and I'm glad to see you've responded here. I'll do the best I can to answer to your questions...

1) Yes, exactly my first thought as well! I've personally been gravitating to a more functional-programming inspired form of OO, and so at first these ideas bothered me. But then I thought about it a bit, and it seemed like these ideas actually push things in the direction of Alan Kay's vision of objects: fairly autonomous entities that interact solely through message passing.

In such a system, the interesting stuff gets pushed up into the messages passing between objects rather than the state and functionality within the objects. This makes it conceptually quite different than functional programming, and probably has very different pros and cons.

2) Prohibiting return values does make a big difference to the way we need to think about error handling. I think raising exceptions might be acceptable for validating inputs, but for other kinds of failures, you would need to use a callback mechanism to allow the client to handle problems. This could be an argument you pass in, as you mentioned, or there could be a mechanism by which either the caller or some other object could subscribe to failure notifications. In any case, the object that caused the failure would be responsible for how to notify its caller, if at all.

I am not sure that the argument for doing things this way is at all related to trying to make things harder or for encouraging you to write error handling at the same time you write a function (although those may be side effects). Instead, I think that the point is to centralize failure handling so that the responsible object takes care of things rather than expecting every caller to know all the possible ways things can go wrong. For the sake of brevity, I cut an example from Smyth's correspondence that perhaps I should have left intact. Hopefully it will help shed some light on this issue for you:

    >4. Since there are no return values, the objects need to be
    >   "responsible" objects: they need to handle both nominal, and
    >   forseeable off-nominal cases. This has the wonderful affect of
    >   localizing failure handling within the object which has the
    >   best visibilitiy, and understanding, of whatever went wrong.
    >   It also dramatically reduces the complexity of protocols, and
    >   clients.
    >
    >   For example, with POSIX file system calls, one needs hundreds
    >   of lines of code to fully handle all possible failures of the
    >   open() call. This code needs to be at every open() call in all
    >   clients, because the POSIX file system is not responsible.
    >
    >   A responsible object would deal with the forseeable off-nominal
    >   cases. Then all clients benefit.
    >
    >   Clearly, something outside of the responsible object may need to
    >   act if the responsible object cannot resolve a problem with local
    >   action. OK - then a wider scope object needs to be involved: the
    >   responsible object sends the problem message "up" to some object
    >   with broader visibility. True, this might be, in a trivial system,
    >   the client -- but the problem is reported as a different message,
    >   not a return value from the original message (don't think
    >   continuations, because we are talking distributed here).
SOURCE: http://www.ccs.neu.edu/research/demeter/demeter-method/LawOf...

3) I stared at this "tight synchronization" statement for a long time too, and it wasn't clear to me until I realized that Smyth's primary interest was in developing guidelines that facilitate robust programming in distributed real time environments. The point he was making here, I think is roughly this: If you are not expecting return values from your functions, you can treat them as if they were all concurrent calls which immediately run in the background. You will never need to wait for a response, because you won't be calling functions on return values if you follow his variant of the LoD. Instead, results will get pushed to you via callback mechanisms only, which means that an arbitrary amount of time can pass between the time you call a function and the time that you know it has finished, and you won't need to worry about your functions blocking execution. The Ruby example I show in this article does demonstrate these ideas, through the use of threading. In a language with concurrent objects, you would get this effect "for free".

If you enjoyed this article, you might also enjoy another issue of Practicing Ruby that is on a related topic. Please check out "Responsibility-centric vs. Data-centric design", by Greg Moeck: http://practicingruby.com/articles/shared/lrwkumltjnxr

Hope that helps! I'll try to keep an eye on the conversation here, but may not have time to continue discussing things until next week sometime. Still, thanks for sharing your thoughts.

sandal··on Practicing Ruby manuscripts archive now on Github
I run practicingruby.com, so if you have any questions, I'd be happy to answer them!
sandal··on Kicking ass together: How to improve coding skills as a group
Ahahahah, I suppose I should fix that :)
sandal··on Ask HN: Best book you read in 2011
The Penguin and the Leviathan. It is an interesting mix of science and anecdotal evidence which hints that most people, most of the time, would actually benefit more from cooperative behavior than they would from competitive behavior.

http://www.amazon.com/Penguin-Leviathan-Cooperation-Triumphs...

sandal··on Node.js 0.6.4 was blocked in China
I am from the US, currently visiting China. I've confirmed that I'm able to access nodejs.org without my VPN. However, it's been my experience here that the system is aggressive about false-positives in general and will result in intermittent access to various websites for seemingly arbitrary reasons.

I'm not sure whether this happens at a regional level or across the entire country, but right now it's loading fine in Wuhan :)

sandal··on Node.js 0.6.4 was blocked in China
Hong Kong and Mainland China have pretty much completely separate political systems except for military and foreign affairs. I think this is supposed to last another 40 years or so at the minimum.

It's weird how two regions connected by a subway system can be so different from one another, and yet still be the same country. My wife is a Chinese citizen but needs a visa to go to Hong Kong... as an American I don't but I need a visa to go to mainland PRC. Fun!

sandal··on Node.js 0.6.4 was blocked in China
I am currently visiting China and everything you said is exactly what I've experienced. Using a VPN is the only way to get a working internet connection, but China is also blocking various popular VPN providers seemingly at random.

You don't need to be doing anything questionable to feel the bite of the GFW, webpages with Facebook like buttons are enough to cause a 30 second delay while the connection times out in the background before the site loads.

The censorship occurs at the TCP level, which is why pretty much only a VPN will help.

sandal··on How Mendicant University Works
You're absolutely right. On top of that, many schools that are "free" are typically just trying to sell you something else. That's not the case with Mendicant University.

Right now our public facing website has very little useful information because we've grown by word of mouth and one-on-one interactions up until this point, and still manage to fill our courses up without a problem. However, in the long term we do need to do a better job of making it easier for folks to know what we're all about without having to be a friend of a friend of mine.

sandal··on How Mendicant University Works
We are aiming at intermediate developers who are proficient in Ruby. While I have a fair bit of Ruby expertise, I still consider myself an intermediate software developer at best, because there is so much to learn!

It's true that Mendicant University doesn't do much right now to serve the beginner to advanced beginner crowd. We had hoped that some combination of Hackety Hack and P2PU would have done that, but it just hasn't happened. Our resources are limited and so the strategy we are taking is to teach students who have some degree of Ruby experience how to get stronger, with the hope that they will turn around and help out others. Many have done so already, but in small scale efforts.

We do have a beginner's course in the works, but it may be another six months to a year before we're ready to try it out. If you are seriously thinking of starting a school for Ruby programmers which is completely free but aimed more towards beginners, please do get in touch with us. We'd love it if someone else could focus on that, because it's a real community need.

sandal··on How Mendicant University Works
No, not vapor at all:

* http://university.rubymendicant.com/resources/learning_mater...

* http://university.rubymendicant.com/resources/student_projec...

* http://university.rubymendicant.com/resources/core_projects....

sandal··on How Mendicant University Works
We had originally hoped that the introductory Ruby course at P2PU would serve as an entry point leading up to the Mendicant University core skills session. Unfortunately that class hasn't quite come together and we don't have an immediate alternative path that is both free and of sufficiently high quality to recommend.

What you can definitely do (as Jordan mentioned) is get some help from our mentoring program. You'll be able to study at your own pace that way, but get some guidance as needed along the way: https://github.com/rmu/mentoring/wiki/Instructions-for-stude...

sandal··on How Mendicant University Works
Yes, all of our courses are completely free as in beer and as in freedom. We run everything on a full open source stack and release all our exercises.
sandal··on What's In A GIF
I've thought about writing a book on that.I've had to implement bits and pieces of PDF,PNG,JPG,and TTF and learning this stuff has been fascinating.

I did write one article and also did a short video on this stuff, but could think about expanding that if there is sufficient interest.

http://www.youtube.com/watch?v=BLnOD1qC-Vo http://practicingruby.com/articles/shared/oelhlibhtlkx

My work so far has been in Ruby but I'd probably want to at least look into how to do this sort of stuff in C or some other low level language, because things like alpha channel splitting in PNG is painfully slow :-/

sandal··on Ruby 1.9.3 released
1.9.3 is not an unstable release. Ruby uses the third version number to represent a point release, i.e. you can expect 1.9.3 to be more stable than 1.9.2 over time.

I think that the versioning policy did work the way you describe it at one point, but it's no longer the case.

sandal··on Ask HN: What programming blogs do you read daily?
I am the author of "Practicing Ruby" ( http://practicingruby.com ). It's a paid newsletter but I offer it for free for anyone who can't pay for it, and try to release back issues relatively frequently.
sandal··on "Unobtrusive Ruby" in Practice
Yes, I was mirroring Mike's original headings and didn't change them, but this is one area where my inner pedant was awoken. Glad to see I'm not alone!

The point here is simply that you should pass the object you directly want to work with, not a class that can be used to generate that object. So if the business of your method is to actually operate on a class object, that's fine. But if you're calling new() on that class, probably not as fine.

sandal··on "Unobtrusive Ruby" in Practice
I agree. I went from the semi-general statements found in this post (robots.thoughtbot.com/post/10125070413/unobtrusive-ruby) and cast them deeply into Ruby examples, but I think that you could go in the other direction with this and find that these concepts are already expressed by some existing general OOD principles. However, that direction seems harder to trace than just coming up with a code example for each point :)
← PreviousPage 2 of 7Next →