Hacker Newsnew | comments | show | ask | jobs | submit | jamesgolick's comments login

More like Memory Allocators 405 haha

-----


True enough, but I think the introduction is pretty tractable and contains some pretty important (but subtle) points about memory allocator performance. Quoth the paper:

It is not sufficient to measure the time consumed by the allocator code in isolation. Memory layout can have a significant impact on how quickly the rest of the application runs, due to the effects of CPU cache, RAM, and virtual memory paging.

The only definitive measures of allocator performance are attained by measuring the execution time and memory usage of real applications. This poses challenges when qualifying the performance characteristics of allocators. Consider that an allocator might perform very poorly for certain allocation patterns, but if none of the benchmarked applications manifest any such patterns, then the allocator may appear to perform well, despite pathological performance for some work loads. This makes testing with a wide variety of applications important. It also motivates an approach to allocator design that minimizes the number and severity of degenerate edge cases.

-----


Actually, the reason is that aspartame has a high glycemic index, so your body reacts to it roughly the same way it reacts to sugar.

http://www.glycemicindex.com/

-----


That is not true, it was a truefact that squirted around health junkies that wasn't backed up by a consensus of the science.

-----


Any sources?

FWIW, I found practically no information regarding aspartame on the University of Sydney site, but I did come across an article that basically said stevia and aspartame both work, but stevia was was significantly better at lowering blood glucose levels.

Sidenote: As someone who loves beer dearly, but also tries to limit his intake of foods with a high glycemic index, I was pleased to read an article [2] linked by the University of Sydney [3] about how beer has too low of a glycemic index to measure (still has plenty of calories, though).

[1] http://www.glycemicindex.com/

[2] http://www2.prnewswire.com/cgi-bin/stories.pl?ACCT=104&S...

[3] http://www.glycemicindex.com/faqsList.php#10

-----


When looking I found this article which pointed at TONS of studies:

http://www.marksdailyapple.com/artificial-sweeteners-insulin...

-----


Oops - meant to reply here. http://www.livestrong.com/article/536467-does-stevia-affect-...

-----


The point I was making was that you can use the library in a different way successfully.

-----


I've read at least a dozen papers on the history of OO, not to mention books and papers on current practices. This is what I came up with. I made what I think is a pretty coherent argument for why in the article. I'd love to hear your refutation of the points I made in there.

-----


You have to think a bit more about what OO really is about. How would properties of your solution differ if you instead of classes split all the code into many very small global methods? The essence of OO is objects freely passing messages between themselves, if you fix all the message routing and put it in a central place you are not doing OO anymore, you loose the most fundamental properties, for example:

http://en.wikipedia.org/wiki/Dynamic_dispatch

You also don't have encapsulation anymore, since to be able to perform the majority of the work in the services, the services have to operate directly on data owned by other objects.

How can you combine the policies in ways other than a simple logical AND? How do you combine services?

Others have also already pointed out other issues.

Please don't be offended by the above. Software engineering is unfortunately a field where some valuable content is buried underneath loads of BS, since it is so easy to "philosophize" about it even with just basic programming experience and this leads other people learning the field to easy misconceptions. I do not want to discredit the work you put into this and it might be that in some form something valuable will come from some of the ideas. It is an interesting problem to work on and for me it was an interesting solution to think about, I just don't think you are there yet.

-----


> You have to think a bit more about what OO really is about.

If you want to have a respectful debate, I'm completely game. If you'd prefer to continue with your incredibly condescending tone, then I'll bow out here.

-----


Well, maybe I got carried away a bit with the tone in general in the last paragraphs of both comments, but I think I substantiated the particular sentence you cited quite a bit. On the other hand, I also took half an hour to clearly explain to you why this is somewhat misguided and tried hard to be polite, while someone below just said "this is fucking ridiculous". It's hard, at least for me, to give constructive criticism, without the other person being offeneded.

-----


I find utilising the Feedback Sandwich Technique, with some authentic positive encouragement, usually works well.

I apply it mostly when I'm writing something and am getting the feeling that it might not come across so well.

http://www.rightattitudes.com/2008/02/20/sandwich-feedback-t... (from a quick Google)

-----


You need to grow thicker skin, that first sentence was in no way condescending and gives you no reason to just ignore the rest of his comment.

-----


No. It may be unintentional, but the tone of stiff's comments is highly condescending.

Exhibit A: Whatever you think about James's choices in this library, he has clearly thought a lot about OOP. It's just silly to start a comment with "You have to think a bit more about what OO really is about."

-----


>You need to grow thicker skin

I'm beginning to be convinced this is almost never an appropriate thing to say.

-----


I think what the GP might be trying to get at is this: you've reinvented partial function application and first-class functions. An instance of a class can be regarded as a bundle of functions which all have the constructor's parameters partially applied. If your instance only has one method, it's equivalent to a single, partially applied function. In that sense, what you've done is found a way to reorganise a Rails app in a very functional way - and, if you want to do that, given that Ruby doesn't have first-class functions or partial application (well, without proc hack, anyway), this may be the best way to do it.

It may work very well, but it's at least as functional as it is OO.

-----


From the examples it doesn't even look like a _partial_ function application since it is not clear whether you can control how those services/policies/responders are initialized. Also I think it would be quite awkward for one service to initialize another and call it, so it is not really functional programming either, since there are no direct function calls. Since all the flow of the data is described in the routes file, it isn't OO at all and mostly reassembles dataflow programming as I said:

http://en.wikipedia.org/wiki/Dataflow_programming

Parts of this approach might be valuable, as I tried to emphasize, but as a whole this doesn't look good for plenty of reasons mentioned in the thread.

-----


The CurrentUserResolver example in the README shows that some initialisation control is possible here.

> it is not really functional programming either, since there are no direct function calls.

There don't have to be. The classes and instances are being referred to by the developer in the same way as any first-class functions defined elsewhere would be - they're actually resolved and called by the framework.

> Since all the flow of the data is described in the routes file, it isn't OO at all and mostly reassembles dataflow programming as I said

It certainly is OO. There are instances, and they receive and act on messages. Yes, there's a dataflow-like DSL for routing, but that's not to the exclusion of other paradigms.

-----


The CurrentUserResolver example in the README shows that some initialisation control is possible here.

This is the dependency injection part, not the policy/service/responder core of the framework I am talking about.

There don't have to be. The classes and instances are being referred to by the developer in the same way as any first-class functions defined elsewhere would be - they're actually resolved and called by the framework.

I am not talking about what happens on the level of Ruby, I am talking about what happens logically at the level of the framework. The classes represent functions, sure, but they do not call other functions (services/policies/responders), the only "function-calling" is done by the router. Yes, this too is a form of functional programming, the form known as dataflow programming where the flow of the data is described explicitly.

It certainly is OO. There are instances, and they receive and act on messages. Yes, there's a dataflow-like DSL for routing, but that's not to the exclusion of other paradigms.

It isn't OO at the level of the framework. Yes, Ruby is underneath, there are classes, there are instances, and the thin ORM layer is object oriented, but the objects within the framework do not exchange messages, the only object doing all the message dispatch is the router. This is not OO, just look at the traits listed here: http://en.wikipedia.org/wiki/Object-oriented_programming

The framework basically forces you to abandon messaging (since there is no exchange of messages, just single directional messages flow from the router), abandon encapsulation (since the services have to access the data of the domain objects and hence the domain objects must make their data available to everyone) and abandon polymorphism (since the services are statically dispatched by the router). How can this be object oriented?

-----


> The framework basically forces you to abandon messaging (since there is no exchange of messages, just single directional messages flow from the router),

The services receive messages from the router, then send messages to whatever they need to call to get the job done. Being sent messages by the framework is what makes it a framework and not a library; I don't get your objection here.

> abandon encapsulation (since the services have to access the data of the domain objects and hence the domain objects must make their data available to everyone)

Only if you're conflating domain objects with persistence objects.

> and abandon polymorphism (since the services are statically dispatched by the router).

They're statically dispatched on a constant name, not on a class. If you need polymorphism at that point, it's trivial to define a dynamic service resolver - all you need is something with a #new method assigned to the constant to do whatever late binding you want.

-----


The services receive messages from the router, then send messages to whatever they need to call to get the job done. Being sent messages by the framework is what makes it a framework and not a library; I don't get your objection here.

If it was a framework modelled in an object oriented way it would itself be built of classes exchanging messages, but it isn't. It encourages you to also structure your code in a non object oriented way by creating hundreds of little services which are basically procedure calls instead of making your model accept a wider variety of messages or instead of building classes with more than just a "call" method. Most of the code is supposed to go directly into the services, that's the whole point of the framework, remember it is a solution to the "fat model" problem:

One in particular is something I've been thinking about and refining for a while now [3]. In this approach, persistence objects remain extremely thin, and business logic is encapsulated in lots of very simple objects known as “services” and “policies”.

Also, keep in mind that the services do not normally call each other (they could in theory, but that would be even more awkward), so instead of having message exchange between models you have duplicated code in services or have to use inheritance. Ruby is object oriented so sure there are message calls further down, it doesn't make the framework object oriented on the logical level.

Only if you're conflating domain objects with persistence objects.

Must you go as far as to refer to a hypothetical reality just to win an argument ;) ? That's how Rails works, that's what the examples show, I am not referring to what is possible in theory, but to what the framework does and the most reasonable possible way of using it. Honestly one more level of indirection would make this look completely ridiculous.

They're statically dispatched on a constant name, not on a class. If you need polymorphism at that point, it's trivial to define a dynamic service resolver - all you need is something with a #new method assigned to the constant to do whatever late binding you want.

Ehm, no? You cannot just define a "new" method returning whatever you want neither in a module nor in a class in Ruby. You would have to overwrite the initialization methods that are usually hidden from the user. Passing a constant name is almost equivalent to passing a class.

  module Foo
    def new
      5
    end
  end

  puts Foo.new.inspect
  # undefined method `new' for Foo:Module (NoMethodError)

  class Bar
    def new
      5
    end
  end

  puts Bar.new.inspect
  # #<Bar:0xa146324>

-----


> Must you go as far as to refer to a hypothetical reality just to win an argument ;) ? That's how Rails works, that's what the examples show, I am not referring to what is possible in theory, but to what the framework does and the most reasonable possible way of using it.

Eh? The sentence you quoted explains that putting domain logic in the persistence objects is precisely what objectify avoids. I do't see any examples of domain logic as separate from persistence logic at all in the examples, so I'm not sure where you're getting the idea that the framework encourages it from. If you're that tied to "how Rails works", why are we even discussing this? Objectify exists to change the way Rails works, because the way Rails works is broken.

> Ehm, no?

Ehm, yes.

    class MyFunkyResolver
      def new
        5
      end
    end

    Foo = MyFunkyResolver.new
    p Foo.new
    # 5

-----


Eh? The sentence you quoted explains that putting domain logic in the persistence objects is precisely what objectify avoids. I do't see any examples of domain logic as separate from persistence logic at all in the examples, so I'm not sure where you're getting the idea that the framework encourages it from. If you're that tied to "how Rails works", why are we even discussing this? Objectify exists to change the way Rails works, because the way Rails works is broken.

I don't understand what you are trying to say. As far as I remember we are discussing here whether Objectify breaks encapsulation. In plain Rails you would have business logic together with persistence in a single class, and the data would be available to the external world only to the extent the business logic allows it. With Objectify all the data in the persistence objects has to be public for the services to be able to access it, and all the business logic is in many small services with only a single "call" method. Do you consider this to be good encapsulation? I am not tied to how Rails works, but I cannot judge all the possible ways of using Objectify, I can only judge what was presented/encouraged in examples and in the blog post and assume that you will use standard Rails practices in the rest of places, since it's in the end a Rails plugin and not a separate framework.

You are right regarding polymorphism.

-----


You can move over slowly by building new components using objectify, and leaving the rest of your legacy app the way it is, if you like. It's designed specifically to be able to coexist with what you've got.

-----


Because of SRP.

-----


At first I thought this was an attempt at trolling, but then I noticed that Mr. Golick is the commenter so therefor I must assume serious intent.

Care to give an answer better than "some book some java dudes wrote 20 years ago said so"?

While I generally agree with SRP, when that single responsibility can be expressed in a single function, I don't see the win with have a class dedicated to it. Smells of pedant OO nonsense.

Is not instantiation etc a cross-cutting concern that violates SRP in this instance?

-----


"some book some java dudes wrote 20 years ago" — If you're referring to "Design Patterns", the Gang of Four were writing about C++, it was 1994, and Java wasn't out yet.

-----


I think you misunderstood each other, you meant a global method and Mr. Golick seems to have understood that you mean just another method in the controller or whatever.

Also, those are not really single-method classes, but single-method interfaces. Since you didn't give any arguments, I don't see how those two extra lines to define a class have any disadvantage in comparison to a global method, and having the framework define a interface to program to leaves more flexibility to the framework user than having the framework accept a method name or block instead. The instatiation of the class can be left to the framework user (in general, I don't know if this is the case here in particular) so that additional data can be attached, inheritance can be used (yes, inheritance has its problems, still it also has plenty of valid usage scenarios), methods broken down into smaller private methods etc. Also in Ruby there are no global methods like you would have in Python or C++, you always define a method of some class, even if it's in the top-level scope - files almost always correspond to individual classes so it would be pretty odd to have methods used here instead.

-----


> Is not instantiation etc a cross-cutting concern that violates SRP in this instance?

Right.

Which is why hes also recommending the use of DI.

It's hard to strike a balance between a strong design which takes a lot of time to work within, and one that just allows you to get things done, but once your project begins to grow in size and complexity, and testing becomes even more important, these things really do start to matter.

It's difficult to internalize until it's bitten you on the ass, hard.

That said, if you have a large amount of single method classes, you might need to take a look at why you need them and find a better approach (which will vary from project to project).

-----


> It's hard to strike a balance between a strong design which takes a lot of time to work within, and one that just allows you to get things done, but once your project begins to grow in size and complexity, and testing becomes even more important, these things really do start to matter.

The whole point of objectify is that it actually makes it pretty reasonable to work this way right off the jump. I would have a hard time believing that it's really any more work to build an objectify app than it is to build a vanilla rails app - at least once you become accustomed to the paradigm.

> That said, if you have a large amount of single method classes, you might need to take a look at why you need them and find a better approach (which will vary from project to project).

I don't buy that. My project has hundreds of single method classes and it's by far the best factored non-trivial application I've ever seen (anecdotal, obviously, but so it goes).

-----


>The whole point of objectify is that it actually makes it pretty reasonable to work this way right off the jump. I would have a hard time believing that it's really any more work to build an objectify app than it is to build a vanilla rails app - at least once you become accustomed to the paradigm.

Sure. I wasn't saying otherwise. What I meant was, in a general sense (prior to really seeing the benefits first hand), it can be hard for people to justify the trade off when they feel like they can just "get it done faster" with a more ad-hoc approach to things. I didn't mean to imply Objectify was some how more difficult (I haven't used it, so I wouldn't dare comment on it in such a way).

>I don't buy that. My project has hundreds of single method classes and it's by far the best factored non-trivial application I've ever seen (anecdotal, obviously, but so it goes).

Agree to disagree, with a caveat. I'm not against having a large amount of "Helper" or in the case of what I'm most familiar with, "Extension" classes (godbless you, .NET Extension classes), but I think if you have so many that they comprise most of your code base, maybe you could consolidate some of them (and maybe you couldn't).

Personally, I try to keep 100% of my core business logic inside of "Service" style classes, and then anything that is more of a helper (in that it performs some work, but not "business logic", and does not require or alter internal state) in either a static helper, or an Extension on the type itself.

For example, I usually end up adding a .ToStart/EndOfDay/Week/Month suite of methods to the datetime object of most of my projects. A "DateTime Service" would be overkill, but an extension method (which is just veneer over a static helper) fits the model perfectly, in that it returns a new copy of the existing datetime, leaving the original intact.

But at this point we're getting pretty deep into the comment tree, so feel free to email me from my profile if you want to go more into the issue - I love shooting the shit over this kind of stuff. Regardless of any minor difference of opinions, I think what you're trying to bring to the rails community is to be commended.

-----


> Regardless of any minor difference of opinions, I think what you're trying to bring to the rails community is to be commended.

Thanks a lot, man.

-----


I gave an answer better than that. Did you read the post?

-----


I can see how that will give you a single-method class some of the time, and I'm in absolute agreement as to how it applies to serialisation classes, but I don't see how SRP implies that single-method service and policy classes are the One True Way.

I think I'll have to give objectify a try and see how it all fits together. It's a different enough approach to what I'm used to that I probably don't have a reliable intuition as to how it'll turn out in practice.

-----


Mixins/modules and open classes do not separate your class in to multiple components - merely multiple files. As I explain in the article, for separate components to be useful, they have to be "protected" from each other - encapsulation, in other words.

-----


Mixins (well, as they're supposed to be used) do provide encapsulation; specifically, they enforce the boundary between instance scope (e.g. access to instance vars) and method interface. I view them as a part of a coupling continuum:

[instance methods] --- [composed subclasses] --- [mixins] --- [the outside world]

But Modules provide more than that. module_function allows for unattached namespaced functions which can be referenced by full name, relative name, or imported into the local scope. Great way to express functions which are decoupled from instance state--much like the services and policies you're advocating for. It's an under-appreciated aspect of the language, I think.

-----


No doubt - That's just good OOP. Looks like this gem will help people achieve that.

-----


This would be funny if it made any sense and if it wasn't a ripoff of an old Merlin Mann tweet about DHH.

-----


A _why tweet? http://favstar.fm/users/_why/status/1640180235

-----


> ...a very complex system

Auto-pilot on a 747 is a very complex system. RubyGems is not.

-----

More

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | DMCA | Apply to YC | Contact

Search: