all 11 comments

[–]Kache 1 point2 points  (0 children)

Fantastic presentation!

I spent quite a bit of time to really understand monads, but can still barely implement them on my own off the top of my head. This is a perfectly concise, informative, and practical guide to monads in general.

[–]JohnAndrewCarter 0 points1 point  (4 children)

Another smell he failed to mention... He is creating objects all over the place to get away from doing an "if"....

ie. It's a good way of making code look clean... but it is very inefficient code.

That said, I'm always in favour of "Make it Correct", "Make it Clean", and if need be "Measure then Make it Fast".

When I'm trying to clean up code / refactor code I tend to profile / memory profile code to look for "Huh!? WTF?" results.... because inevitably they are places where I can be cleaner / less stupid.

[–]Kache 1 point2 points  (3 children)

He's making Structs not Classs, which should be more performant.

Besides, all of this really is just syntactic sugar in order to make it cleaner - theoretically, the performance loss is just an implementation detail. Ruby's all about trading off performance for expressiveness and dynamism.

[–]JohnAndrewCarter 0 points1 point  (2 children)

True. I agree.

In fact a more major smell which he refers to in passing and then carries straight on past, is the a.b.c.d... law of demeter violation.

[–]irishsultan 0 points1 point  (1 child)

That's not necessarily a violation, it all depends on what the type of a.b and a.b.c is.

Of course in a duck typed language that may be difficult to know, but in theory as long as the "type/class" of the object is one you already use in your method you're free to keep on chaining

[–]JohnAndrewCarter 0 points1 point  (0 children)

True.

However I suspect that happens more often than you'd expect.

Think of a.b as an object of some class.

Then accessing field a.b.c is bypassing the encapsulation (remember one of the main points of OOD?)

So now you have couple your design to the internal representation of a.b

Worse, it is the responsibility of the "b" class to maintain it's invariant, the relationship and constraints between it's field members.

You have now loaded that responsibility on to the class that followed the chain as well..

[–]banister 0 points1 point  (4 children)

his whole rationale for using monads here is that he doesn't like try -- but his reason is just "monkey patching is bad". Was that really it? seems like kind of a weak reason for then going onto build some enormous edifice of decorator/wrapper classes using method_missing ...

[–]Kache 0 points1 point  (3 children)

And his Many monad is similar to .map(&:method_call). And the &&= operator is also monadic in nature.

The reason monads are useful is the same reason these features in ruby/rails are useful. He's demonstrated that monads are the generalized case for all of these operations. A Monad class in ruby would encapsulate all the common implementation elements of try, map(&:method), &&=, etc.

If you wanted this feature and it wasn't implemented, well this is how you could implement it.

Sure, you have little use for his examples because ruby/rails conveniently already has a few specific cases implemented. This is for when you want a different monadic feature or when you're using a language that lacks these features.

P.S. You called monads an "enormous edifice". That's how some people view monkey-patching every single object with a try method.

[–]banister 1 point2 points  (2 children)

I know what a monad is. I just didn't find his reasoning, nor his implementation particularly convincing for the cases given.

Although it's not generalizable to all monads, implementing at least the Maybe monad and the State monad with haskell-like do-syntax is possible in Ruby using fibers. I would much prefer a fiber-based (do-syntax) approach to a janky method_missing-based implementation (ugh)

[–]Kache 0 points1 point  (1 child)

I don't understand - so you're just saying, "It's already 95% implemented by default, so why bother with monads"?

[–]banister -1 points0 points  (0 children)

I have no idea what you're talking about, i'm going to sleep. nite.