Request for a $this variable

Started by TedWalther, October 23, 2009, 12:01:51 PM

Previous topic - Next topic

Lutz

#15
Quote ... but my main gripe with it is not even efficiency, but rather how it limits certain coding possibilities ...


Putting efficiency issues aside, the reason you would want reference a data object directly is to modify it. If there was no need to modify data there wouldn't be a need for referencing.



From a program hygienic point of view: the more code you have in your program modifying data objects the more error-prone gets the code. This is why people have tried to to design languages completely free of mutable data objects. Change is described in a pure functional way.



The functional approach avoids modification of data objects and state. It sees modifying data as a necessary evil, you cannot live without to complete your programming task, but you try to avoid modifying data, where possible. The main reason that destructive functions where introduced in newLISP was for efficiency. Ideally 'set/setf/setq' would be the only destructive operations saving the final result of a computation.



Referencing data directly is a necessity only for modifying data but should be kept to a minimum, to make a program less error-prone. When you must use referencing for the sake of efficiency, e.g. passing big data objects to user-defined functions, newLISP offers the method of passing data contained in a default functor. For complex structured data objects context handles can be passed.

itistoday

#16
Quote from: "Lutz"
Quote ... but my main gripe with it is not even efficiency, but rather how it limits certain coding possibilities ...


Putting efficiency issues aside, the reason you would want reference a data object directly is to modify it. If there was no need to modify data there wouldn't be a need for referencing.



From a program hygienic point of view: the more code you have in your program modifying data objects the more error-prone gets the code. This is why people have tried to to design languages completely free of mutable data objects. Change is described in a pure functional way.



The functional approach avoids modification of data objects and state. It sees modifying data as a necessary evil, you cannot live without to complete your programming task, but you try to avoid modifying data, where possible.


I disagree, at least with regards to newLISP.



Code becomes error-prone with regards to modification when there are concurrency issues at stake, i.e. when it's possible that your data could be modified in a dangerous way. This does not happen in newLISP where everything is in the same thread.



Your statements sound very much like the arguments the author of Clojure makes, but one of the main reasons Clojure was created was to address concurrency issues in a language where multi-threading is possible and therefore modifying data can lead to serious issues.



The way that Clojure went about solving this problem was very intelligent, it did not allow you to modify data, but it also did not simply make copies of data either. Instead it uses entirely new data structures at the core of the language that allow for "purely functional modification of data" without copying. When mutating these structures (lists, hash tables, arrays), instead of making copies of the entire thing it makes a new structure that *shares data* with the old structure, thereby avoiding copying the entire thing.



newLISP does not really have concurrency issues yet it will copy entire data structures anyway, and when it does so the modified data structures are new copies, not the crazy advanced shared-data ones that Clojure has.



I thought that newLISP was supposed to be a simple and practical language that did not have to worry about these issues and therefore could take full advantage of the improvement in readability and performance that you have when everything is done in a single thread.



newLISP doesn't need to worry about the multi-threaded issues that other languages worry about. It's certainly possible to introduce them using shared memory between two newLISP processes, but why would you do that? And even if you did you can always use standard synchronization mechanisms. The vast majority of tasks newLISP is used for can be solved in a single thread, or by using the new actor functions.



Another reason that is championed as a virtue of functional programming languages is side-effects. Where modification leads to problems is with unmentioned side-effects. This however is not a fault of a language for allowing direct modification of data, but rather the fault of poorly written APIs that do not state what they actually do.



Saying that newLISP should be handicapped because of any of these reasons is in my view unjustified, and again, limits the capabilities of the language.


QuoteThe main reason that destructive functions where introduced in newLISP was for efficiency. Ideally 'set/setf/setq' would be the only destructive operations saving the final result of a computation.



Referencing data directly is a necessity only for modifying data but should be kept to a minimum, to make a program less error-prone. When you must use referencing for the sake of efficiency, e.g. passing big data objects to user-defined functions, newLISP offers the method of passing data contained in a default functor. For complex structured data objects context handles can be passed.


There are plenty of times when you would want easy reference passing. Any data structure needs this. Queues, n-ary trees, hash tables, priority queues, etc. All of these data structures need to be able to reference their data to be able to manipulate it efficiently.  Writing these data structures in newLISP is neither efficient nor simple.



The use of contexts (a global namespace and grouping mechanism) as pointers is, in my view, a hack and nothing more. Pointers should be anonymous because their use is quite common. If in C, for example, every pointer suddenly became a global symbol, you would not be able to use the language for any practical purpose. Yet this is what newLISP has done. For me at least, the use of newLISP's default functors as pointers is an option to be used only in the rarest of situations, particularly when it comes to writing modules for newLISP, otherwise I'd be liable to mess up someone else's code.
Get your Objective newLISP groove on.

itistoday

#17
I'm willing to accept that perhaps newLISP just isn't designed to be used in certain ways, and that to do certain things you either don't do them at all, do them in C instead, or use default functors (albeit sparingly). But I am simply frustrated because I don't see why this has to be the case. I really like newLISP and I wish I could apply it to a larger set of problems, but either I can't or the solution isn't pretty.
Get your Objective newLISP groove on.

cormullion

#18
Although I'd hate to see you go, I can't help thinking but that you'd be happier with something like http://programming.nu/">//http://programming.nu/. It's got the Obj-C stuff you know about, plus (presumably) much object-oriented orientation. And some iPhone activity. They could do with a new logo, though.

itistoday

#19
Quote from: "cormullion"Although I'd hate to see you go, I can't help thinking but that you'd be happier with something like http://programming.nu/">//http://programming.nu/. It's got the Obj-C stuff you know about, plus (presumably) much object-oriented orientation. And some iPhone activity. They could do with a new logo, though.


Thanks, it's good to know I haven't pissed everyone off with my ranting. ;-)



I did look into that a while ago actually and I decided I preferred newLISP. :-)



For iPhone/OS X type development I have no problem doing regular Objective-C (the non-garbage collected variety).
Get your Objective newLISP groove on.