Arc Forumnew | comments | leaders | submitlogin
4 points by bOR_ 6166 days ago | link | parent

There was this bit of text on paulgraham.com that made me blush: http://paulgraham.com/noop.html

  Back in the days of fanfold, there was a type of programmer
  who would only put five or ten lines of code on a page, 
  preceded by twenty lines of elaborately formatted comments. 
  Object-oriented programming is like crack for these people: 
  it lets you incorporate all this scaffolding right into 
  your source code.

Managed to reduce my host-pathogen model (which seems a perfect match for oop) from 600 lines to 120 lines (and speeding it up quiet some) by dropping all objects but the hosts, which are now reduced to being arrays of size 4.. so as any proper weathercock I'm off objects for a while. Perhaps instruct us on when objects are a good idea?


4 points by bayareaguy 6165 days ago | link

In Arc (and most other functional languages), you generally solve your problem by specifying how to transform some input into some output. It should be no suprise to anyone here that this is a great fit for the most visible aspects of Web programming.

In OOP you instead solve your problem by trying to neatly partition it into lots of little bits of state and specifying how each little bit reacts to changes. As the comment explains, OOP programs are often clumsier than functional ones because OOP enshrines scaffolding in the form of the class hierarchy and method/message dispatch model.

So when is OOP a good idea?

I tend to think that it boils down to the size and organization of your team, the number of independent "architects" in your system and how they are managed.

In a small team this should not be an issue and you're probably better off with a functional approach and perhaps rolling your own messaging scheme like the one in the article if you think you need one.

However in a large team you not only have to deal with whatever problem you're working on, you also have to deal with the secondary problems of how the developers interact with each other. The OOP scaffolding pg makes fun of is one way to make managing a larger team easier since it helps the developers play nicely, stick to their little part of the system and stay out of each others way. It's not the only way, but it is relatively popular in part because it allows some management decisions to be directly expressed in the class hierarchy and programming language.

Right now Arc doesn't look like a language for big teams, but perhaps with a good module system that could change.

-----

4 points by absz 6165 days ago | link

I do think you leave out an important class (no pun intended) of problems for which OOP is helpful. Simulation, windowing systems... these are modeled elegantly by using classes and objects. In other words, OOP seems to me to be a good fit when the problem you are trying to solve deals with objects. The problem lies in trying to coerce other problems into noun-land.

-----

4 points by bayareaguy 6165 days ago | link

I think pg agrees with you in http://paulgraham.com/noop.html when he writes:

5. Object-oriented abstractions map neatly onto the domains of certain specific kinds of programs, like simulations and CAD systems.

Also for things like instance creation and method dispatch, OO languages can easily be both faster and more concise than functional languages. In a performance-sensitive setting like a desktop gui or a window system this can easily decide the issue.

But while simulation and OOP do have an important historic relationship, I don't believe you actually gain any special modeling expressiveness by making your objects adhere to a "class" framework. What's worse, the hardcoded assumptions OO languages make about classes and methods can confuse the assumptions in a simulation (e.g. because you can implement an "IS-A" relationship with inheritance doesn't mean you should).

If you want objects in a functional setting, you can just create the appropriate "factory" functions and have those functions return "objects" (i.e. functions with state in closures) which dispatch "methods" however you want them to, just like Jim Rankin did in the article at the top of the thread.

Personally I prefer the approach in SICP ( http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-19.html... ).

-----

2 points by absz 6164 days ago | link

I've skimmed the SICP link, and that does look like a good method. But I don't think they're mutually exclusive. As Jonathan Rees points out (http://paulgraham.com/reesoo.html), the definition of OOP varies; having just inheritance (coughjavacough) does make that problematic. Ruby's mixins and duck typing allow "is-a" without inheritance, thus alleviating some of the complaints.

I think that describing certain things, e.g. a windowing system, in terms of classes and objects does result in a useful description. "My window contains a button and a text field" maps nicely to an OO model. The implementation can (perhaps should) be user-level and/or functional with closures, but that modeling system can be powerful.

And of course, some of this is "taste;" I can't think very well in a visual paradigm, but I love a symbolic one. OOP may be orthogonal to your mental processes, in which case don't use it.

-----

2 points by jimbokun 6165 days ago | link

"Personally I prefer the approach in SICP ( http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-19.html.... )."

I was negligent in citing prior work. I had SICP in mind when I wrote my code.

The main differences are I wrapped it all up in a macro, I supported inheritance, and "method invocations" require one less set of parentheses:

    (define acc (make-account 100))
    ((acc 'withdraw) 50)
    50
    ((acc 'withdraw) 60)
    "Insufficient funds"
    ((acc 'deposit) 40)
    90
    ((acc 'withdraw) 60)
    30
I also didn't allow for initial arguments (yet). And you need to say "(vars 'varname)" to get values in method bodies instead of just "varname." I could probably fix both those things together.

But, generally speaking, the goal was to provide a macro for creating SICP style "objects."

-----

1 point by NickSmith 6165 days ago | link

Be interested to read your code Jim with your 'fixes'.

-----

1 point by jimbokun 6166 days ago | link

Excellent question. I think it deserves at least a blog-length answer which I hope to get to soon but first a couple thoughts here.

First, how many comments do you count in my code?

Second, I think my class definitions are pretty concise, as class definitions go.

Third, Paul said somewhere he doesn't use objects but does use hash tables filled with closures. That is precisely what my objects are. It just provides a brief syntax for defining them. If there is a way to define hash tables filled with closures with even greater brevity I'm all for it.

Fourth, Arc has opened the door to data in functional position and I find that a huge win over other Lisps. I think this should be available to those hacking with Arc, not just the language designer. Maybe another way of saying this is give hackers the ability to create new types and define what they do in functional position and defining "setters" that work with =. Objects are one paradigm for doing that but if there's a better, more Arc-ish way that would be awesome, too.

Fifth, I think this can be a pedagogically useful example to someone coming from, say, Python or Ruby to Arc. I believe that it can help bridge the understanding gap between objects on the one hand and first-class-functions + anonymous functions + closures on the other.

Well, that turned out longer than I meant to type right now, but I appreciate hearing others' thoughts.

-----

4 points by mnemonicsloth 6166 days ago | link

The first form does tell you how to

   make-meth

-----

1 point by riffraff 6164 days ago | link

Maybe, well, the usual polymorphic dispatch? Take the tipical "foreach" loop in ruby/python/java/c# for var in list dostuff

all rely (through coroutines, lambdas, side effects) on the list to know how to be iterable. If you change from a cons list to an array/file/socket/prime generator it will still work.

Of course, perfectly doable with, say, haskell type classes, but I don't know how to it in arc. Any hints?

-----