Re: Macro Question: Paraphrasing
- From: drewc <drewc@xxxxxxxx>
- Date: Thu, 17 Nov 2005 06:21:40 GMT
Jack wrote:
drewc wrote:
I still don't see what you are getting at. If your problem is the ordering of arguments, why not use keywords for everything?
(unzip :files-listed-in ticket :from zipfile)
Now, you're just being difficult. Why not use keywords for everything? Talk about mantra-chanting!
You've conveniently ignored my subsequent explanation (with example)
that keywords can distort the meaning of a symbol on the surface level,
which is the language used by the human reader to map symbols to
concepts.
Your assertion that keywords can distort the meaning of a symbol on the surface level is understood, although what i fail to see how adding the extra layer of complexity helps to clarify things.
As far as i undertand it, your issue in this case is with the symbols in the body of a function definition having 'odd' names due to the desire to have 'good' names when calling it. for example:
you want to do
(move-contents :from container :to empty-container)
so you have :
(defun move-contents (&key from to) (put-contents to (find-contents from))
Your complaint is with the 'to' and 'from' in the function body, and you'd like them to have clearer names, maybe like 'full-container' and 'empty-container', which can convey to the reader what the objects actually are, but you feel constrained by the way keyword parameters are named.
In this instance i suggested simply defining a function is enough to clean up the names.
(defun perform-move-content (full-container empty-container) (open-container full-container) (let ((contents (find-contents full-container))) (put-contents empty-container contents)))
(defun move-content (&key from to) (perform-move-content from to))
If you make perform-move-foo a method, you can specialize the functionality of perform-move-foo, and that would make a lot of what you want to do possible without creating new syntax.
But, that's not going to be good enough for you, because you also want your source code to read as if it was your your native english. And you are entirely correct that the native constructs of lisp do not support that particular objective directly.
So, your idea is that you want the call to look like :
(move-content (from foo) (to foo))
and you like PARAPHRASE to allow you to take the form above and translate it to call the actual function that performs things with the correct argument order
(defun %move-content (full-container empty-container) (open-container full-container) (let ((contents (find-contents full-container))) (put-contents empty-container contents)))
(paraphrase (move-content (from full-container) (to empty-container)) (to (%move-content full-container empty-container)))
To my eyes, the two methods are almost identical, with the sole difference being that you get to use the names you wanted in the paraphrase, where i had to use 'from' and 'to' in my function call. If that is your only problem, than paraphrase can de defined as :
(defmacro paraphrase ((name &rest key-name-pairs) &body body)
(multiple-value-bind (keys let-bindings)
(loop for ((key alias)) on key-name-pairs
collect key into keys
collect (list alias key) into let-bindings
finally (return (values keys let-bindings)))
`(defun ,name
(&key ,@keys)
(let (,@let-bindings)
,@body))))and used like :
(paraphrase (move-contents (from full-container) (to empty-container))
(perform-move-contents full-container empty-container))which expands to :
(DEFUN MOVE-CONTENTS (&KEY FROM TO)
(LET ((FULL-CONTAINER FROM) (EMPTY-CONTAINER TO))
(PERFORM-MOVE-CONTENTS FULL-CONTAINER EMPTY-CONTAINER)))Now, you still have to call it using keywords, but you didn't have a problem with that ... right? Because, the problem with your (to foo) syntax (rather than :to foo) is that it breaks with the users expectations, namely that a form that looks like (foo ...) is a function call. also, adding the extra superfluous parens is not going to make too many people happy ;)
Whereas you can accept using the preposition :from in the body of the function definition to refer to the noun zipfile--which would suggest that you're just mentally mapping symbols to objects--you can't accept that I've chosen another convention, because I want to write (setf buffers (to (unzipped (files-listed-in ticket) (from zipfile))) instead of (setf buffers (unzip :files-listed-in ticket :from source). Do you really not understand my position? Or are you just a Lisp bully?
Well, possibly a good mix of the two. If i can assume that i accurately summarised your opinion above, then i now understand your position, although, as my example shows, i am far from agreeing with it. If my disagreeing with it makes me a bully, then so be it.
or if you really want to be specific at the call site, create a new (possibly local) function UNZIP-USING-TICKET. Again, i'm still missing the point entirely. UNZIP is a function which unzips files right? What is a ticket? what does it have to do with unzipping files?
What is a ticket? Are you really that dense? WTF? :files-listed-in what? :files-listed-in list? :files-listed-in shopping-list? :files-listed-in ticket? Who cares if it's a list or a (make-instance 'ticket) containing a list of files that the caller wants to be
Right ... why should the unzip function know what a 'ticket' is. I can understand wanting to pass a list of files to extract, but why an aribtrary object? in my opinion, unzipping files from a shopping list or a ticket are different operations than unzipping a list of files, and should probably have their own abstractions. what's wrong with:
(unzip :from file :files-listed-in (file-list ticket))
why do you need to have "unzip" know what a ticket is?
I found a zip library written by someone. I'd like to use that library, or at least parts of it, without restricting myself to writing unreadable code. The original UNZIP function has no concept of extracting individual files from a zipfile. Using UNZIP-USING-TICKET requires that I add another function to the interface of the core of the library, and it still forces me to refactor the library, because the original author decided that UNZIP would extract all of the files in an archive
Ok, UNZIP-USING-TICKET should not be in the library. it is part of your code .. do you think that everyone who used the library will want to use your 'tickets' or 'shopping lists' ? there is no need to add it to the core library.
Now, as for the author of the library not supporting the extraction of single files from an archive, perhaps you are using the wrong library?
http://common-lisp.net/project/zip/ seems to have all the machinery in place :
(defun extract-files (pathname list-of-files)
(zip:with-zipfile (z pathname)
(mapcar #'(lambda (f)
(zip:get-zipfile-entry f z))
list-of-files)))(paraphrase (unzipped (from pathname) (files-listed-in list-of-files)) (extract-files pathname list-of-files))
(unzipped :from #P"/home/drewc/src/sunrise/css/css_for_sunrise.zip"
:files-listed-in '("presentation.css"))This is all without creating new syntax and semantics, and without modifiying the library.
So i understand what PARAPHRASE is supposed to do, and i actually kind of like my implementation, but it doesn't really gain much, and simply pushes the complexity of remembering the order of function parameters to the author of the PARAPHRASE forms. It's a DEFUN and a LET. If i had to do this a lot, i might find the macro a nice thing, but i can't see why you want to go writing a code walker to get rid of keyword arguments.
Your (unzipped (FROM foo) (TO foo)) in a big lose, IMO, because it gains nothing over keywords, and looks exactly like a function call. i assume these function-call-looking-constructs are what you call 'CUE's. It is definately not clearer to hijack the syntax lisp uses for a very specific purpose (calling), and use it for something completely unrelated. of you want CUEs to be visually distinct, you need a different syntax, otherwise you end up with a mess. we could try something like
(unzipped {from foo} {to foo})And, you could do this with my paraphrase macro if you simply make {} a reader macro that outputs ":from foo". or, you could just use keywords.
If I rename unzipped to %unzipped and define paraphrases:
(paraphrase (unzipped (files-listed-in ticket) (from zipfile) (to target-path)) (to (%unzipped zipfile ticket target-path)))
(paraphrase (unzip (files-listed-in ticket) (from zipfile) (to target-path)) (to (%unzipped zipfile ticket target-path)))
(unzip (from zipfile) (to target-path)) --> (%unzipped zipfile NIL target-path)
(unzipped (from zipfile) (to target-path)) --> (%unzipped zipfile NIL target-path)
(unzip (from zipfile) (files-listed-in ticket)) --> (%unzipped zipfile ticket NIL)
(unzipped (from zipfile) (files-listed-in ticket)) --> (%unzipped zipfile ticket NIL)
(unzip (from zipfile) (files-listed-in ticket) (to target-path)) --> (%unzipped zipfile ticket target-path)
(unzipped (from zipfile) (files-listed-in ticket) (to target-path)) --> (%unzipped zipfile ticket target-path)
With two paraphrase, I have six functions. As with keywords, I can call the functions with the arguments in any order.
What you do here is no different from using keywords.
Unlike keywords, I don't pollute the function definition with noise. Sure, with a slightly different paraphrase macro, I could instead form the paraphrases with keyword syntax, as follows:
(paraphrase (unzipped :files-listed in ticket :from zipfile :to target-path)) (to (%unzipped zipfile ticket target-path)))
(paraphrase (unzip :files-listed in ticket :from zipfile :to target-path)) (to (%unzipped zipfile ticket target-path)))
This still doesn't pollute the function definition, and I might find good reasons to do it this way, e.g., namespace pollution. However, specifying the cues in lists would be consistent with macros for eliding these cues in cases for which I don't need full paraphrases.
Or, you could keep your syntax for paraphrase, as i did above, but use keywords at the call site, without messing with lisp syntax in any way.
Now, you're just being ridiculous--or you have the I.Q. of a snail. Do you mean to tell me that you can't relate hiding the most significant information in Java code and javadocs by not putting the most significant information first to hiding the most significant information in a function call by not putting the most significant argument first?
My IQ must be sinking, because you talking about javadocs has little relation to anything i've seen in lisp. Here you are, trying to modify common lisp to get rid of things you don't like in java?
I don't see functions that hid the significant argument, and if i want a different argument order for a specific task, i define a new function. If i want arbitrary order, i use keywords ...etc. I see no need to add your "CUES" to the calls.
I answered your question directly and elaborated, in order to clarify my reasoning. Short attention span? ADD? ADHD? What? Or are you just having fun egging me on?
Busted. I was actually interested in what you were trying to do, but now that you've explained it to me, and i've played with it, there is nothing to see here.
Which arbitrary order? you don't have to order keywords.KEYWORDS DON'T GIVE ME THE EXPRESSIVENESS I WANT AT THE CALL SITE *AND*
IN THE FUNCTION DEFINITION!!!!!!!!
Is there anything wrong with my PARAPHRASE macro? it seems to give you exactly what you want... minus the superfluous CUES.
If you are not using keywords, i might agree that for some functions, the arbitrary order is a hassle (GETF and GETHASH always mess me up)
THANK YOU! That is exactly my point.
And i understand that point. I just completely fail to see how your CUES and PARAPHASES solve this problem better than a function with keyword args.
but i certainly would not want to type (cons :car 'a :cdr b) , nor read it.
Your example is completely contrived. A CONS is an ordered collection:
Of course it's contrived .. that's the point. Some functions have explicit ordering,
It's the basic building block of the Lisp language. CAR and CDR add more maps, for historical reasons. It doesn't require any more mental mapping. (cons 'a 'b) doesn't cause any confusion unless your native language is by convention read right to left. I don't accept the notion that I need a new map for every single function of every single library, just to maintain some kind of mathematical purity, when my native language (which is usually mapped onto the code with SYMBOLS) could provide a direct map to the semantics if the code gave me enough CONNECTIVE cues.
Right ... i get that ,you prefer to make up your own symbol names (like unzipped) rather than use what is provided because you have a hard time 'mapping' names to objects. What i don't understand is how you expect it to be easier to rember a whole bunch of PARAHPHRASEs and the infinite possible number of "CUES', or how this is any easier than remembering a function and it's keywords. If it helps you make the connection becuase _you_ created them yourself, that great for you, but it doesn't help other people with your particular difficulty, and if anything makes the problem worse.
How does PARAPHRASE help here?
Have I not clarified it yet? One paraphrase *effectively* remapped the
function to the imperative verb, *effectively* obviated the need to
write three different DEFUNs, got rid of those NILs at the call, which
you so desperately despise, and effectively provided keywords, which
you can specify in any order,
ok, and as i've shown, paraphrase is simply defun + let with a bizzare syntatic convention for CUES. Again i ask you, what does it add? The one defun would have done the exact some thing as the one PARAPHRASE.
without fouling up the expressiveness of the function definition with :keywords which map to the surface level but not to the definition level, because the Lisp keywords serve as placeholders for the arguments instead of connectives... IN TWO LINES OF CODE! What more do you want?
Well, something more than DEFUN + LET really.
Most of your function names make no sense to me. why 'unzipped' and 'extracted-files'? Perhaps the reason i have trouble understanding what it is you are looking for because intent is not clear from your code.
Oh, jeez! Here we go! What is so difficult to understand about (setf buffers (to (unzipped (files-listed-in ticket) (from zipfile)))). It's perfectly NATURAL and maps directly from the surface level (English) to the concept: "Set buffers to the unzipped files listed in the ticket, from the zipfile." Yay, Lisp!
Ok, so there are unzipped files in the ticket? i thought we had to unzip them first .. oh wait, the last argument is a zipfile? ok .. so maybe we have to unzip them .. but it said to use the unzipped files in the ticket .
Yes, i'm being thick, just to show that natural language is not the best notation for computer programs. The surface level is not 'english' as you claim, english is terrible language for computer programming, to much room for error, ambiguity, and misinterpretation. In the case of lisp, the surface level is the symbolic expression. English is for requirements and manuals.
I have no problem reading function lambda-lists, so your "problem with readability" is only subjective.
Guess what! I have relatively little problem reading lambda lists either. My problem with the readability of code I've seen is DIRECTLY related to your problem with GETF and GETHASH. It requires mapping a symbol order specified by someone else to the concepts which the functions encapsulate, precisely because the specification doesn't provide any connectives to cue the reader to the semantics of the form.
I agree with you, but for the most part, SLIME tells me the argument order, and if i mess it up C-t flips them. Not a big deal, and certianly no need for your CUE's.
If you want to map hundreds of forms to hundreds of concepts because the specifications don't provide the information necessary to map it directly from the surface level of the forms, that is your prerogative. It's a waste of energy. I want to concentrate on the problems, not on mapping form to meaning.
Its just the i don't see the lack of "CUE"s in the language as a problem ..You do, and i suggest that keywords can solve most of those problems for you. You refuse to entertain that notion, and insist that your CUES are the only way to provide the semantic information.
I'd rather concentrate on problems that exist rather than ones that don't.
I chose keywords to clarify the meaning on the surface level at the function call, and because Lisp keywords in lambda lists are placeholders, instead of connectives, the surface meaning changed from the function call to the lambda, where the surface level is almost meaningless.
Right, ok. and you don't like LET. I now understand this part, and PARAPHRASE makes sense.
Instead of the prepositions to and from, I could have chosen nouns.
(defun unzip (&key ticket source path)...)
Of course, that cleans it up for the lambda, but what does it do to the function call?
(let ((ticket ...) (target ...) (zipfile ...)) (unzip :ticket ticket :target target :zipfile zipfile))
Or even_
(progn (unzip :ticket (("context.xml")) :zipfile "opus.sxw" :target "target-path"))
That's ridiculously redundant in either case, and it fouls up the surface form. I don't want to unzip the TICKET. I want to unzip the files-listed-in TICKET
Then why are you using UNZIP like that? I'd name this UNZIP-FILES-FROM-TICKET. Why should the users of the ZIP library car about your ticket objects?
..
(unzip :files-listed-in ticket :from zipfile :to target)
and
(unzip (files-listed-in ticket) (from zipfile) (to target))
say exactly what I mean to say. But if the DEFUN uses the keywords in the former, it makes a mess. The latter should be much easier for the human reader, because it groups the connective with the argument.
Give me a break. Using a form that looks exactly like a function call to mean something completely different does _not_ makes things easier for the human reader. example :
(defun files-listed-in (ticket) (get-files ticket))
(defun from (pathname) (make-from pathname))
(defun to (pathname) (make-to pathname))
(defun unzip* (files from to) (%unzip files from to))
now, look at these two function calls :
(unzip (files-listed-in ticket) (from zipfile) (to target))
(unzip* (files-listed-in ticket) (from zipfile) (to target))
Identical syntax, and the human reader would assume that they are similar in semantics, but your UNZIP paraphrase with CUES does something very very different than unzip*. Don't tell me this is better than keywords.
The only problem i had with mapping the code above to what it should do was deciphering your function naming convention.
GOOD GRIEF, CHARLIE BROWN! On the surface, you can map the preposition to the object, but you can't map a sentence specifying that I want the UNZIPPED files-listed-in the ticket from the zipfile. You seem to have no problem with the preposition mapping to the object of the preposition, effectively eliding the nominative, which would convey more meaning within that lexical environment. So why can't you map the imperative to the noun phrase UNZIPPED file-listed-in ticket from zipfile, which is what I really want when I have a ticket.
Because i've never though of functionas as objects (like a list of unzipped files) but rather as actions (unzip a list of files) that return objects (a list of unzipped files). so where
(let ((unzipped (unzip ...)) ...)
makes sense, (unzipped ...) doesn't.
If you find this easier to understand, that's fine, i'm aware you have difficulties with mapping, and if this makes it easier for you, you have every right to do it. I have real problems reading your code, where i don't have problems when people use more standard naming conventions, but that is perhaps my problem, you are free to write code however you need to make it clear to yourself.
You are complaining about having problems reading code and documentation, and here you are naming functions after what they return rather than what they do
Oh! And (car foo) cars foo, but (cdr foo) cdrs it.
You bet it does! at least when i'm reading that code, that's what i read. rather 'find the first item in the list and return it), but CAR it is close enough. UNZIPPED would be 'find the unzipped files in the ticket and return them' , which implies that the files are already unzipped (like the cons already has a car. car does not create cars, unzipped should not create unzipped files). if i wanted to create some UNZIPPED files (or, and object with a list of unzipped files), i'd probably look for a function that creates them (like, if i wanted to create a CAR (or, an object with a car) i'd use CONS, which makes objects with CARs).
IIRC car and cdr
were the NAMES of the registers, Content Address Register and Content
Decrement(?) Register.
Actually, it's Content of the Address Register, which is is not something performs an action (like unzip) but rather an accessor.
And I suppose (first bar) firsts bar and (rest
bar) rests it. Does (second baz) second it?
You've got it.
They are? I don't see that anywhere in the specification, and a lot of coders would disagree with you. In addition to the examples above, we also have_
(defclass foo () ((bar :accessor bar)))
(setf (bar foo) 'baz)
Ok, setf if a verb, and this form is performing a action.
(bar foo) --> 'baz
The accessor method (a generic function) specifies what it returns. Your assertions are ridiculous, and your logic based on these mind-numbing assertions is faulty. How old are you? 12?
Right, but it doesn't go creating BAR's in FOO. It does not perform an action, but returns a value. UNZIPPED performs an action, createing the UNZIPPED files. This is why i believe the name is wrong.
There is no need to throw a temper tantrum. My age has little to do with the topic at hand, and you lose quite a bit of credibility when you resort to tactics like this.
What 'mapping' are you refering to? I'm probably one of those who find it natural, because i can't seem to see what your problem is. Then again, i've programmed a fair bit of CL and am used to reading it.
And I've written and read a ton of Java and C/C++ code, and I will NEVER be used to it. It's insane to constantly remap forms to concepts when language can map it directly on the surface. A symbol can only point to something. If I ask you what the moon is, you can only point to it. But language can do it on the surface level. Stop working for the computer, and make the computer work for you.
Rhetoric aside, i think you'll find CL to be very different than Java/C++. Trying to fix Java's problems in CL (before you even know CL) will get likely get you nowhere. But, don't let me stop you.
It's not that i don't like it, its just that i can't seem to grasp what it is you are trying to do, and why. Can you explain what your PARAPHRASE macro does, and what 'eliding semantic cues' is.
That all depends on what the definition of is is.
Obviously.
The connectives clarify the meaning. The compiler can munge the connectives from the surface form and still have all of the information for the underlying functional form. When I tell the compiler to (elide-cue to), the compiler will elide (omit) the semantic cue, which contains meaning on the surface level but is meaningless to the compiler on the functional level.
Ok, so TO is a no-op in this case? And adding forms for no reason, that have no effect on control flow, scope, or anything, makes things clearer for you. So you have no problem throwing these TO non-operators everywhere, which obviously increases noise by adding something that does nothing, yet you'd rather modify UNZIP instead of define UNZIP-FILES, which adds actual useful information to the function name.
I'm full circle again. I don't get it.
This is the problem i have with your 'paraphrase' operator .. why do you want to reorder the arguments of existing functions when you can simply define new functions with whatever wacky ordering you want?
With the paraphrase example above, I effectively defined three functions with one paraphrase, in two lines instead of three defuns. That's at least a 3:1 compression without loss of meaning.
Great ... and i showed that its just defun, and that you can do it without overloading the function call syntax.
I was not aware that you were creating a new language here,
We've discussed different ways to add on to Lisp. That's creating a new language in itself, so it was obvious. Whether I'm only enhancing Lisp or I'm creating an entirely new language, I'm creating a new language in either case. Every single computer program for which I have reviewed the source code has created a new language but failed to map the concepts directly.
The difference is that, if you are making your own language, i couldn't give a ***. But, if you are proposing to 'enhance' lisp, then it matter, because your enhancements are anything but, and CL already supports what you want to do. If you really don't like keywords, use a reader macro! If anything, the presence of curly braces like i used above will be a much better semantic CUE than something that looks to the reader like a function call bit is infact something completely unrelated.
How is it that, without knowing much about lisp, you already know what needs 'enhancing'? As i've shown, lisp already can do the equivalent of your idea (unless i am totally off base), and there is no need to 'enhance' things or fsck with function calling.
i simply thought you were trying out common lisp.
Why should my motives affect the discussion.
Because if you want to learn lisp, trying to fix non-problems is a big waste of time. If you experimenting with language design, its a learning experience (esp when you realize _why_ the creators of CL did things a certain way), and you _should_ be wasting your time.
Whoa! I haven't forced anything on anyone. In the original post, I only asked if other people had used Lisp to do what I described and how they would do it. I had some difficulty with some macro concepts, and others simplified it for me. You started egging me on, so I decided to defend my reasoning. I think I have explained myself very coherently.
I admit egging you on, as i find that a probing critic can really help me to solidify and clarify my thoughts. I thought that perhaps by addressing my questions you'd see your idea from a different view point, and maybe then see why people are telling you its a bas idea.
And you have (now) explained yourself coherently, and made your points. You didn't much listen to my questions, but that's ok. My point is that, since lisp does what you need now, and using syntax that others are comfortable with and can help you with, why go off on a tangent? How does this feature outway the negatives associated with it? Language design is all about balance.
There is no library. I defined a mechanism for rephrasing forms in a way I haven't seen elsewhere. I thought Lisp was first about List Processing. That's all I'm doing.
No, you are changing the syntax of LISP with your CUEs, for no good reason beyond an idea which can be expressed without the need to break the readers assumptions.
(which slime makes easy ... i shows you the name and order of the arguments as you type ... how is that hard?),
Hmmm... Yet you still have trouble with GETF and GETHASH.
Sure. i often forget for a second which side is left and which is right. I'm not going to go tatooing RIGHT on my right hand as a cue.
Sure, SLIME is neat. It adds some nice functionality to Emacs. But I
still haven't determined how to copy and paste from XEmacs to other
programs. I still haven't determined how to tab from the directory
widget to the file widget in the file dialog without taking my hands
off of the keyboard, and I can't find this information documented
ANYWHERE.
Did you try the manual? Emacs is very well documented. Archaic perhaps, but full of docs.
XEmacs doesn't use a standard interface, so I have to remap
concepts again. CTRL-C no longer means copy. CTRL-V no longer means
paste. It's a klucking fudge.
I hate to point this out, as it probably doesn't matter to you, but the EMACS keybindings have been around for one hell of a lot longer than Windows. and, they are almost trivial to change (you do know that emacs is written mostly in lisp .. right?). Just because the makers of Emacs don't tailor to your own personal preferences is no reason to have a fit.. these things are trivial to change.
So I don't always use XEmacs + Slime to
read or write code.
well, you should. Lisp, with its long operator names and parens, really needs a good enviroment to take advantage of. Try one of the commercial implementations. You'll find that they come with great IDEs, and all include a version of Emacs ;)
If you want to play language designer, i'm not going to stop you. Hell, for all i know you are the next Steele. But, you should at least understand what is out there and how it works before running off and making a whole new language.. you are probably re-inventing a lot of wheels. What does your new language offer the programmer? A shortcut for defun+let and a confusing change in syntax due to CUEs. Not that i care, if you are infact creating a new language. This is fun task, and if paraphase+cue is really what you need to get work done, go for it.Lisp was new at one time. Lisp was new to you at one time. Lisp hasbut an entirely new language with a compiler written in itself that only one programmer on earth knows how to maintain!
more than one implementation with more than one programmer who knows
how to maintain it.
I think you are wasting your time, but you don't care about my opinion, nor should you.
This new language and this new compiler don't even have full specifications. I haven't even described this new language and this new compiler, and already you've cast it aside. That's on you, Bub.
If all you have is PARAPHRASE, then yup, useless as tits on a bull. If you've got some more 'super-secret wait till you see this you'll change your mind' stuff hidden away, then more power to you. I personally cant wait to see it (i'm still waiting for IncreduLISP).
When i write code, i want the reader, who i almost always assume will not be me, to be able to read the code without having to struggle with weird contructs of my own creation.
That's bull***. Any code you write will create new constructs. If the
new constructs don't map directly to prior known constructs, the reader
will need to work harder to create those maps.
Ok, this is true, but you are missing the point (a favorite tactic of yours it seems). When creating new contructs, i try to make it very clear what it is i'm doing. If possible, i emulate existing contructs that the reader will be familiar with (with-* def* etc). What i'm saying is that i find DEFUN+LET and keyword args easier to read than your PARAPHRASE and CUE (specifically CUE .. the former is not so bad at all). CUE, as my unzip* example shows, can really mess with the readers expectations.
Just because my
preferred style doesn't follow convention doesn't make this style
unreadable.
To those who are used to the convention, it most certainly does. Its like people who put their closing parens on lines by themselves, or people who use CamelCase... By not following convention, your code does not look like 'normal' lisp code, and is therefore harder to read for a lisp programmer. Is this too difficult a concept to understand? When people are used to reading things in a certain way, it is easier to continue reading things that way, and changes (especally drastic ones like CUE) are going to make things harder to read.
Just because these new constructs that I have defined don't
follow those used by the herd doesn't mean that these new constructs
aren't useful.
Not at all. But in this case, the constructs are are used by the herd are well thought out can easily emulate your new construct. Why create a whole new language when it's simply a macro that expands to a DEFUN+LET.
These concepts map more directly to common knowledge. Whereas they don't map directly to common Lisp usage, they'll require less effort to use than other types of mappings.
For a non-lisp programmer, maybe. But if your target audience is lisp developers (i'll usume it's not, as you don't seem interested in what lisp developers think of your idea), than the 'common knowlege' is lisp knowlege.
I tend to only use two types of macros. WITH-* and DEF-*, and i comment very clearly when doing something hairy or tricky.
La-ti-da.
Missing a very important point here, you are. Care not, do i.
Again .. why didn't you just define your own function
I defined six new signatures in 5 lines. I could probably compress it further without any loss of information. Two lines per DEFUN with a space between each would total 17 lines. Each PARAPHRASE only paraphrase the function, so it won't break existing code. The keywords are no longer placeholders instead of connectives... The list of reasons just keep growing.
Ok, as i've shown, PARAPHRASE can basically be expressed as a let and a defun. using the macro gains you a line of code and little else. I can see how, if you wanted to do a lot of this, the macro would come in handy, but i still don't see the point of CUE, and can't see how you could ever justify overloading the function calling syntax as a method of making things more 'clear' and 'readable'.
.. why the desire to change someone elses?
Hell is other people--Sartre, I believe,
Great, but nobody is stopping you from wrapping other peoples functions in your own. Why do you feel you have to change their library to do what _you_ want ... unzip-files was a three liner using the ZIP library. Three lines of code (and getting the job done) vs a new language? which is more practical here?
DEFUN is a lot easier to learn than DEFMACRO,
Oh, in that case, let's not use any macros anymore. As a matter of fact, let's not use anything based on macros, and we can throw out a large part of the standard library and the functionality of lisp. Deal?
How you extrapolated that from what i said, i'll never know. Maybe this is related to your difficulty mapping concepts, but saying 'X is easier to learn than Y' in no way states that Y should be dropped. Maybe the sentance was missing some semantic cues ;)
But, yes, DEFMACRO is the last tool you should reach for. If you can do it with DEFUN, you should. DEFMACRO is a big hammer.
Ah .. that's what a 'ticket' is ? a list of files? why not a new function EXTRACT-FILES-FROM-ARCHIVE or UNZIP-FILES?
But %UNZIPPED already does that! And with the paraphrases, you don't need to know anything about how it does it.
Ok, right. so, instead of having a function named UNZIP and a function named UNZIP-FILES, you got a function named %UNZIPPED, and the wrapper UNZIP. What i fail to understand, and what you have yet to elucidate, is what it gains over DEFUN+LET + keyword arguments.
Ok ... why not READ-OPEN-OFFICE-FILE ? why should i, the reader, care that the file is just a zip file .. abstraction is the key here. Why are you trying to take a function called UNZIP and turn it into a function that reads OO.o documents? If you are trying to accuratly convey information to the reader, choosing the right name, and having small functions with simple behavior, will go a lot farther than having a function with a single name that has as many different behaviors as there are uses for zip files.
Now wait just a cotton-pickin' minute! Your tangent assumes that I haven't defined such a function for the abstraction (though I surely wouldn't choose such a name for the function). You have absolutely no evidence to support such an assumption. How does mentioning the desire to parse OpenBook documents lead to the conclusion that I wouldn't make such an abstraction? I only mentioned that the OOo file was a zipfile in the context of extracting a single file from an archive.
I assumed that 'ticket' was part of your internal interface, as i've never heard of a 'ticket' in the context of archives. So, if you plan on using READ-OO-FILE, or whatever, as your top-level function (surface level), why redefine UNZIP (or UNZIP-FILES) at all? ideally, youve given your function the perfect interface for reading oo files, and unzip is buried, never to be called by users again.
You know, you could factor out the common code into a function that is used by all three. Then you wouldn't have to write the same code everywhere.
I believe I already mentioned considering the possibility. However, the PARAPHRASE does very nicely hide the implementation details. At the moment, I can't see any reason to define three different function when I bought the same with one paraphrase in two lines.
Where do you get the idea that you need three different functions? keyword args do exactly what you want , minus the thing in the function defintion body, which LET, or my PARAPHRASE macro solves. This is what still don't get.. why do you need to define a new language when you can do everything you need to do in Lisp. Don't like the syntax? Why use lisp at all then.
But how does your macro fix that? now i only have to remember one name, but a possible infinite number of behaviors?
You don't have to do any such thing! It's no more complicated than calling a specialized method! And I didn't need to define three different methods!
Sure you did ... what are the forms passed to PARAPHRASE if not a function signature and a body. The expansion of my PARAPHRASE macro shows that perfectly.
I'd rather see READ-OPENDOC-FILE than try to figure out that the UNZIPPED(!?) function is also used, when called in some strange manner, to open OO.o files.
As I already made painfully clear, it would require no such thing, because you JUMPED to the WRONG conclusion.
Imagine that. I suppose its my fault, and your explaination was as clear as glass. Since you are obviously so good at expressing your ideas, this must be because my mentality is that of a 12 year old. I apologize for not being able to understand your scattered explanations.
[snipped a whole bunch of bull*** about grep. Grep is a computer program..
not a function. If you are advocating writing a function that take as many
arguments and performs as many diverse tasks as grep... lol]
Following that to it's logical conclusion, the entire language should be consolidated into a single operator. We can just pass lists of code to that function, with maybe, say, the first item in the list denoting a function, and the rest arguments to that function... Wow ... we've just invented EVAL :)
Following your logic to the extreme, we shouldn't specialize any methods which have very similar semantics, and we shouldn't name anything with the same name, function, value or otherwise, in any context whatsoever.
Your logic escapes me, and calling it my logic shows a major misunderstanding. All i was saying is that, because your CUES look a lot like function calls, your code walker is going to be almost exactly like eval... and since EVAL can already do what you want with its keyword mechanism .. why bother?
I don't know how I could have been more clear about it. Lisp keywords in functions serve as placesholders instead of connectives. I offered an elegant solution, but you're stuck on using the keyword kludge.
Your 'elegant' solution changes the syntax of LISP, in only certain, special cases (the paraphrased form). If you think that having function calls and CUES share a syntax is somehow elegant, i'm not going to argue with you, but my god man .. you can't be serious.
What information are you adding? I still don't understand the point of what you are trying to do here.
You're not even trying. You must think that people should just use whatever maps someone decides to give them, instead of finding better ways to create those maps. Sure. Let everyone use Slime and that f'ing kludge Emacs. It will give you the signature--but it won't tell you what it means. But that's all we have, so let's just keep using it. Let's not progress any further. Everything's fine the way it is. I'm fine with it, so everyone else should be, too. Only one programmer on earth understands what Jack is doing, because I sure don't. When Jack implements his new language and compiler, only Jack will ever comprehend it. Jack must be the only one on earth with a brain. I wish I was Jack.
Do you even see how distorted your thinking is?
If you insist on 'paraphrasing' my words while distorting my ideas, you can piss off. Where did i say everybody had to use emacs+slime? Where did i say everything was fine? all i asked was for you to explain your idea, and how it improves on existing tools. You have still failed to show me this... if you insist on thinking it's because i'm closed minded and bigoted, and that your idea is so brilliant anybody with a brain could see how it improves things... that's up to you.
You know what? i use whatever map someone gives me. I might draw lines on it, maybe add some of my own information on the surface, but i'm not going to go treking across the continent to find out how far it is to halifax, i'm more than happy to use the existing map. If you're not, thats find. And if you want to make a map that is drastically different than the map i am used to because you have problems reading the existing maps, that's fine as well. Enjoy the trek.
You talk about progress while knowing nothing of history, and thus dooming yourself to repeat it.. but you know what... i don't care anymore. If you are going to twist my words to make it seem as if i am a close minded bigot, that's fine, go ahead, but don't expect me to listen.
I've backed up my bull. You've come back with fallacies, twisted logic and whining--I don't understand; I don't understand.
Listen. I didn't understand what you wanted to do. Have you ever stopped to think for a minute that i didn't actually understand, and wanted you to clarify? What i don't (and still dont) understand is what your CUES offer above keywords (given my definition of PARAPHRASE).
I was probably the only guy here left didn't write you off as a troll or a nutjob. Maybe you are right, maybe i do have the intellect of a 12 year old.
Do I need to prove it to anyone? No. I'm just having fun watching you avoid any kind of logic just to prove me wrong.
Accusing me of twisting logic instead of addressing my points is an interesting tactic. I'm not interested in debating logic with you. I simply wanted to understand what you were trying to do. Since you've been such a pleasant conversationalist, and since your ideas are obviously way over my head with genius, i'm going to drop this now.
Or maybe you just want me to blather on about it, so that I can prove to the rest of the world what a great language Lisp is for this type of solution.
Actually, now that i know more about what you want to do, and have found that it is, in fact, nothing new and can be implemented in 3 lines of lisp, i couldn't care less about the idea.
Maybe you are used to people not caring or dismissing your ideas, but i was genuinely interested. Now, given that you've found it neccesary to attack my person rather than discuss your ideas, i'm going top write you off as a nutjob.
You want more? Bring it on!
This could have been an enlightening technical discussion, but you seem to have turned it into some sort of schoolyard game of one-upmanship. I am not interested in playing these games, prefering conversation about Lisp. Best of luck with your new language, there will be a lot of critics, but if you simply answer every critisism and request for understanding with insults to the critics intellegence and nature, i'm sure you and your language will enjoy a great success.
-- Drew Crampsie drewc at tech dot coop "... the most advanced use of lisp in the field of bass lure sales" -- Xach on #lisp .
- Follow-Ups:
- Re: Macro Question: Paraphrasing
- From: Jack
- Re: Macro Question: Paraphrasing
- From: Thomas A. Russ
- Re: Macro Question: Paraphrasing
- References:
- Macro Question: Paraphrasing
- From: Jack
- Re: Macro Question: Paraphrasing
- From: RPG
- Re: Macro Question: Paraphrasing
- From: Jack
- Re: Macro Question: Paraphrasing
- From: drewc
- Re: Macro Question: Paraphrasing
- From: Jack
- Re: Macro Question: Paraphrasing
- From: Jack
- Macro Question: Paraphrasing
- Prev by Date: Re: Identifying CL Implementations?
- Next by Date: Re: Identifying CL Implementations?
- Previous by thread: Re: Macro Question: Paraphrasing
- Next by thread: Re: Macro Question: Paraphrasing
- Index(es):