(show&tell) Def-Con-Function, What's Your Function*

Started by m i c h a e l, May 13, 2006, 07:45:56 AM

Previous topic - Next topic

m i c h a e l

*to the tune of "Conjunction Junction", a popular children's educational commercial (did I really just say educational commercial?)



The Def-Con-Function I'm referring to in the title stands for default context function, and it's the means to the end for a little programming dream I've had for some time now. To spoil the ending for you (don't worry, I know what I'm doing), it ends badly. How so? I wouldn't dream of spoiling the ending for you ;-)


-> (words Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
("Jan" "Feb" "Mar" "Apr" "May" "Jun" "Jul" "Aug" "Sep" "Oct" "Nov" "Dec")
> (words:help)
words
syntax: (words sym*) -> (str*)
Returns a list containing a string for every sym. Can be empty (no args).

example:

-> (words Mon Tue Wed Thu Fri Sat Sun)
("Mon" "Tue" "Wed" "Thu" "Fri" "Sat" "Sun")
> (words)
()
> (words:test)
"ok"
> (words:test -v)
The following should look identical:
("this" "is" "the" "way" "we" "wash" "our" "clothes")
("this" "is" "the" "way" "we" "wash" "our" "clothes")
> ; wheeeee!


Calling a function function. That was it. That was my big dream. Actually, at the time, I wanted to send a message to a message. It began while experimenting with Ruby's natural way of chaining methods together, and I found I wanted to call a method on the method I was typing at the command line. Why? To ask it (remember we are in objectland here) for help on using it or to test it, for example. This is all happening on the command line, so the idea was to talk to the method right then and there while I had the object (method) in front of me. An example might be:


:ruby> carton.open.unpack(table).sort(_#<-- right here

      

At this point, I think to myself, what is the symbol I pass in to sort by size? So what I wanted to do is backspace over the left paren and proceed:


:ruby> carton.open.unpack(table).sort.help
sort

syntax: sort : Array <- Array <- Symbol

Bla bla bla . . . the symbols are :size, :weight, :age, etc.

   

There's my answer: :size, so I can continue:


:ruby> carton.open.unpack(table).sort(:size).show

   

That's were the idea began, and I have wondered how I could implement something to this effect in most every language I have studied since.



If you're still unclear on the difference between what I wanted and what would actually happen if I sent help to the table returned by (unpack), then realize that instead of wanting to send a message to the receiver, I wanted to send one to the message I was intending to send to the receiver. A message to the message.



The value of being able to do this is questionable, but preserving our flow while coding is a big deal and should be aided whenever possible. Bringing the answer as close to the question as we can through minimal effort on the user's part helps keep us on the plane (a sailing term).



Is this a language or an IDE issue? I just don't know. I do know that if a language had the power of an IDE built right into it, that might be one of the easiest languages to program in to date.



Really though, I realized the OOP languages I'd been using were not OOP enough, as I could not send messages to the messages. Are messages objects? I needed them to be in this case.



Here in newLISPland, we're blessed with not having to worry about all that OOP poop :-) In fact, the ability to do what I wanted is built right into newLISP! Default context functions let us call functions in a context (this is normal), but they also allow us to call functions that seem to be part of functions themselves (neat!). Function functions!



Now, here is the bad part I mentioned in the beginning. This technique is mostly useless. Yes, I finally get to experience calling a function function, but like most dreams, it has a way of looking pale and small, once realized.



I've found this lends itself mostly to contexts with one function called repeatedly or by default. I have this situation in my ob context where I normally call the . . . well, maybe we should leave that for another time ;-)





m i c h a e l

Lutz

#1
The chaining of functions you use in your Ruby example would correspond to nesting of functions in newLISP:



(unpack (open carton) table)


newLISP is mostly a functional language. Contexts can be used for simple prototype OO, but there is only one level of objects, i.e:



(unpack (carton:open) table)


The default function in newLISP is meant to hide the context and write functions with static, isolated data, which appear like normal functions. This would be an example for a simple generator function, which gets initialized and then keeps state:



(define (acc:acc x)
   (if x
     (set 'acc:val x)
     (inc 'acc:val)))

>(acc 100)  ; initialize generator to 100
100
> (acc)
101
> (acc)
102
> (acc)
103
> acc:val
103


The function you are really calling is (acc:acc) but the default mechanism lets you just say (acc) and all data and internals are hidden in a context closure realized by context 'acc'. You could look at 'acc' as a simple prototype object and copy it with 'new':



> (new acc 'myacc)
myacc
> (myacc 20)
20
> (myacc)
21
> (myacc)
22
>


The other, more used purpose of contexts in newLISP is the ability to partition bigger code bases into smaller isolated modules. These modules are first class objects, you can create or delete them during runtime and pass them as parameters by reference in functions or look at them as protoypes from which copies can be created. But they are not meant for heavy OO programming as seen in the Java or Ruby.



Again, the main programming model in newLISP is the functional paradigm.



Lutz

m i c h a e l

#2
Thank you, Lutz, for clearing up any confusion I may be stirring up here. I had hoped that by using the (show&tell) label on my posts it would convey a sense of playfulness, as they are not meant to be taken too seriously. I have never programmed computers for a living, and my interest in programming definitely falls into the hobby category. Originally, I considered putting a disclaimer at the top of my show&tells stating that you should skip the following if you have actual work to do or are not one for levity :-)



What Lutz considers the language to be, I consider it to be. No paradigm bigot here. I learned from Grady Booch to respect the style of the language used. But, as you my have guessed from my reference to Booch, I have been in the OO mindset for much of the time I have been studying languages. And, of course, with languages, come paradigms. As Lutz makes clear, newLISP is more naturally suited to the functional approach. My experience with functional programming has always been positive, and there are times when I feel a real affinity with it. But, shifting paradigm gears requires a great deal of discipline, and sometimes, I find myself stuck in "last language" gear when trying to learn a new one. I have already begun to embrace the way contexts are implemented, for example, and I know that with time, all the other parts of newLISP will come into focus, as well.



I do realize that my posts are more appropriate in the context of a blog and have felt a little self-conscious since I started posting here a short 20 days ago. I did receive encouragement from cormullion and Rick to contine posting, and that has meant a lot to me. Just consider my posts as the non-necessary, but hopefully enjoyable and maybe sometimes inspiring bits of life that pop up from time to time, cause us to pause, and then, as we move on, wonder what that was all about. I just don't want to begin to test Lutz's patience with all my michaelfoolery :-)





m i c h a e l

Lutz

#3
I am enjoying your posts tremendously and just like Rick and Cormullion, I am ancouraging you to keep on posting.



As for ... convey a sense of playfulness ... that is exactly the right thing to do and in line with newLISP's t-shirt tag line: "puts the fun back in LISP" and part of the attraction to newLISP for many (see also http://newlisp.org/index.cgi?page=Art">http://newlisp.org/index.cgi?page=Art ).



... consider my posts as the non-necessary ... no, not at all, your OO post and my response to it have probably clarified a lot of things for other users. Trying to do stuff more foreign to a specific programming language always helps to get bettter insight in that language, and that was probably the purpose of your OO posts in the first place.



I have been in OO land myself for a long time (C++, Smalltalk, Java) and enjoyed it tremendously, this is why we have some limited OO support in newLISP.



Looking forward to your next post ;)



Lutz

m i c h a e l

#4
Quote from: "Lutz"I am enjoying your posts tremendously


Thank you, Lutz, for helping to soothe this admittedly too-sensitive artist :-) This is a load off my mind, as I actually have about three our four posts in various states of dress lying around. When cormullion mentioned his need, I of course was moved with compassion :-) And so, with the floodgates open (second thoughts, Lutz?), I will try to keep a steady stream of readables going.


Quote from: "Lutz"As for ... convey a sense of playfulness ... that is exactly the right thing to do and in line with newLISP's t-shirt tag line: "puts the fun back in LISP"


Since I would describe how I program as playing, I must certainly be in the right language :-)


Quote from: "Lutz"Trying to do stuff more foreign to a specific programming language always helps to get bettter insight in that language, and that was probably the purpose of your OO posts in the first place.


The things I try to write codewise stem from an inspiration to model some situation not common in a programming context. For example, quite early in my language affairs, I wanted to model, as closely as I could, a toaster. Not to control one. Not to make anything practical at all. Just something I could press the little handle down on (through code), and wait for it to pop up. No question in my mind where this comes from -- I built model kits for twelve years. All this modeling seemed to map well to OO.



For many years, I struggled to get my head around the whole OOP thing. Classes were the worst. You know, the funny thing is, when I had a chance to use OCaml's OO, I rejected it. The functional solutions' beautiful simplicity was too compelling, and I could not abandon them for their homelier OO counterparts. Perhaps the designers of OCaml used such an ugly symbol (#) for method calls to dissuade the use of OO ;-)


Quote from: "Lutz"I have been in OO land myself for a long time (C++, Smalltalk, Java) and enjoyed it tremendously, this is why we have some limited OO support in newLISP.


The OO support in newLISP feels just about right. Too heavy, and it begins to dominate; too light, and the OOheads may feel lost :-)





m i c h a e l

rickyboy

#5
It's good also to read the other side's propagada.  :-)
(λx. x x) (λx. x x)

m i c h a e l

#6
Quote from: "Rick"It's good also to read the other side's propagada. :-)


Always good to be well-read ;-)


QuoteWhy Arc Isn't Especially Object-Oriented


I read this some time ago, and when I reread it this time, one line stuck out.


Quote from: "Paul Graham"I personally have never needed object-oriented abstractions. Common Lisp has an enormously powerful object system and I've never used it once.


He sounds here, to me, to be proud of never having used OO. This reminds me of when Melissa and I would make a point of avoiding the movie "Titanic." We resisted seeing it at the theaters (too popular!), and by the time it hit the movie channels, our resolve became even stronger. Until one day -- before we jettisoned our cable -- I did watch it and, though it was predictably loaded with Hollywood tripe, the scenes of the ship were positively breathtaking. Of course, our personal picketing of the movie was a way of showing we weren't like the "mindless drones" who could not see the movie was pulp. But, isn't this just a way of feeling superior to others? And those who dismiss a movie, book, artwork, or other form of expression out of hand, sight unseen, based on some hinted or suggested offense to them or their group seem to fall into this category. I certainly respect Lutz's decision to limit OO in newLISP, which was based on his experience of OOP, as opposed to Graham's pigeonholing of it into "a useful technique in some cases." This is not an attack against Paul; in fact, I've read and enjoyed much of his writing. Instead, it's the observation that many of the opinions we hold come not from experience or understanding, but from hunches and fear.


QuoteJAR on Object-Oriented


This one I had merely come across before and not read too closely. Reading this reminded me that Booch's Object-Oriented Design with Applications contains a short list of what was considered OO at the time (I have the 1991 edition, a treasure). Here is the list, divided into essential and non-essential, of the elements making up the framework of OO:



   Essential

   * Abstraction

   * Encapsulation

   * Modularity

   * Hierarchy

   

   Non-Essential

   * Typing

   * Concurrency

   * Persistence



Personally, it was always the non-essential part that most interested me, and the one that was, by and large, sorely lacking in most OOP languages.


QuoteObject Oriented Programming Oversold!


Topmind has been a fixture on comp.object for as long as I can remember. His arguments can be compelling, but sometimes his zealotry can drown out his message. I was impressed by the idea of using tables as a better representation for objects (see http://www.geocities.com/tablizer/top.htm">Table Oriented Programming). I realized the table, using each row as an object and each column as an attribute or method, was probably an elegant way to define objects. But until he or someone else makes this table-oriented programming language, we'll just have to imagine. Unless someone writes a couple of LISP macros to do it first ;-)





m i c h a e l