Comments on: The problem with OOL is not the OO.
This article is in response to reboler Ratio who posted a few comments related to OOL in my R3 article about Concluding on object creation. And, it's a broad enough topic that it deserves its own article.
Perhaps you know of my history in OOL.... which began in the early 1980's when I was alpha testing Smalltalk at HP, which was from Xerox PARC. (But, it should be noted in fairness, I was also programming on an MIT Lisp Machine during those same days... not in Smalltalk of course.)
For more than ten years, I was a strong believer in OOL. A bit of a fanatic actually.
At Apple ATG, I worked with many from the Xerox Smalltalk team, and we pushed for stronger models of OO within software designs. And, we resisted as much as possible the introduction of C++ , which in fact Larry Tesler jokingly called it C+- (approriate, actually.)
In its purest form, OO is a model of associating behavior with state (function with data). Originally, back in 1982, it seemed like a good idea because real world objects had specific actions related to them. A pen was used to write and draw. A pencil was used to write and draw. We thought, "Wow, there's a pattern, and it seems to be quite natural."
However, it was a false model. A pen does not write and draw, it takes a human to make a pen write and draw. The actions of write and draw do not belong to the pen. OOL is not a complete solution. Too many of the behaviors of objects come from (or are influenced by) sources that are external to their encapsulated definitions.
After ten years, I concluded that OOL was not the answer -- but it was more from the practical reality that everywhere I used OOL it made my code more complex and more difficult to create, maintain, and improve. Whenever I used pure OOL, I lost productivity. (But, if I simply used OO concepts, even without an OOL, such as in the Amiga OS or REBOL kernels, it made the programming model cleaner and easier to understand.)
I realize that in today's programming world, I am a heretic. OOL is ingrained within the fabric of nearly all modern software, justified in terms of cost savings, but rarely withstanding any detailed cost analysis of that claim.
Joe Armstrong (Erlang) once said "The problem with object-oriented languages is they’ve got all this implicit environment that they carry around with them. You wanted a banana but what you got was a gorilla holding the banana and the entire jungle."
However, I think that statement is incorrect. The problem is much deeper than that. The problem with OOL begins when you try to encapsulate behaviors, that almost always have external influences, and cracks or divisions begin to occur within the class definition. It breaks apart, and quickly the situation becomes pathological (diseased).
The idea of implicit environment (large or small) is a good one. That's what we call context in REBOL, and it's the cornerstone of the language. That part of OO is fine. (And in fact it's the reason there's an 'O' in the word REBOL. Also, it sounds a lot better than REBCL.) As humans our thoughts and our languages exist within layers of context, a hidden framework, the primary environment of interpretation. Without that context, thinking and communicating would be impractical.
So, that is what we mean when we talk about objects in REBOL. It's about the context of interpretation, and the fact that we really do want that environment wrapped around our expressions. It makes communicating (i.e. programming) so much more efficient.
I don't think you've ever heard me make claims about REBOL being an OOL in the classical sense of the definition, but more of a variation on the idea. It supports many OOP practices, but we don't beat the drum that these are necessarily the best methods to solve problems - really, we prefer language-oriented-programming (of which DSL is an important part.) So, I think at a fundamental level, we agree.
PS: I should also link this old Eric S. Raymond article, Unix and Object-Oriented Languages.
34 Comments Comments:
Kaj 2-Sep-2009 5:55:33 |
Thanks for that narrative explanation. This is the kind of thing we need to sublimate our thoughts about the wider model behind REBOL and to explain it to others. | ChrisH 2-Sep-2009 9:02:35 |
The strongest believers can become the most vocal non-believers (and vice versa). It's sad to see that Carl has (seemingly) swung from one extreme to another, rather than realising that OOP is just a tool - which is appropriate for some situations & not for others.
Use OOP (or any tool) in the wrong situations or the wrong way, and of course you will have problems. OOP is *not* a universal panacea (despite the hype), but that doesn't mean OOP is useless. I personally tend to stick with using OOP for making Abstract Data Types (ADT), but it does have wider uses if you are careful. | Carl Sassenrath 2-Sep-2009 11:07:44 |
Kaj: Yes, and let's hope it will be understood in that way.
ChrisH: I hope my opinion in this article didn't imply that. I've not swung to the extreme but rather look at it precisely as you've stated: it's a method, a tool. Use it as needed. (You've hit it right on.)
REBOL has OOP capabilities, and for example, the GUI benefits from those. I would not attempt to code the GUI without OOP. In addition, various parts of REBOL are OO-ish, but not pure OOL, in the traditional sense of the term.
I think of OO, OOP, and OOL as different things. OO as a way of thinking, OOP as a programming method, and OOL as a language intended to support an OOP method (of various flavors.)
As an OO example: I once worked for a very OO company, HP, which back in the day encapsulated each team as an "object" with its own
"functions and state" -- a kind of MBO++ (management by objectives, but even more encapsulated). It worked very well, and made HP hugely successful in development of great products (but from what I hear, it has changed now to a more traditional profit-driven not invention-driven model.)
| Ratio 2-Sep-2009 17:06:05 |
Hi Carl, thanx for your answer.
As always I basically agree with you. I only doubt that OOP/OOL is of any real advantage.
Why just in GUIs and not everywhere? ;-) Is a button logically another thing than a pencil or a horse?
It is NOT. Neither in GUIs nor in other graphical things. Internally all is based on functions.
Sure, some developers are happy to create a few dialogs or display pictures. So they jubelee OOP. I see and disgust that since decades. :-( They normally are beginners or players, not (yet) serious application developers.
Nowaday HP's problems to provide a useable manager for a little printer might be rooted here. As I mentioned: 700 MB pure rubbish. All show, no substance
The question to all OOP/OOL fans is:
Why should we call any function via "object"/path/path/Xfunction... if we can have it easier and just call Xfunction directly? Why do we have to "attach" functions to
That's the question which must, but cannot be answered by all OOP/OOL fans.
-----------
To speek from myself: We have not just a few, we have hundreds of dialogs.
So we need a generic, i.e. functional solution for that. OOP/OOL even in REBOL needs an overhead which isn't possible to handle and to struggle with again and again.
-----------
All users already have lots of negative side effects of the OOP approach, e.g.:
Users cannot call the functions creating e.g. a button (returning its structure). The button is - as a so called "keyword" - hidden within the LAYOUT function!
Same applies to all other widgets or "faces".
REBOL itself certainly uses functions to create buttons etc., or not? ;-)
I'm sure you do! ;-) ...and why are users hampered to do that?
-----------
Another problem. You mentioned it yourself earlier:
The "normal" handling of structures/arrays/blocks/series (which an "object" certainly is) is not (yet?) possible.
In our applications we have lots of generic array functions. All are based upon the possibility to adress all(!) arrays via index!!!.
If not giving up OOP totally. At least this should be made possible (or better be allowed ;-)) for REBOL "objects" also. Users could then use "objects" in a more generic way using the normal functions, simply skipping or using the Column names.
REBOL already IS an extraordinary, powerful IT language. Nonetheless: as everything it could be improved. ;-)
The most basic and therefore most effective way is to abolish all OOP/OOL - sorry - nonsens.
REBOL/view would be much easier to use - and shrink a lot ;-)
Ratio
| Ratio 2-Sep-2009 17:18:55 |
Sorry: There is a small html syntax error in my previous posting, correction:
Why do we have to "attach" functions to anything?
Ratio
| Gerard Cote 2-Sep-2009 19:29:01 |
I'm new to OOP and my first serious attempt to learn them is recent. It comes to reading the Russ Olsen book about Design Patterns in Ruby. In fact my objective is to see how easy it will be to port these most OO concepts to REBOL. And even without having done much OOP with REBOL I see it will be very easy for the most part. So much in common.
But the author also takes time to show the dynamic Way Ruby is acting and in this sense it is similar to REBOL dynamic side - but to my simple knowledge REBOL is even less limitative in its way to permit things to be done.
And as the author points out in his book, OOP is limitative in many ways similar to what Carl said above. The context is useful but external events often tend to require more flexibility than what is encapsulated into classes, so delegating outside the Objects themselves some logic is part of getting the missing OO flexibility and it seems to be one of the tricks to adopt to be efficient in OOP.
A nice demonstration from Russ about the OO concepts and how to use them well into real applications. Will say more later about it on the ML.
Already recognized many "native" patterns implemented right into REBOL - thus requiring no porting but offering direct access. Thanks Carl for this vision. | shadwolf 2-Sep-2009 21:23:30 |
Nice explanation Carl.
I like the rebol flexibility the power to choose what coding strategy you will use at momment in your code isn't it what we call freedom ?
As i'm able to choose how i organise my script i want to be able in some precise case to be able to choose what memory management i want.
That doesn't means i will base all my scripts on that feature that doesn't mean my rebol scripts will look like a C++ or a java source code. That just implicate some times i will be sure the things i want to be gone are gone for good and that they won't make a later unexpected comeback.
one short example from viva-rebol that illustrate that:
If i do that:
clear lay
lay: [ origin 0x0 space 0x0 backdrop white]
then lay is keeping the previous data stored in it. So when i do a second load of a file lay countains the list of the function of the first and the second document mixed together like an "append".
But if instead i do that ->
lay: make block! [ origin 0x0 space 0x0 backdrop white]
Then lay (which is a local var to a function) only contains the functions list of the currently shown document. There is no list "append" effect anymore
Then i don't know if the previous list as desapear from memory or not and all i can expect it's it have been the case or that it will be the case.
See the function clear exists but it's not doing what we expect from it. Clear variable -> kick the current content out of memory that's all.
Now do i care clearing each and everything like it could be the case in C C++ JAVA etc.. NO!! but if it's an heavy block! and heavy list! or an heavy objet! or a var that countains a string! representing 300 line text file then yes i do care.
| Steeve 3-Sep-2009 4:54:51 |
Hmm... Shad, your examples make no sense.
>>clear lay lay: [ origin 0x0 space 0x0 backdrop white]
"then lay is keeping the previous data stored in it"
wtf, what do you meant ??? | Luis. 3-Sep-2009 8:41:32 |
Hiya,
I think it's more than just 'The right tool for the right job'. More than the context if the systems involved are over a certain size. It's also comfort: Some people are more comfortable thinking in/manipulating objects, others prefer the other route.
Performance and other issues aside, getting the job done is often a higher goal than the route taken to achieve it.
That being said, I miss Z80 assemler...
Cheers,
Luis.
| Luis. 3-Sep-2009 8:43:24 |
Agh!! For 'assemler' (sheesh!) read 'assembler'.
Anyroad, we're all right and we're all wrong.
Cheers,
Luis.
| Ashley 3-Sep-2009 18:16:56 |
Personally, I've found that using objects to hide the details combined with a few global functions to access the object's words seems to work rather well in REBOL. My typical usage pattern for objects is:
ctx-app: make object! [
...
set 'access-func make function! [] [...]
...
]
The object is then a self-contained 'black box', and the global functions have full access to the 'internals' of the object. I'm far less concerned whether this meets the strict definition of OOP or functional programming than with the ability it gives me to group and access related bits of functionality. | Shadwolf 3-Sep-2009 21:07:39 |
>>clear lay lay: [ origin 0x0 space 0x0 backdrop white] "then lay is keeping the previous data stored in it"
it means what it's writen -> when you load a second document lay keep the previous data and append the new datas at the end of it...
lets take an example (we are in Rebol 2)
I load a file and i create a list of function in it
so lay countains the VID dialect instruction to create on scren the list of widgets. But normally lay is "freed" at the end of the function since it's a /local var
but maybe because the lay reference it's transfered to
a "countainer" face of box type it's not freed and it remains as it. Then maybe in this case a copy/deep in the affectation of lay in bx/pane would alow lay to be a canceled reference (i'm not sure I understand it well see it's supposed to be easy to deal with... but it's not)
So when i load a new document in this version of the function without a make to reinitialise lay, then lay still countains the previous content and as lay is countaining " VID dialect idioms" (hope you appreciate the efforts Carl to speak with the proper rebolish descriptors :P) then the new idioms are added to the end of lay and that's like an append effect.
Using lay: make object! [...] instead of clear lay then allow me to get what i expect a reinitialisation of lay contents each time i run the function involving lay.
Yeah ashley that's a particularity appreciable in rebol object concept. I use that too often.
| -pekr- 3-Sep-2009 22:05:40 |
Shadwolf, your code is wrong :-)
>> clear lay lay: "aaaaaa"
** Script Error: lay has no value
** Near: clear lay lay: "aaaaaa"
| -pekr- 3-Sep-2009 22:12:06 |
Maybe what shadwolf tries to point out is, that when you do your layout, then layout dialect creates hierarchy of faces on low level.Unsetting of layout does NOT free the memory used, does not undefine those faces:
>> lay: layout [b: button "OK"]
>> view lay
>> lay: none
== none
>> b
>> type? b
== object!
So - you consumed system resources without easy ability to undo the once viewed layout content ... | shadwolf 4-Sep-2009 8:02:26 |
Pekr no my code is not wrong that's my explaination which is hard to understand, if you don't see the whole code of this function.
I will try to make it more clear. Ok to reproduce that "problem" you can do it with this minimal code
>> my-func: func [ /local lay ] [ clear lay lay: [] insert tail lay 1 bx: lay ]
clear lay should reset lay when you recall the lay
or the affectation lay: [] should to say hey we affected to lay a new content so create a new reference in memory.
>> my-func
== [1]
>> probe lay
** Script Error: lay has no value
** Where: halt-view
** Near: probe lay
>> probe bx
[1]
== [1]
>> my-func
== [1 1]
>> probe lay
** Script Error: lay has no value
** Where: halt-view
** Near: probe lay
this means lay is not accesible from out side the function "context" it's normal since it's a /local variable (In Rebol 3 the local variable have been solved anyway so I'm talking about things that would not exists anymore but that can show the interest of having a closer memory management dictated and choosed by the coder)
>> probe bx
[1 1]
== [1 1]
the only why to really affect a new memory older to lay
is to replace the clear lay lay: [] by lay: make block! []
>> my-func: func [ /local lay ] [ lay: make block! [] insert tail lay 1 bx: lay ]
>> my-func
== [1]
>> my-func
== [1]
>> probe bx
== [1]
But then my previous contents of lay and bx in memory i don't know if they are supressed from memory or if it will be supress from memory. Which is not a problem when you deal with some intergers but which can be a serrious probleme when you deal with loaded in memory text files.
by adding a prechecking in the my-func we obtain something strange
>> my-func: func [ /local lay ] [ probe lay clear lay lay: [] insert tail lay 1 bx: lay ]
>> my-func
none <- that's the result of probe lay
== [1]
>> my-func
none
== [1 1]
So when i enter anytime in this functionlay have no value
which is normal since it's a /local var and have life time span only during the inner function instruct when we are out of the function it desapears. But when we do
lay: [] what i should expect is rebol to understand that a new value and not a call to a previous reference.
Now lets probe lay after the lay: [] to see that effect
>> my-func: func [ /local lay ] [ probe lay clear lay lay: [] probe lay insert tail lay 1 bx: lay ]
>> my-func
none <- lay countains nothing
[] <- here lay is affect with an empty block
== [1]
>> my-func
none <- lay countains nothing
[1] <- here lay has a value comming from the previous execution of my func and that's not logical. In the first execution of the function I get lay: []
doing what I expected lay stared an empty block!. So I expect when I call again this affectation and since lay at the start of my function countains nothing to obtain the second time the same effect, lay countains an exmpty block! and not the previous value of lay comming form where??? I don't know !!! and that's the problem !!!
it's not logical, if lay is local and anytime before it's affectation it's value is none then any time when i affect something to lay this something should not have a "wake up previous values" effect.
== [1 1]
I hope i was cristal clear this time but if you have more asks and want to discuss why we see that and if in rebol3 we will still see that then i'm open to the discution any time ^^.
thank you for reading me and I'm sorry if my previous explainations were too fuzzy.
(blog doens't likes long posts) | -pekr- 4-Sep-2009 8:23:24 |
I think you might be mistaken here. You know what's happening? You simply assign your 'lay word to the stand-alone block [], which can exist on itself, the same way, as "" does. It seems that function preserves its context, and hence keeps the address of the initial [] block and then reuses it, but we might need some gurus to answer that here. See my example:
>> test: func [][var: "" insert var "a"]
>> test
== ""
>> test
== "a"
>> test
== "aa"
>> test
== "aaa"
>> test
== "aaaa"
>> test
== "aaaaa"
Use: lay: copy [] in your example ....
I had something different in mind - not being able to unset all GUI related elements:
>> lay: layout [b: button "OK" []]
>> view lay
>> unset 'lay
>> probe b
make object! [
type: 'face
offset: 20x20
size: 100x24
span: none
pane: none ...
... as you can see, 'b button face still exist in memory. Dunno if there is any solution of how to scrap all memory related resources, once you unview your GUI. Maybe wrapping it into some context, I don't know ... | shadwolf 4-Sep-2009 8:51:35 |
pekr, how this ->
>> my-func: func [ /local lay ] [ clear lay lay: [] insert tail lay 1 bx: lay ]
is the same than that ?
test: func [][var: "" insert var "a"]
first thing first in my code lay is LOCAL to my-func
In your code var is GLOBAL context related so the "append" effect is LOGICAL in your case not in mine.
A local var is suppose to have no value when the function starts and when you give a value to this local var then this value should be always considered as NEW !
but what i see is that when i affect something to lay ot using make then the previous value is restored into lay.
which is an LOGICAL non sens.
Lay has a none value i affect an empty block! to it then it's value is [] then i insert something in it lay value is [1] which is what i expect to get.
until that point all is logical and coherent.
Same code second run.
lay have still no value when entring the function, then i affect empty block! to lay (same way I did the first time) then instead of obtaining lay: [] I obtain lay: [1]
which is a non sens!!!
Where is the hell have you seen it was logical a new affectation provokes a call back of previous content of a memory chuck supposed to not being linked anymore to this variable.
entring the function my-func lay is set to none any time yes or not ?
that's not like it was KEEPING the refference to the previous data. When you enter a second time to this function.
Which is the case and is logical, when you use gobal variable by the way. In your example pekr.
A non sens is an unexpected effect.
| shadwolf 4-Sep-2009 8:56:33 |
lets forget about the "clear lay" which has no impact
and lets forget about the "bx: lay" which has no impact too.
I though that could be an explanation to that "callback" effect but it doesn't.
So we have this function:
my-func: func [ /local lay ] [
probe lay
lay: []
probe lay
insert tail lay 1
probe lay
]
first run of this function.
you obtain :
>> my-func
none <---1st probe lay
[] <--- 2nd probe lay
[1] <-- 3rd probe lay
the results are what is expected. | Shadwolf 4-Sep-2009 9:32:39 |
I made another test
my-func: func [ /local lay ][ probe lay lay: [] clear lay insert tail lay 1 probe lay ]
In this case i obtain the expected results when I do recursiv use of my-func.
So my conclusion is. And it's a supposition. When you do lay: [] the same memory location is revived to store the new content. When you then use clear lay the content of this memory location is "cleared" from any previous content.
When you use lay: make block! [] then you force rebol to change the location in memory where the block! and it's content will be stored. And the prévious location in memory and it's content remains until recycle deside to remove it. So in the lay: make block! [] we obtain a memory eating effect hard to predictate.Instead in the "lay: [] clear lay" we have a "memory reuse" effect which leads to a better memory management ?
| shadwolf 4-Sep-2009 10:22:46 |
I had a chat with Steeve on alt me and he explained me why
I got this memory comeback effect.
Here is steve explaination:
>> my-func: func [ /local lay ] [ lay: [] append lay 1]
>> source my-func
my-func: func [/local lay][lay: [] append lay 1]
>> my-func
== [1]
>> source my-func
my-func: func [/local lay][lay: [1] append lay 1]
>> my-func
== [1 1]
>> source my-func
my-func: func [/local lay][lay: [1 1] append lay 1]
as you can see the internal code of my-func is modified by rebol. I always thought a rebol function code was static.
Ok now I understand the thing but that still not logical for me...
And for the mémory management issue I was right or wrong in fact (eating effect / reuse effect) ?
| Steeve 4-Sep-2009 11:44:37 |
Well Shad ;-)
As you know , in Rebol, code is data and data is code.
There is no different treats between a block containing code and a block containing data. | shadwolf 4-Sep-2009 18:00:48 |
I knew you could use rebol to write rebol code.
but i was far to imagine the VM would change the code of a function that way.
| Grant Rettke 4-Sep-2009 21:21:49 |
Carl, check out "Component Oriented Programming". Arguably it is proof that the industry recognizes that OOP "just don't scale right". | Ratio 7-Sep-2009 18:04:55 |
Hi folks! I'm dreaming... ;-)
With normal function syntax it would be no problem to create almost all buttons we need in a generic subroutine "makebutton".
We would define just the button label we want, send it to our subroutine and would get back a fully functional button definition usable in layout/view or RebGUI's display function.
After sending for example just "Yes" we would get back something like this.
button "Yes" #"y" [result: #"y" unview]
Also of course we could and normally would send our subroutine a whole bundle of buttons we actually need:
allbuttons: ["Yes" "No" "Delete" "Cancel" "Read" "Save" "Anything" "Etc.pp"] ...
We would get back perfectly defined buttons without writing all the special stuff for all the different buttons again and again.
I now really tried a lot to achieve the same with current REBOL 2 OOP/OOL.
Surprise! After hours I found a way to create correctly displayed buttons with code like this:
(shortened)
foreach xbutton allbuttons
[xkey: lowercase first :xbutton
append blk reduce ['button xbutton xkey ]
]
return blk
With some other rather peculiar settings it works so far.
But I was unable to append a functional action block so simple as it looks:
[result: xkey unview].
The code is appended but not working as needed, partly because xkey always gets the same (last) value and function unview seems ignored or misunderstood.
Tried it with 'words, arrays of the xkeys and a many other ways. Perhaps there might be a solution. But in hours of work I couldn't find it.
Why do I write this?
The reason for these problems is the hardly generizable OOP concept.
OOP establishes a totally superfluous parallel system to the function syntax and produces much more problems than it is (wrongly) assumed to solve.
As I know it from other systems, also in REBOL it would be a good idea to allow developers to use the functions used by OOP internally at their discretion directly, too.
But we would be better off to abolish this 'modern' - sorry - nonsens completely. I never missed it, I never liked it, I simply try to avoid it wherever I can.
Ratio
| Ashley 7-Sep-2009 18:20:39 |
Try using compose, as in:
insert tail blk compose/deep [
button (xbutton) (lowercase first xbutton) [
result: (lowercase first xbutton)
unview
]
]
| Ratio 8-Sep-2009 10:59:34 |
Yes, works indeed!
Thank you so much, Ashley!
Ratio
| shadwolf 8-Sep-2009 21:44:42 |
that's the ability in rebol to create script that generates sub-scipt automatically that's particularly interresting in VID and draw since they are dialect and that rebol don't make any difference betwin code and data.
so at certain momment data can turn into code and code can turn into data. only matters if you call the dialect or not.
| Ladislav 9-Sep-2009 7:31:37 |
Pekr: "...It seems that function preserves its context, and hence keeps the address of the initial [] block and then reuses it..." Please, do not repeat this nonsense. I tried so many times to straighten this, that I am pretty sure you must have already read it is false. The effect does not depend on the fact, that the function context is preserved. You can make sure about that in R3, where functions don't preserve their contexts, but this effect still exists, since functions *preserve their bodies*. | Ladislav 9-Sep-2009 11:46:43 |
Shadwolf, this is a simplification:
my-func: func [/local lay] [lay: clear [] append lay 1 lay]
in this case the function does not create a new block every time it is called, it always (re)uses the block that happens to be the third element of the my-func's body. Therefore, no garbage collection is needed, as you correctly wrote.
If we use
my-func: func [/local lay] [lay: copy [] append lay 1 lay]
, we don't have to clear the third element of the my-func's body, since it is not modified (we modify its copy). On the other hand, we always create a new block, which needs to be garbage collected after it becomes unreferenced. No "memory eating" occurs, but this implementation surely is slower, requiring work from the GC. Neverheless, the two implementations are not identical, and we have to make sure, that the one we use is appropriate for the specific job. | Ratio 16-Sep-2009 15:03:42 |
... BUT I'm not convinced of ANY OOP at all
Even worse, that even a genius like Carl sometimes liked it and still presents it to users in his VID.
Sorry to all beginners in programming:
OOP/OOL is a basically WRONG path - from the beginning.
Ratio
| William Payne 13-Dec-2013 6:42:29 |
Here is my take on the debate:
http://williamtpayne.blogspot.co.uk/2013/11/reasoning-about-state-evolution-using.html
As you can probably tell from the above, I think that OO concepts are frequently useful, but that the OO modelling approach to application development is a poor fit for many numerical & algorithmic applications. | Pierre 10-Jan-2014 0:39:28 |
(at)William Payne: interesting point of view.
I always had a hard time writing in an object-oriented way; my mind always tends to bend towards the more "classical" (variables, arrays, functions, etc.) way.
Although I admit that using objects made by someone else is often quite comfortable.
One advantage I can see to OO is that, when I finally achieve a useful piece of code which actually works, I *try* to wrap it inside an object, which would then /only act as a container to reuse my code elsewhere, in a "hermetical" way. I did not always succeed doing so, though...
Thanks for your point of view: it actually encourages me to keep on coding with an old-style, out-of-fashion, but efficient (imho) way! | Pierre 10-Jan-2014 0:50:47 |
Sorry, I should have said that not /only your point of view was interesting, but also the ones expressed in http://hadihariri.com/2013/11/24/refactoring-to-functionalwhy-class/ and the ones expressed here.
(at)Ratio: your opinion is quite abrupt; I think that in some cases though, OO is still interesting. But not to a beginner, I agree.
Now, our beloved Rebol is so atypical as a language (I realise this daily, since I began re-diving in it) that the question of OOP is almost secondary, since we can program things in a much more original way (by using parse, especially). | Fork 1-Aug-2017 5:29:51 |
(at)Carl: C++ is not a prescriptive "objects-only" language like Java. It permits "free" functions (non-members) and templates. If you look at std::algorithm, for instance, it contains many familiar things:
http://en.cppreference.com/w/cpp/algorithm
Hence, you do not call the ".sort()" method on a list. sort() is a free function, to which you pass iterators.
While I understand many early class libraries did not do a good job of separation of concerns in this way, modern C++ as practiced by professionals does things in a way I'd imagine you would find sensible (notation aside). |
Post a Comment:
You can post a comment here. Keep it on-topic.
|