From: Jack
Subject: Macro Question: Paraphrasing
Date: 
Message-ID: <1132003147.828778.263710@g43g2000cwa.googlegroups.com>
Suppose I have a function,

(defun unzip (ticket zipfile target-path &key (if-exists :error
verbose) ...)

* where TICKET (if not NIL) lists the files to be extracted from the
zipfile named by ZIPFILE and where TARGET-PATH (if not NIL) names the
directory to which the files will be extracted;

* which would return either a list of buffers containing the contents
of the unzipped files listed in TICKET (or if TICKET is NIL, all of the
files in ZIPFILE) or the pathnames of the files extracted to
TARGET-PATH.

My anal-retentive brain insists that whereas

(progn (unzip ticket zipfile path)...)

is fine and dandy,

(let ((buffers (unzip ticket zipfile path))) ...)

and

(setf buffers (unzip ticket zipfile path))

violate some linguistic and/or aesthetic rules and should be written

(let ((buffers (UNZIPPED ticket zipfile path)))...)

and

(setf buffers (UNZIPPED ticket zipfile path))

Furthermore, my anal-retentiveness wants to morph these into

(let ((buffers (BE (unzipped :files-listed-in ticket :from zipfile :to
path))))...)

or even

(let ((buffers (BE (unzipped (files-listed-in ticket) (from zipfile)
(to path)))))...)

and

FIG 1: (setf buffers (TO (unzipped :files-listed-in ticket :from
zipfile :to path)))

or

FIG 2: (setf buffers (TO (unzipped (files-listed-in ticket) (from
zipfile) (to path))))


where

(BE form1)

and

(TO form2)

elide the cues BE and TO, expanding/rewriting/refactoring to

(form1)

and

(form2)

Note: In FIG 2 and the corresponding LET, I haven't determined which
part(s) of the cue forms should be quoted to avoid evaluation before or
during macro expansion, and the syntax in the examples might seem
somewhat hokey. I still haven't internalized all of the Lisp concepts.
Feel free to correct any errors, so that I can map the concepts
correctly.

For the moment, ignore any tendencies in modern programming languages
toward brevity and away from verbosity. Also, keep in mind that I
realize that some programming languages (e.g. COBOL(?)) have tested
this use of verbal cuing to promote readability--whether these
programming languages have succeeded or failed to usurp languages with
terser notations. I don't envision changing the status quo in the
large. I only hope to develop a system of notation that will aid my own
endeavors. You might ask why I would go to such extremes. For now,
let's suffice it to say that it involves some proactive interference.

QUESTION #1: Please, forgive my ignorance. I have experimented with
REPL (SBCL) and haven't determined how to write a macro

(defmacro elide-cue (cue...)...)

which would expand

(elide-cue to...)

allowing me to elide the cue TO in, for example, FIGs 1 and 2. Can a
defmacro expand to another defmacro? Or have I missed another mechanism
that will do effectively the same? (I have studied chapter 8 of Peter
Seibel's "Practical Common Lisp" and other related texts, but I just
haven't had that AHA! moment.)

QUESTION #2: For now, let's forget the difficulty I've had with macro
syntax. Is there any reason why it wouldn't be possible to write a
macro PARAPHRASE that would allow me to write, for instance,

(PARAPHRASE (unzip...) (unzipped...))

in order to allow different means to call the same function, without
having the paraphrase expand to another function call? (As above, I
envision a macro expanding to another macro.) Of course, I'd like to
have the PARAPHASE macro examine the arguments for cue forms, in order
to determine whether the caller chose to change the order of the
arguments.

For example,

(move-object (FROM p1) (TO p2))

would mean the same as

(move-object (TO p2) (FROM p1))

and actually calls

(move-object p1 p2)

Otherwise, I suppose I would just defmacro from one form to another for
each paraphrase. However, as in ELLIDE-CUE, a PARAPHRASE macro makes
the intention of the form clear at first glance.

Such an abstraction would allow me to leverage existing code in my own
style, where for whatever reason the original author's style disagrees
with me. Effectively, I want an expedient mechanism to make my code
easier for me to read. After all, I tend to read code more than I write
it. Am I asking too much from Lisp?

Has anyone used macros to do such paraphrasing? How would you write a
PARAPHRASE macro for the functionality described above?

Thanks in advance for your ideas.

- Jack

From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132004354.204877.33890@g47g2000cwa.googlegroups.com>
PS: The last example,

> (move-object (FROM p1) (TO p2))
>
> would mean the same as
>
> (move-object (TO p2) (FROM p1))
>
> and actually calls
>
> (move-object p1 p2)

is obviously flawed. As written, it would require a preprocessor.
Assuming MOVE-OBJECT is a paraphrase of another function signature, the
last line would read (moving-object p1 p2) or some such deviation.
From: M Jared Finder
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <xr2dnYgV9_rgx-TenZ2dnUVZ_vidnZ2d@speakeasy.net>
Jack wrote:

> For the moment, ignore any tendencies in modern programming languages
> toward brevity and away from verbosity. Also, keep in mind that I
> realize that some programming languages (e.g. COBOL(?)) have tested
> this use of verbal cuing to promote readability--whether these
> programming languages have succeeded or failed to usurp languages with
> terser notations. I don't envision changing the status quo in the
> large. I only hope to develop a system of notation that will aid my own
> endeavors. You might ask why I would go to such extremes. For now,
> let's suffice it to say that it involves some proactive interference.

Enforcing English grammar rules in a programming language is (usually) 
bad.  The programming language has its own grammar rules that are 
simpler and much more consistent than natural language.  Just look at 
how easy it is to understand LOOP.

If you did want to have your language have it's own grammar, the easiest 
way would be to write a macro WITH-ENGLISH-GRAMMAR that processes all 
its subforms and rearranges it to look like normal Lisp.

But why bother?

   -- MJF
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132033048.210307.285870@g44g2000cwa.googlegroups.com>
MJF wrote:

>> For the moment, ignore any tendencies in modern programming languages
>> toward brevity and away from verbosity. Also, keep in mind that I
>> realize that some programming languages (e.g. COBOL(?)) have tested
>> this use of verbal cuing to promote readability--whether these
>> programming languages have succeeded or failed to usurp languages with
>> terser notations. I don't envision changing the status quo in the
>> large. I only hope to develop a system of notation that will aid my own
>> endeavors. You might ask why I would go to such extremes. For now,
>> let's suffice it to say that it involves some proactive interference.

>Enforcing English grammar rules in a programming language is (usually)
>bad.  The programming language has its own grammar rules that are
>simpler and much more consistent than natural language.  Just look at
>how easy it is to understand LOOP.

Your somewhat twisted reasoning amuses me, especially considering the
text you chose to quote. From the original post onward, I've tried to
elucidate that I would like to add to the language for my own viewing
pleasure. Far from enforcing English grammar rules on Lisp, these ideas
entail adding context to arbitrary ordering and paraphrasing awkward
expressions. That doesn't seem like too tall an order.

LOOP is quite brilliant. It allows the formation of compact
compound-very-complex sentences. The variable clauses resemble
[potentially compound] dependent clauses, and the main clause
represents the [potentially compound] independent clause(s). It mimics
English grammar very nicely, though I might improve the punctuation.

>If you did want to have your language have it's own grammar, the easiest
>way would be to write a macro WITH-ENGLISH-GRAMMAR that processes all
>its subforms and rearranges it to look like normal Lisp.

Aha! So you admit that I can tailor Lisp to suit my needs. Thanks for
the 411, but I had already pinned that donkey's tail.

>But why bother?

Why bother? he asks. Because I can tailor Lisp to suit my needs. I
already said that, and I believe you did, too.

Mr. Bourguignon has given me some useful advice toward my aims--his
fluency amazes me, even if I don't quite understand everything he
writes--and I appreciate that he has attempted to answer my questions
in language that I might understand. If I hadn't lurked in c.l.l.
frequently enough, I might wonder that others haven't exactly
volunteered, instead of shooting down my attempts to make it easier to
personally read my own code.

Is it a bad idea? My motives seem to be in the right spirit. Will it be
too cumbersome to implement? Perhaps. I won't know until I have tried
it for myself. If it makes it easier for me to read what I write, it
will be worth the effort.

Why bother? Why bother doing anything? It might lead to a better way.

- Jack
From: M Jared Finder
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <c6idnX5Rx847ROfeRVn-pg@speakeasy.net>
I'm replying to your reply out of order.  I think my reasoning is 
clearer in this order.  Just giving a heads up...

Jack wrote:
> MJF wrote:
> 
>>If you did want to have your language have it's own grammar, the easiest
>>way would be to write a macro WITH-ENGLISH-GRAMMAR that processes all
>>its subforms and rearranges it to look like normal Lisp.
> 
> Aha! So you admit that I can tailor Lisp to suit my needs. Thanks for
> the 411, but I had already pinned that donkey's tail.

I'll admit it, I didn't put much effort into my original post.  I'll put 
more effort into this one.

What I was trying to say is that you won't be able to define macros TO 
and BE that would rearrange (move-object (to destination) (from source)) 
to (move-object source destination).  You can't do this because macros 
have no access to the super-form they are in.   Instead, you will need 
to put some macro around all the forms that need to be processed, and 
use a code walker to process each subform, a la

(with-english-grammar
   (move-object (to destination) (from source)))

The with-english-grammar macro has access to the super-form of
(from source) and (to destination) and can make the necesarray 
modifications.

Keyword arguments and the package system should be enough, though.

>>Enforcing English grammar rules in a programming language is (usually)
>>bad.  The programming language has its own grammar rules that are
>>simpler and much more consistent than natural language.  Just look at
>>how easy it is to understand LOOP.
> 
> Your somewhat twisted reasoning amuses me, especially considering the
> text you chose to quote. From the original post onward, I've tried to
> elucidate that I would like to add to the language for my own viewing
> pleasure. Far from enforcing English grammar rules on Lisp, these ideas
> entail adding context to arbitrary ordering and paraphrasing awkward
> expressions. That doesn't seem like too tall an order.

Lisp already has a construct that serves exactly that purpose -- keyword 
arguments.  Combined with the package system, you can define your own 
version of any existing function or macro:

(defpackage :cl-keyworded
   (:use) ;not using COMMON-LISP!
   (:export setf let))

(in-package :cl-keyworded)

(cl:defmacro setf (cl:&rest args)
   `(cl:setf
     ,@(cl:loop :for cons :on args :by #'cl:cdddr
                :do (cl:assert (cl:eq (cl:second cons) :to))
                :collect (cl:first cons) :collect (cl:third cons))))

(cl:defmacro let (bindings cl:&body body)
   `(cl:let ,(cl:loop :for (symbol cl:&key be) :in bindings
                      :collect (cl:list symbol be))
      ,@body))

Now you can use cl-keyworded:setf and cl-keyworded:let instead of 
cl:setf and cl:let.  The paraphrase macro is similarly simple:

(defmacro paraphrase ((old-name &rest old-args)
                       (new-name &rest new-args))
   `(defun ,new-name ,new-args
      (,old-name ,@(paraphrase-lambda-list-args old-args))))

where paraphrase-lambda-list-args is a function that returns a list that 
could get called.

I still don't think this is a good idea.  If you break the existing 
convention, other people will find it harder to help you, since they 
won't understand why let and setf are taking keyword arguments.

> LOOP is quite brilliant. It allows the formation of compact
> compound-very-complex sentences. The variable clauses resemble
> [potentially compound] dependent clauses, and the main clause
> represents the [potentially compound] independent clause(s). It mimics
> English grammar very nicely, though I might improve the punctuation.

And I could not disagree with you more.  LOOP is *the* worst construct 
in the Common Lisp language, because it disregards everything that's 
good about computer programming.  Worse still, because LOOP's syntax is 
completely different from *the rest of Lisp*, I don't get 
autocompletion, indenting, or any other computer assistance.  So I have 
to parse its meaning, token by token, by hand.

You consider that "quite brilliant"?

   -- MJF
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132163453.620154.212870@o13g2000cwo.googlegroups.com>
>What I was trying to say is that you won't be able to define macros TO
>and BE that would rearrange (move-object (to destination) (from source))
>to (move-object source destination).

I understand that. I flubbed one or more examples, because I was saying
what I wanted to say, without taking into account the recursion issue
in the code I generated for the examples. This confused everyone,
making them think that I didn't understand the issue, and for that I
apologize. I do understand that the macro and the resultant macro or
function need different names, unless I want to process it before the
macro expander evaluates it.

>You can't do this because macros
>have no access to the super-form they are in.   Instead, you will need
>to put some macro around all the forms that need to be processed, and
>use a code walker to process each subform, a la

>(with-english-grammar
>   (move-object (to destination) (from source)))

>The with-english-grammar macro has access to the super-form of
>(from source) and (to destination) and can make the necesarray
>modifications.

Instead, I would like to write (as I elucidated in a former post and am
trying to clarify here):

;;; I could also use WITH-CUES locally and might do just that,
;;; but it isn't critical to this example.

(defmacro paraphrase (...)
  ; Psuedocode
  Walk the paraphrase and target function for their names and
arguments.
  Define a macro named by the paraphrase, which
  expands to the target function.
  ; Of course, the paraphrase and the target function will need
different names.

(paraphrase (unzip (files-listed-in ticket) (from source) (to target))
            (%unzipped source ticket target))
(paraphrase (unzipped ticket source target) (%unzipped source ticket
target))

* (pseudo-macro-expand '(unzipped (files-listed-in (("content.xml")))
(from "source.sxw")))
--> (%unzipped ("source.sxw") (("content.xml")) NIL)

(defun open-writer-document (filename)
  (unzipped (files-listed-in (("content.xml"))) (from filename)))

Why not just defun or defmethod unzip and unzipped? That doesn't give
me any more flexibility.
Given the paraphrase, I can call any of the following:
(unzip (files-listed-in ticket) (from source))
(unzip (from source) (files-listed-in ticket))
...
(unzipped (files-listed-in ticket) (from source) (to target))
...
And any permutation or combination.
...

Where I don't need full-blown paraphrasing, I can (elide-cue cue) to
give me the semantic cues in the code without affecting the result.

Why not just use keywords? Because, as I have shown in another post in
this thread
(http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/8a4b328a05c5b9ee/fffab3c1e475d92f#fffab3c1e475d92f),
using keywords with the desired semantic cues can make the code less
readable somewhere else (i.e., in the function definition).

>(with-english-grammar
>   (move-object (to destination) (from source)))

>The with-english-grammar macro has access to the super-form of
>(from source) and (to destination) and can make the necesarray
>modifications.

Why don't I just go all the way and write a full-blown English
syntactic and semantic parser? That's not the point here. I merely want
to make Lisp more readable for my purposes.

WITH-ENGLISH-GRAMMAR could be used to isolate a set of cues from the
rest of the package, but is it necessary now that I have defined it
without flubbing the example? I don't see otherwise wanting to define a
preposition as a function name. A package would isolate sufficiently
the few symbols I would necessarily use as cues.

Why not just use defun or defmacro for all of these permutations and
computations? Why indeed! Paraphrasing, as I have described it,
provides a new mechanism which allows arbitrary ordering of arguments
which the author defined explicitly yet arbitrarily. It might not gel
with formal mathematical notation, but we already have plenty of
programming languages that define specifications for defining
specifications so restrictively.

>Lisp already has a construct that serves exactly that purpose -- keyword
>arguments.  Combined with the package system, you can define your own
>version of any existing function or macro:

>(defpackage :cl-keyworded
>   (:use) ;not using COMMON-LISP!
>   (:export setf let))

>(in-package :cl-keyworded)

>(cl:defmacro setf (cl:&rest args)
>   `(cl:setf
>     ,@(cl:loop :for cons :on args :by #'cl:cdddr
>                :do (cl:assert (cl:eq (cl:second cons) :to))
>                :collect (cl:first cons) :collect (cl:third cons))))

>(cl:defmacro let (bindings cl:&body body)
>   `(cl:let ,(cl:loop :for (symbol cl:&key be) :in bindings
                      :collect (cl:list symbol be))
>      ,@body))

Your example here is interesting and clearly shows a different way to
do it than what I had envisioned. If I understand it correctly, you're
suggesting that cl-keworded:let would be used as follows:

(let ((foo :be bar))
  ...)

which would expand to

(cl:let ((foo bar))
  ...)

I could live with it, though I might have tried something to allow me
to do as follows:

(where ((ticket is a new instance of 'ticket)
        (document is "opus.sxw")
        (path is "target/path"))
  ...
  (unzip (files-listed-in ticket) (from document) (to path)))

--> (cl:let ((foo bar) (baz goop)...) ...)

BUT that doesn't use lispy keyword-syntax conventions, and here I've
stepped closer to natural language parsing. I'm not trying to modify
Lisp quite that much.

I could do as follows:

(defmacro elide-cue (cue)
  `(defmacro ,cue (form)
     form)

(elide-cue be)

(let ((ticket (be (make-instance 'ticket)))
      (document (be "opus.sxw))
      ...)
  ...)

It seems much simpler than wrestling with redefitions of LET and any
other form I want to bandage.

>(defmacro paraphrase ((old-name &rest old-args)
>                       (new-name &rest new-args))
>   `(defun ,new-name ,new-args
>      (,old-name ,@(paraphrase-lambda-list-args old-args))))

EXACTLY!

>I still don't think this is a good idea.  If you break the existing
>convention, other people will find it harder to help you, since they
>won't understand why let and setf are taking keyword arguments.

Well... I don't understand their code, so we're even.

>And I could not disagree with you more.  LOOP is *the* worst construct
>in the Common Lisp language, because it disregards everything that's
>good about computer programming.  Worse still, because LOOP's syntax is
>completely different from *the rest of Lisp*, I don't get
>autocompletion, indenting, or any other computer assistance.  So I have
>to parse its meaning, token by token, by hand.

LOOP is a domain-specific language. Why shouldn't it have its own
syntax?

If your tool doesn't give you autocompletion, indenting or other
assistance for a construct defined by the standard, then I'd assume
that your tool is broken and not the construct.

>You consider that "quite brilliant"?

Do you have a better idea for LOOP?

- Jack
From: M Jared Finder
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <9cCdnW6H78ReluHeRVn-qg@speakeasy.net>
Jack wrote:

>>The with-english-grammar macro has access to the super-form of
>>(from source) and (to destination) and can make the necesarray
>>modifications.
> 
<snip>
> Why not just defun or defmethod unzip and unzipped? That doesn't give
> me any more flexibility.
> Given the paraphrase, I can call any of the following:
> (unzip (files-listed-in ticket) (from source))
> (unzip (from source) (files-listed-in ticket))

But you can't do (map #'unzip tickets zip-files).  Even worse, you can't 
update your paraphrase with a bugfix without recompiling *every usage* 
of the paraphrase.  These are very useful abilities; you shouldn't give 
them up without a very very very good reason.

> ....
> (unzipped (files-listed-in ticket) (from source) (to target))
> ....
> And any permutation or combination.
> ....
> 
> Where I don't need full-blown paraphrasing, I can (elide-cue cue) to
> give me the semantic cues in the code without affecting the result.
> 
> Why not just use keywords? Because, as I have shown in another post in
> this thread
> (http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/8a4b328a05c5b9ee/fffab3c1e475d92f#fffab3c1e475d92f),
> using keywords with the desired semantic cues can make the code less
> readable somewhere else (i.e., in the function definition).

This link refers to a post of mine.  Was this in your discussion with 
Pascal?

>>(with-english-grammar
>>  (move-object (to destination) (from source)))
> 
> 
>>The with-english-grammar macro has access to the super-form of
>>(from source) and (to destination) and can make the necesarray
>>modifications.
> 
> Why don't I just go all the way and write a full-blown English
> syntactic and semantic parser? That's not the point here. I merely want
> to make Lisp more readable for my purposes.
> 
> WITH-ENGLISH-GRAMMAR could be used to isolate a set of cues from the
> rest of the package, but is it necessary now that I have defined it
> without flubbing the example? I don't see otherwise wanting to define a
> preposition as a function name. A package would isolate sufficiently
> the few symbols I would necessarily use as cues.
> 
> Why not just use defun or defmacro for all of these permutations and
> computations? Why indeed! Paraphrasing, as I have described it,
> provides a new mechanism which allows arbitrary ordering of arguments
> which the author defined explicitly yet arbitrarily. It might not gel
> with formal mathematical notation, but we already have plenty of
> programming languages that define specifications for defining
> specifications so restrictively.

You're right.  I see paraphrasing and with-english-grammar doing the 
same thing.  I'd prefer paraphrasing because it has the potential to be 
more lispy, if you make sure to define FUNCTIONS with your paraphrasing 
and not MACROS.

>>Lisp already has a construct that serves exactly that purpose -- keyword
>>arguments.  Combined with the package system, you can define your own
>>version of any existing function or macro:
> 
>>(defpackage :cl-keyworded
>>  (:use) ;not using COMMON-LISP!
>>  (:export setf let))
> 
> 
>>(in-package :cl-keyworded)
> 
> 
>>(cl:defmacro setf (cl:&rest args)
>>  `(cl:setf
>>    ,@(cl:loop :for cons :on args :by #'cl:cdddr
>>               :do (cl:assert (cl:eq (cl:second cons) :to))
>>               :collect (cl:first cons) :collect (cl:third cons))))
> 
> 
>>(cl:defmacro let (bindings cl:&body body)
>>  `(cl:let ,(cl:loop :for (symbol cl:&key be) :in bindings
> 
>                       :collect (cl:list symbol be))
> 
>>     ,@body))
> 
> 
> Your example here is interesting and clearly shows a different way to
> do it than what I had envisioned. If I understand it correctly, you're
> suggesting that cl-keworded:let would be used as follows:
> 
> (let ((foo :be bar))
>   ...)
> 
> which would expand to
> 
> (cl:let ((foo bar))
>   ...)

Yes.  It also shares much of the semantics of Lisp, making it easy to 
learn and reason about.

> I could live with it, though I might have tried something to allow me
> to do as follows:
> 
> (where ((ticket is a new instance of 'ticket)
>         (document is "opus.sxw")
>         (path is "target/path"))
>   ...
>   (unzip (files-listed-in ticket) (from document) (to path)))
> 
> --> (cl:let ((foo bar) (baz goop)...) ...)
> 
> BUT that doesn't use lispy keyword-syntax conventions, and here I've
> stepped closer to natural language parsing. I'm not trying to modify
> Lisp quite that much.

Uhg.  That gets me to wondering, why can't I say:

(where ((home-dir is my home directory)
         (socket is an open connection to "127.0.0.1:80")
         (phase is the phase of the moon))
   ...)

I don't see why I'd ever want something this.  I just get to discard one 
set of arbitraries for another, more verbose one!

> I could do as follows:
> 
> (defmacro elide-cue (cue)
>   `(defmacro ,cue (form)
>      form)
> 
> (elide-cue be)
> 
> (let ((ticket (be (make-instance 'ticket)))
>       (document (be "opus.sxw))
>       ...)
>   ...)
> 
> It seems much simpler than wrestling with redefitions of LET and any
> other form I want to bandage.

Because it gives no information to the underlying system, and a false 
sense of semantics to the programmer.  Assuming you had defined cues 
from and to, what do you expect

(let ((numbers (be (list (to 10) (from 1)))))
   ...)

to do?

If you want something that has no semantic value, don't make it look 
like it has semantic value.  Use comments.

>>And I could not disagree with you more.  LOOP is *the* worst construct
>>in the Common Lisp language, because it disregards everything that's
>>good about computer programming.  Worse still, because LOOP's syntax is
>>completely different from *the rest of Lisp*, I don't get
>>autocompletion, indenting, or any other computer assistance.  So I have
>>to parse its meaning, token by token, by hand.
> 
> LOOP is a domain-specific language. Why shouldn't it have its own
> syntax?

LOOP should have its own *semantics*, but not its own *syntax*.  I can 
not think of a good reason for a domain specific language to have its 
own syntax.  LOOP breaks Lisp syntax in two very important ways that are 
ultra confusing.

* Loop clauses are not represented as sexps.
* Loop clauses are named by strings, not symbols.




If you want a different syntax than Lisp, a different set of semantics 
than Lisp, without many of the cool features of Lisp, why are you coding 
in Lisp?

   -- MJF
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132274522.999487.262830@o13g2000cwo.googlegroups.com>
Mr. Finder wrote:

> This link refers to a post of mine.  Was this in your discussion with
> Pascal?

I apologize. That was the wrong link. I'd have to review to determine
where I intended to direct you, and at the moment it doesn't seem that
important.

Thanks for the pointers. I've noted your exceptions and need to decide
whether I'm ready to be assimilated. Despite the feeling that
resistance is futile, I still have some fight left in me.

> If you want a different syntax than Lisp, a different set of semantics
> than Lisp, without many of the cool features of Lisp, why are you coding
> in Lisp?

I recognize features in Lisp which might make it a great tool for
implementing an idea that has tugged at me me since childhood. I also
see that Lisp might allow me to change its shape just enough to suit my
fancy. If I can change its shape without forfeiting its power, where's
the problem?

-- Jack
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132162924.512964.242780@g44g2000cwa.googlegroups.com>
>What I was trying to say is that you won't be able to define macros TO
>and BE that would rearrange (move-object (to destination) (from source))
>to (move-object source destination).

I understand that. I flubbed one or more examples, because I was saying
what I wanted to say, without taking into account the recursion issue
in the code I generated for the examples. This confused everyone,
making them think that I didn't understand the issue, and for that I
apologize. I do understand that the macro and the resultant macro or
function need different names, unless I want to process it before the
macro expander evaluates it.

>You can't do this because macros
>have no access to the super-form they are in.   Instead, you will need
>to put some macro around all the forms that need to be processed, and
>use a code walker to process each subform, a la

>(with-english-grammar
>   (move-object (to destination) (from source)))

>The with-english-grammar macro has access to the super-form of
>(from source) and (to destination) and can make the necesarray
>modifications.

Instead, I would like to write (as I elucidated in a former post and am
trying to clarify here):

;;; I could also use WITH-CUES locally and might do just that,
;;; but it isn't critical to this example.

(defmacro paraphrase (...)
  ; Psuedocode
  Walk the paraphrase and target function for their names and
arguments.
  Define a macro named by the paraphrase, which
  expands to the target function.
  ; Of course, the paraphrase and the target function will need
different names.

(paraphrase (unzip (files-listed-in ticket) (from source) (to target))
            (%unzipped source ticket target))
(paraphrase (unzipped ticket source target) (%unzipped source ticket
target))

* (pseudo-macro-expand '(unzipped (files-listed-in (("content.xml")))
(from "source.sxw")))
--> (%unzipped ("source.sxw") (("content.xml")) NIL)

(defun open-writer-document (filename)
  (unzipped (files-listed-in (("content.xml"))) (from filename)))

Why not just defun or defmethod unzip and unzipped? That doesn't give
me any more flexibility.
Given the paraphrase, I can call any of the following:
(unzip (files-listed-in ticket) (from source))
(unzip (from source) (files-listed-in ticket))
...
(unzipped (files-listed-in ticket) (from source) (to target))
...
And any permutation or combination.
...

Where I don't need full-blown paraphrasing, I can (elide-cue cue) to
give me the semantic cues in the code without affecting the result.

Why not just use keywords? Because, as I have shown in another post in
this thread
(http://groups.google.com/group/comp.lang.lisp/browse_frm/thread/8a4b328a05c5b9ee/fffab3c1e475d92f#fffab3c1e475d92f),
using keywords with the desired semantic cues can make the code less
readable somewhere else (i.e., in the function definition).

>(with-english-grammar
>   (move-object (to destination) (from source)))

>The with-english-grammar macro has access to the super-form of
>(from source) and (to destination) and can make the necesarray
>modifications.

Why don't I just go all the way and write a full-blown English
syntactic and semantic parser? That's not the point here. I merely want
to make Lisp more readable for my purposes.

WITH-ENGLISH-GRAMMAR could be used to isolate a set of cues from the
rest of the package, but is it necessary now that I have defined it
without flubbing the example? I don't see otherwise wanting to define a
preposition as a function name. A package would isolate sufficiently
the few symbols I would necessarily use as cues.

Why not just use defun or defmacro for all of these permutations and
computations? Why indeed! Paraphrasing, as I have described it,
provides a new mechanism which allows arbitrary ordering of arguments
which the author defined explicitly yet arbitrarily. It might not gel
with formal mathematical notation, but we already have plenty of
programming languages that define specifications for defining
specifications so restrictively.

>Lisp already has a construct that serves exactly that purpose -- keyword
>arguments.  Combined with the package system, you can define your own
>version of any existing function or macro:

>(defpackage :cl-keyworded
>   (:use) ;not using COMMON-LISP!
>   (:export setf let))

>(in-package :cl-keyworded)

>(cl:defmacro setf (cl:&rest args)
>   `(cl:setf
>     ,@(cl:loop :for cons :on args :by #'cl:cdddr
>                :do (cl:assert (cl:eq (cl:second cons) :to))
>                :collect (cl:first cons) :collect (cl:third cons))))

>(cl:defmacro let (bindings cl:&body body)
>   `(cl:let ,(cl:loop :for (symbol cl:&key be) :in bindings
                      :collect (cl:list symbol be))
>      ,@body))

Your example here is interesting and clearly shows a different way to
do it than what I had envisioned. If I understand it correctly, you're
suggesting that cl-keworded:let would be used as follows:

(let ((foo :be bar))
  ...)

which would expand to

(cl:let ((foo bar))
  ...)

I could live with it, though I might have tried something to allow me
to do as follows:

(where ((ticket is a new instance of 'ticket)
        (document is "opus.sxw")
        (path is "target/path"))
  ...
  (unzip (files-listed-in ticket) (from document) (to path)))

--> (cl:let ((foo bar) (baz goop)...) ...)

BUT that doesn't use lispy keyword-syntax conventions, and here I've
stepped closer to natural language parsing. I'm not trying to modify
Lisp quite that much.

I could do as follows:

(defmacro elide-cue (cue)
  `(defmacro ,cue (form)
     form)

(elide-cue be)

(let ((ticket (be (make-instance 'ticket)))
      (document (be "opus.sxw))
      ...)
  ...)

It seems much simpler than wrestling with redefitions of LET and any
other form I want to bandage.

>(defmacro paraphrase ((old-name &rest old-args)
>                       (new-name &rest new-args))
>   `(defun ,new-name ,new-args
>      (,old-name ,@(paraphrase-lambda-list-args old-args))))

EXACTLY!

>I still don't think this is a good idea.  If you break the existing
>convention, other people will find it harder to help you, since they
>won't understand why let and setf are taking keyword arguments.

Well... I don't understand their code, so we're even.

>And I could not disagree with you more.  LOOP is *the* worst construct
>in the Common Lisp language, because it disregards everything that's
>good about computer programming.  Worse still, because LOOP's syntax is
>completely different from *the rest of Lisp*, I don't get
>autocompletion, indenting, or any other computer assistance.  So I have
>to parse its meaning, token by token, by hand.

LOOP is a domain-specific language. Why shouldn't it have its own
syntax?

If your tool doesn't give you autocompletion, indenting or other
assistance for a construct defined by the standard, then I'd assume
that your tool is broken and not the construct.

>You consider that "quite brilliant"?

Do you have a better idea for LOOP?

- Jack
From: Thomas A. Russ
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <ymi3blwqss9.fsf@sevak.isi.edu>
M Jared Finder <·····@hpalace.com> writes:
> Jack wrote:
> 
> > LOOP is quite brilliant. It allows the formation of compact
> > compound-very-complex sentences. The variable clauses resemble
> > [potentially compound] dependent clauses, and the main clause
> > represents the [potentially compound] independent clause(s). It mimics
> > English grammar very nicely, though I might improve the punctuation.

Jack should track down one of the sources of the loop macro and take a
look at all of the mechanism that is required to achieve that result.
The surface presentation of the form hides an awful lot of hairy
programming and parsing code.

> And I could not disagree with you more.  LOOP is *the* worst construct 
> in the Common Lisp language, because it disregards everything that's 
> good about computer programming.  Worse still, because LOOP's syntax is 
> completely different from *the rest of Lisp*, I don't get 
> autocompletion, indenting, or any other computer assistance.  So I have 
> to parse its meaning, token by token, by hand.

Hmmm.  I'll sidestep the religious argument about LOOP, but will admit
to being a fan.

I will note that a decent IDE, such as some of the Common Lisp modes for
Emacs (i.e., Allegro's fi:common-lisp-mode) do understand the loop macro
and its keywords and so give you the automatic indenting of the code in
a reasonable manner.  I can't see much benefit in autocompletion for
LOOP keywords since they are almost always pretty short.

> 
> You consider that "quite brilliant"?
> 
>    -- MJF

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: M Jared Finder
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <9cCdnWmH78TnkeHeRVn-qg@speakeasy.net>
Thomas A. Russ wrote:
> M Jared Finder <·····@hpalace.com> writes:
>
>>And I could not disagree with you more.  LOOP is *the* worst construct 
>>in the Common Lisp language, because it disregards everything that's 
>>good about computer programming.  Worse still, because LOOP's syntax is 
>>completely different from *the rest of Lisp*, I don't get 
>>autocompletion, indenting, or any other computer assistance.  So I have 
>>to parse its meaning, token by token, by hand.
> 
> Hmmm.  I'll sidestep the religious argument about LOOP, but will admit
> to being a fan.
> 
> I will note that a decent IDE, such as some of the Common Lisp modes for
> Emacs (i.e., Allegro's fi:common-lisp-mode) do understand the loop macro
> and its keywords and so give you the automatic indenting of the code in
> a reasonable manner.  I can't see much benefit in autocompletion for
> LOOP keywords since they are almost always pretty short.

Not so much autocompletion as the other computer assistance.  Being able 
to type "(mapcar ", and see "(mapcar function list &rest more-lists)" is 
great, especially when dealing with unfamiliar libraries.  This would be 
much harder to do with LOOP because loop clauses are not sexps.

   -- MJF
From: Thomas F. Burdick
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <xcvsltvt7th.fsf@conquest.OCF.Berkeley.EDU>
···@sevak.isi.edu (Thomas A. Russ) writes:

> M Jared Finder <·····@hpalace.com> writes:
>
> > And I could not disagree with you more.  LOOP is *the* worst construct 
> > in the Common Lisp language, because it disregards everything that's 
> > good about computer programming.  Worse still, because LOOP's syntax is 
> > completely different from *the rest of Lisp*, I don't get 
> > autocompletion, indenting, or any other computer assistance.  So I have 
> > to parse its meaning, token by token, by hand.
> 
> Hmmm.  I'll sidestep the religious argument about LOOP,

Wimp

> but will admit to being a fan.

A wimp with a saving grace at least :-)

Rather than side-step the religious argument, I'll repeat myself:

http://groups.google.com/group/comp.lang.lisp/msg/fc76412f5d65080c

-- 
           /|_     .-----------------------.                        
         ,'  .\  / | Free Mumia Abu-Jamal! |
     ,--'    _,'   | Abolish the racist    |
    /       /      | death penalty!        |
   (   -.  |       `-----------------------'
   |     ) |                               
  (`-.  '--.)                              
   `. )----'                               
From: Barry Margolin
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <barmar-20339A.20404114112005@comcast.dca.giganews.com>
In article <························@g43g2000cwa.googlegroups.com>,
 "Jack" <············@msn.com> wrote:

> (setf buffers (unzip ticket zipfile path))
> 
> violate some linguistic and/or aesthetic rules and should be written
> 
> (let ((buffers (UNZIPPED ticket zipfile path)))...)

Lisp doesn't typically use this type of naming convention.  Function 
names are typically active, command-style verbs, rather than past-tense 
like this.  For instance, we write

(setq stream (open "filename"))
(setq total (+ val1 val2 val3))

not

(setq stream (opened "filename"))
(setq total (summed val1 val2 val3))

We're not trying to mimic English (except in LOOP).

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132027202.042420.184540@g14g2000cwa.googlegroups.com>
Barry Margolin wrote:

>> (setf buffers (unzip ticket zipfile path))

>> violate some linguistic and/or aesthetic rules and should be written

>> (let ((buffers (UNZIPPED ticket zipfile path)))...)

> Lisp doesn't typically use this type of naming convention.  Function
> names are typically active, command-style verbs, rather than past-tense
> like this.

I understand that it isn't how it is typically done. I'm not trying to
change how other people do it. I admit that I have a knee-jerk reaction
to expressing ideas in an awkward manner or parsing that kind of
awkwardness. I've identified certain aspects of formal notations that
have made it more difficult for me. I struggled with C and Java for
many years. For many years, I stared at C code, wanting to retch every
time I had to even look at the standard libraries. I wrote many lines
of C and Java code, all the while wishing I could express ideas how I
wanted to express them. My personal projects often ended up in the
trash been, mired by the weight of the spaghetti.

I cringe every time I see a comment that merely paraphrases a function
signature in order to document it for the API documentation. Many would
say that this is ineffective use of comments, but most of the time, the
lack of cues, such as prepositions, makes it necessary to disambiguate
between, for example, p1 and p2. If the code had the cues, you might
not need the paraphrase, which could be automatically transcribed,
given those cues. (One might rightly ask why we're not just programming
with natural language, if such automatic translation is possible. Let's
not go there. That dead horse has been beaten to an unrecognizable lump
of protoplasm, and the naysayers who whine about ambiguity are dead
wrong.) More appropriate argument naming would also alleviate the
problem, but this might adversely affect the understandability of the
code in the body of the function.

I react similarly to poorly written prose, with which the Internet is
absolutely swamped. This kind of rubbish reflects sloppy thinking and
puts the burden on the reader. (A few people have called me a grammar
nazi.) Whenever I happen upon something from someone who can't write a
coherent sentence, especially when English is obviously the person's
native language, very rarely do I not change the channel and move on to
something else.

Though I haven't studied Lisp for very long, I see that it might offer
me the flexibility to express ideas how I would prefer to express them.

> For instance, we write

> (setq stream (open "filename"))
> (setq total (+ val1 val2 val3))

> not

> (setq stream (opened "filename"))
> (setq total (summed val1 val2 val3))

Whereas I find (setq total (+ val1 val2 val3)) perfectly acceptable,
I'd prefer (setq stream (opened "filename")).

I recently read in a popular Lisp textbook (to paraphrase) that to
write a program functionally, you express what you want and not how to
do it--at the moment, the name of the author escapes me. Now, if you
want to write imperatively, by all means, (open "filename") fits the
problem. On the other hand, (setq stream (open "filename")) is just
ugly, despite the convention of the majority.

By the way, in the example given above, for (UNZIPPED ticket...),
unzipped is not the past tense of a verb but an adjective modifying
ticket (or in the elided subsequent example, the phrase
:files-listed-in ticket). If an adjective not formed from the past
tense of a verb and denoting an uncompressed state (as opposed to a
compressed state) came to mind when I defined the function, I would
have used that word instead. When I wrote that I'd prefer to write
(unzipped :files-listed-in ticket :from zipfile :to path), that's
precisely what I want the function to give me, and it aligns with the
aforementioned principle about naming what you want, which I think is a
very good idea.

Paraphrasing the function allows the flexibility to express a problem
succinctly in whichever manner suits the expression. Within a progn,
where the problem doesn't require the caller to save the result of the
function, (UNZIP ticket...) expresses exactly what the expression
entails. In a LET or a SETF, I'd prefer UNZIPPED. (I'm up in the air
about the return form in PROGN, LET, etc. I suppose I would lean toward
the imperative in those cases.) I see nothing wrong with having it both
ways.

> We're not trying to mimic English (except in LOOP).

It's not about expressing everything in natural language. It's about
expressing things in ways that I find easier for my brain to parse, so
that when I need to read my own writing, I don't need to reparse it
several times to understand what I wrote.

You coyly admitted LOOP as an exception. Does that mean that the
symbols you choose for all of your functions and other objects don't
convey anything about what they represent in English or another natural
language? Does (f "filename") denote (open "filename")? Does (asdfjkl
qwer uio) denote (draw-line [from] p1 [to] p2)? For the sake of others
who need to read your code, I hope not! If it makes you happy, more
power to you, as long as I don't need to understand your code.

Though I appreciate the ideas, I didn't necessarily ask about the
convention. I did ask how to do it otherwise, so that I could do it
otherwise. If nobody appreciates my elegantly expressed code, I won't
require them to read it. However, I must admit that I do impress
myself. (Ha ha!)

- Jack
From: Pascal Bourguignon
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <87veyuhzl9.fsf@thalassa.informatimago.com>
"Jack" <············@msn.com> writes:
> I cringe every time I see a comment that merely paraphrases a function
> signature in order to document it for the API documentation. Many would
> say that this is ineffective use of comments, but most of the time, the
> lack of cues, such as prepositions, makes it necessary to disambiguate
> between, for example, p1 and p2. If the code had the cues, you might
> not need the paraphrase, which could be automatically transcribed,
> given those cues. (One might rightly ask why we're not just programming
> with natural language, if such automatic translation is possible. Let's
> not go there. That dead horse has been beaten to an unrecognizable lump
> of protoplasm, and the naysayers who whine about ambiguity are dead
> wrong.) More appropriate argument naming would also alleviate the
> problem, but this might adversely affect the understandability of the
> code in the body of the function.


Do you know perligata?  If not, you might read about it, it gives an
interesting perspective.  (Don't use it unless to adapt it to lisp :-)
http://www.csse.monash.edu.au/~damian/papers/HTML/Perligata.html

> By the way, in the example given above, for (UNZIPPED ticket...),
> unzipped is not the past tense of a verb but an adjective modifying
> ticket (or in the elided subsequent example, the phrase
> :files-listed-in ticket). If an adjective not formed from the past
> tense of a verb and denoting an uncompressed state (as opposed to a
> compressed state) came to mind when I defined the function, I would
> have used that word instead. When I wrote that I'd prefer to write
> (unzipped :files-listed-in ticket :from zipfile :to path), that's
> precisely what I want the function to give me, and it aligns with the
> aforementioned principle about naming what you want, which I think is a
> very good idea.

Yes, you would go a long way using intensively keyword parameters.


> Paraphrasing the function allows the flexibility to express a problem
> succinctly in whichever manner suits the expression. Within a progn,
> where the problem doesn't require the caller to save the result of the
> function, (UNZIP ticket...) expresses exactly what the expression
> entails. In a LET or a SETF, I'd prefer UNZIPPED. (I'm up in the air
> about the return form in PROGN, LET, etc. I suppose I would lean toward
> the imperative in those cases.) I see nothing wrong with having it both
> ways.

Note that a stray keyword gets self-evaluated  and ignored; you can write:

 (progn
     (do-something)
   :and-then
     (do-something-else)
   :finally-return
     (some-result))


or:

 (prog1 (some-result) :is-the-result
   :but-do (something)
   :and-then (something-else)
   :before-returning)


Compilers don't see the difference:


[161]> (disassemble(compile nil (lambda () (progn
     (do-something)
   :and-then
     (do-something-else)
   :finally-return
     (some-result)))))
WARNING :
Function DO-SOMETHING is not defined
WARNING :
Function DO-SOMETHING-ELSE is not defined
WARNING :
Function SOME-RESULT is not defined

Disassembly of function NIL
(CONST 0) = DO-SOMETHING
(CONST 1) = DO-SOMETHING-ELSE
(CONST 2) = SOME-RESULT
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0     (CALL0 0)                           ; DO-SOMETHING
2     (CALL0 1)                           ; DO-SOMETHING-ELSE
4     (CALL0 2)                           ; SOME-RESULT
6     (SKIP&RET 1)
NIL
[162]> (disassemble(compile nil (lambda () (progn
     (do-something)
     (do-something-else)
     (some-result)))))
WARNING :
Function DO-SOMETHING is not defined
WARNING :
Function DO-SOMETHING-ELSE is not defined
WARNING :
Function SOME-RESULT is not defined

Disassembly of function NIL
(CONST 0) = DO-SOMETHING
(CONST 1) = DO-SOMETHING-ELSE
(CONST 2) = SOME-RESULT
0 required arguments
0 optional arguments
No rest parameter
No keyword parameters
4 byte-code instructions:
0     (CALL0 0)                           ; DO-SOMETHING
2     (CALL0 1)                           ; DO-SOMETHING-ELSE
4     (CALL0 2)                           ; SOME-RESULT
6     (SKIP&RET 1)
NIL
[163]> 



>> We're not trying to mimic English (except in LOOP).
>
> It's not about expressing everything in natural language. It's about
> expressing things in ways that I find easier for my brain to parse, so
> that when I need to read my own writing, I don't need to reparse it
> several times to understand what I wrote.
>
> You coyly admitted LOOP as an exception. Does that mean that the
> symbols you choose for all of your functions and other objects don't
> convey anything about what they represent in English or another natural
> language? Does (f "filename") denote (open "filename")? 


Well, if you consider that you can use keywords in loop (and I'd say
you should use them to avoid name collisions in some cases), LOOP is a
small exception:

   (loop :for i :from 1 :to 10 :do (print i))

The exception of LOOP is that you can use a keyword twice, and the
order of the keywords is specified by LOOP syntax:

   (loop 
      :for i :from  1 :to  10
      :for j :from -1 :to -10
      :do (print (- i j)))

You cannot write: (loop :to 10 :from 1 :do (print i) :for i)


> Does (asdfjkl qwer uio) denote (draw-line [from] p1 [to] p2)? 

What does (asdfg [eqwr] p1 [wg] p2) denote?
How do you implement the sematics of your cues?
If you translate them as the identity function, then they're meaningless.

> For the sake of others
> who need to read your code, I hope not! If it makes you happy, more
> power to you, as long as I don't need to understand your code.
>
> Though I appreciate the ideas, I didn't necessarily ask about the
> convention. I did ask how to do it otherwise, so that I could do it
> otherwise. If nobody appreciates my elegantly expressed code, I won't
> require them to read it. However, I must admit that I do impress
> myself. (Ha ha!)
>
> - Jack

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132070351.874759.70190@g14g2000cwa.googlegroups.com>
Pascal Bourguignon wrote:

> Do you know perligata?  If not, you might read about it, it gives an
> interesting perspective.  (Don't use it unless to adapt it to lisp :-)
> http://www.csse.monash.edu.au/~damian/papers/HTML/Perligata.html

That is very interesting! I'll have to look at it in more depth later.
Thanks for the link.

>Note that a stray keyword gets self-evaluated  and ignored; you can write:

> (progn
>     (do-something)
>   :and-then
>     (do-something-else)
>   :finally-return
>     (some-result))

That's perfect! I did not remember the stray keyword rule. Of course,
this comes from me not knowing the standard well enough yet. This sort
of negates the need for ELIDE-CUE--though I find it more proper to
actually specify in the code what the cues mean and that they will not
affect the evaluation of the subsequent form. (Sure, one could use
inline comments (move object #|from|# p1 #|to|# p2), to the same
effect, but the syntax of the reader macro for inline comments adds
NOISE that obscures the signal.) However, the stray cue idea does look
slightly better than (to object) which might violate the lisp
convention of the first symbol in a list denoting a function. (Note
that this reasoning breaks down when you consider the init-forms in a
let, amoung other constructs that I don't recall off the top of my
head.)

In fact, I see a possibility for using these stray keywords in a
paraphrase to reorder (if necessary) arbitrarily ordered arguments. (If
the compiler munges the stray keywords, would arbitrary keywords be
available to the paraphrase macro?)

>You cannot write: (loop :to 10 :from 1 :do (print i) :for i)

LOOP exception duly noted. Thanks.

>What does (asdfg [eqwr] p1 [wg] p2) denote?
>How do you implement the sematics of your cues?

Oops! I was mixing Lisp with the English convention of using square
brackets to annotate omissions in context.

> If you translate them as the identity function, then they're meaningless.

In one of your previous posts in this thread, you used the word
meaningless in the same context. Yes, it is meaningless noise to the
compiler. No, it is not meaningless noise to the human reader, because
it adds meaning by adding semantics which map directly to the reader's
pre-existing layers of knowledge. (asdf jkl uio) is meaningless without
the proper context. Even within context, the jumbles of letters don't
map directly to something that the reader understands directly. (move
object :from p1 :to p2 :with energy) is very clear, even to someone who
isn't well versed in the science of physics. Whereas the physicist
might recognize immediately (f p1 p2 e), (move object...) makes it
abundantly clear, even when the author returns to the code after having
put it aside for some time. Yes, it is meaningless to the compiler,
just as the ignored stray keywords. This particular notation isn't
meant to be for the compiler. It's for the human who needs to read the
code, and to *this* human, it is not meaningless.

Thanks again for all of your useful ideas. You've helped clarify a few
things for me.

- Jack
From: Barry Margolin
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <barmar-805074.20415615112005@comcast.dca.giganews.com>
In article <························@g14g2000cwa.googlegroups.com>,
 "Jack" <············@msn.com> wrote:

> You coyly admitted LOOP as an exception. Does that mean that the
> symbols you choose for all of your functions and other objects don't
> convey anything about what they represent in English or another natural
> language?

We use the English vocabulary to convey what's happening, but other than 
LOOP, which is admitted to be an aberration, we don't try to mimic 
English grammar.  It's actually more like mathematical functional 
notation -- that's where LET comes from.

-- 
Barry Margolin, ······@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
From: Thomas A. Russ
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <ymiu0ebp0dl.fsf@sevak.isi.edu>
"Jack" <············@msn.com> writes:

> I cringe every time I see a comment that merely paraphrases a function
> signature in order to document it for the API documentation. Many would
> say that this is ineffective use of comments, but most of the time, the
> lack of cues, such as prepositions, makes it necessary to disambiguate
> between, for example, p1 and p2.

I doubt it is the lack of prepositions, but rather the choice of
information-free names that cause the problem.  If argument names are
sensible, then there is often no need for other syntactic markers.

-- 
Thomas A. Russ,  USC/Information Sciences Institute
From: Pascal Bourguignon
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <87acg6kij1.fsf@thalassa.informatimago.com>
"Jack" <············@msn.com> writes:
> (progn (unzip ticket zipfile path)...)
> (let ((buffers (unzip ticket zipfile path))) ...)
> (setf buffers (unzip ticket zipfile path))
> (let ((buffers (UNZIPPED ticket zipfile path)))...)
> (setf buffers (UNZIPPED ticket zipfile path))
> (let ((buffers (BE (unzipped :files-listed-in ticket :from zipfile :to path))))...)
> (let ((buffers (BE (unzipped (files-listed-in ticket) (from zipfile) (to path)))))...)
> (setf buffers (TO (unzipped :files-listed-in ticket :from zipfile :to path)))
> (setf buffers (TO (unzipped (files-listed-in ticket) (from zipfile) (to path))))


The first lesson of lisp is that it doesn't matter.
Be done with syntax, just choose a unique prefix token.


> QUESTION #1: Please, forgive my ignorance. I have experimented with
> REPL (SBCL) and haven't determined how to write a macro
>
> (defmacro elide-cue (cue...)...)
>
> which would expand
>
> (elide-cue to...)

This is not possible, because the macroexpansion goes on expanding the macro.

You could write:

[115]> (defun %elide-cue (&rest args) "...")
%ELIDE-CUE
[116]> (defmacro elide-cue (&rest args) `(%elide-cue ,@(cdr args)))
ELIDE-CUE
[117]> (macroexpand '(elide-cue cue etc))
(%ELIDE-CUE ETC) ;
T
[118]> 


> allowing me to elide the cue TO in, for example, FIGs 1 and 2. Can a
> defmacro expand to another defmacro? 

This can be another macro or another function, but it cannot be the
same macro (unless you can stop the recursion eventually).


> QUESTION #2: For now, let's forget the difficulty I've had with macro
> syntax. Is there any reason why it wouldn't be possible to write a
> macro PARAPHRASE that would allow me to write, for instance,
>
> (PARAPHRASE (unzip...) (unzipped...))
>
> in order to allow different means to call the same function, without
> having the paraphrase expand to another function call? (As above, I
> envision a macro expanding to another macro.) Of course, I'd like to
> have the PARAPHASE macro examine the arguments for cue forms, in order
> to determine whether the caller chose to change the order of the
> arguments.
>
> For example,
>
> (move-object (FROM p1) (TO p2))
>
> would mean the same as
>
> (move-object (TO p2) (FROM p1))
>
> and actually calls
>
> (move-object p1 p2)

Well, you can do it the hard way, or you can just use what CL provides
you: keyword arguments.

(defun move-object (&key (from nil from-p) (to nil to-p))
   ...)

(move-object)
(move-object :to x)
(move-object :to x :from y)
(move-object :from y :to x)
(move-object :from y)


Now, to answer to your question: are you able to write a function that
takes a list such as: (m (f p) (t q)) or (m (t q) (f p))
and return a list as: (m p q) ?

Macros are mere functions!


> Such an abstraction would allow me to leverage existing code in my own
> style, where for whatever reason the original author's style disagrees
> with me. Effectively, I want an expedient mechanism to make my code
> easier for me to read. After all, I tend to read code more than I write
> it. Am I asking too much from Lisp?

No.


> Has anyone used macros to do such paraphrasing? 

Yes.


> How would you write a
> PARAPHRASE macro for the functionality described above?

As any other random function.




[121]> (defun order-values (pattern list-of-key-value-lists)
   (loop :with result  = '()
         :for key :in pattern
         :for assoc = (assoc key list-of-key-value-lists)
         :do (if (null assoc)
                (error "Missing parameter ~A" key)
                (push (second assoc) result))
         :finally (return (nreverse result))))
ORDER-VALUES
[122]> (order-values '(from to) '((to "to") (from "from")))
("from" "to")
[123]> (order-values '(from to) '((from "from") (to "to")))
("from" "to")
[124]> (order-values '(from to) '((from "from")))

*** - Missing parameter TO
The following restarts are available:
ABORT          :R1      ABORT
Break 1 [125]> :q

[126]> (dolist (form '( (m (f "f") (t "t"))
                        (m (t "t") (f "f")) ))
  (print (cons (car form) (order-values '(f t) (cdr form)))))


(M "f" "t") 
(M "f" "t") 
NIL


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
You're always typing.
Well, let's see you ignore my
sitting on your hands.
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132017357.520648.145490@g43g2000cwa.googlegroups.com>
Pascal wrote:

> The first lesson of lisp is that it doesn't matter.
> Be done with syntax, just choose a unique prefix token.

To whom does it not matter? I would be done with it if I didn't find
myself constantly backtracking at the mere sight of certain
constructions and indeed all elements lacking the contextual cues which
I addressed in the original post. Many programming languages map so
closely to natural language, as a reference aid, but most omit the cues
to give the reader context. For any given library, for each function
the reader must map the arbitrary symbol order chosen by the author to
one's pre-existing knowledge to form a complete picture of the process.
Every time the reader happens upon each element, the reader has to
refer to this new map (another layer atop the reader's pre-existing
layers of knowledge). This doesn't add much overhead for simpler
problems, but for more complex problems it becomes a burden [especially
for me].

Aside from arbitrary order of arguments to a function, one form in
particular often stops me in my tracks, for example:

(defclass thing
  ((widget :acessor widget)))

...

Where something is a thing:

(setf var (widget something))

When trying to analyse someone else's code, seeing (widget something)
often has me scratching my head, while I'm trying to parse what it
means.

I would prefer to construct it as follows:

(defclass thing
  ((widget :accessor widget-of)))

Then (widget-of something) is immediately clear to me.

However, in most third-party libraries, I see (widget something), and I
can't change how other people choose to construct the description.
Therefore, I see paraphrasing as a possible alternative.

>> (defmacro elide-cue (cue...)...)

>> which would expand

>> (elide-cue to...)

> This is not possible, because the macroexpansion goes on expanding the macro.

PREPOSTEROUS! I can't tell you how many times I've read about the power
of Lisp macros, specifically the use of macros to produce macros. If a
macro can expand to a DEFUN, it would seem to involve no more to expand
it to another defmacro:

(defmacro elide-cue (cue &rest body) ...)

where (elide-cue to) could expand to

(defmacro to (&rest body)
  append body)

in which case (to something) would simplify to something which would
evaluate something.

Right? Wrong? Why can't it be done?

Of course, if I understood the backquote syntax enough to actually do
it, I wouldn't have asked the question.

> You could write:

>[115]> (defun %elide-cue (&rest args) "...")
>%ELIDE-CUE
>[116]> (defmacro elide-cue (&rest args) `(%elide-cue ,@(cdr args)))
>ELIDE-CUE
>[117]> (macroexpand '(elide-cue cue etc))
>(%ELIDE-CUE ETC) ;
>T
>[118]>

Why the need for the (DEFUN %elide-cue...)? I parse that as a runtime
function call? No?

Aha! I think I just discovered why my macroexpand kept kicking me into
the debugger. I fouled up the quote. Thanks for the reminder. I was
familiar with macroexpand, but I screwed up the execution.

* (defmacro elide-cue (cue) `(progn (defmacro ,cue (&rest body) body)))

ELIDE-CUE
* (elide-cue to)

TO
* (to 42)
; in: LAMBDA NIL
;     (42)
;
; caught ERROR:
;   illegal function call
;
; compilation unit finished
;   caught 1 ERROR condition

debugger invoked on a SB-INT:COMPILED-PROGRAM-ERROR in thread #<THREAD
"initial thread" {9003451}>:
  Execution of a form compiled with errors.
Form:
  (42)
Compile-time-error:
  illegal function call

Type HELP for debugger help, or (SB-EXT:QUIT) to exit from SBCL.

restarts (invokable by number or by possibly-abbreviated name):
  0: [ABORT] Exit debugger, returning to top level.

(NIL)
0]

OOPS! If I parse this correctly, it's trying to (apply #'42)... which
doesn't work, of course. I'm at a loss as to how to correctly splice
the body into the macro.... Onward!

Essentially, my problem with your macro is that it looks to me like a
run-time function call. One could change it to a compile-time function
call, but I don't understand why it requires a defun at all.

> Well, you can do it the hard way, or you can just use what CL provides
> you: keyword arguments.

> (defun move-object (&key (from nil from-p) (to nil to-p))
>   ...)

Keywords work for functions that I define, but what about third-party
libraries that I merely want to clarify with paraphrases?

> Macros are mere functions!

Ah, but a macro "function" allows one to transform code at compile
time, instead of run time. If I wanted to evaluate something at run
time I'd use a function definition. Yes?

Thanks for the example ORDER-VALUES. I'll look at it more closely when
I can give it the attention it deserves. At the moment, my brain is
burnt, and I need to run an errand.

-Jack
From: Stephen Compall
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <pan.2005.11.15.02.04.57.828879@gmail.com>
On Mon, 14 Nov 2005 17:15:57 -0800, Jack wrote:
>> This is not possible, because the macroexpansion goes on expanding the macro.
> 
> PREPOSTEROUS! I can't tell you how many times I've read about the power
> of Lisp macros, specifically the use of macros to produce macros. If a
> macro can expand to a DEFUN, it would seem to involve no more to expand
> it to another defmacro:
> 
> (defmacro elide-cue (cue &rest body) ...)
> 
> where (elide-cue to) could expand to
> 
> (defmacro to (&rest body)
>   append body)

I think the confusion was caused by your original example expansion,
which looked like (elide-cue to) expands to (elide-cue to), which
barring side effects or outside influences would go on expanding
forever.

Mr Bourguignon already mentioned the condition under which you could
expand the macro to another call to itself.

-- 
Stephen Compall
My email username is s11, and my domain is member..org, except insert
the abbreviation for "Free Software Foundation" between the dots.
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132033751.010703.83310@g14g2000cwa.googlegroups.com>
Stephen Compall wrote:

>I think the confusion was caused by your original example expansion,
>which looked like (elide-cue to) expands to (elide-cue to), which
>barring side effects or outside influences would go on expanding
>forever.

>Mr Bourguignon already mentioned the condition under which you could
>expand the macro to another call to itself.

I tried to spell out my intentions as clearly as possible, and I
thought I did. I did consider a possible mistranslation of my goal,
considering Mr. Bourguignon's reference to recursive macro expansion,
which had little if nothing to do with the problem as I stated it. I
can see the possible misunderstanding, given how I originally snipped
the desired expansion of (elide-cue to...) (which should have been
(elide-cue to), without the ellipses). I thought the previous
explanation made it clear: (TO form2) ==> (form2).

Thanks for pointing out the possible confusion.

- Jack
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132034363.185205.102810@g14g2000cwa.googlegroups.com>
> (TO form2) ==> (form2)

AAARGH! That would be

(TO form2) ==> form2
From: Pascal Bourguignon
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <873blyk60m.fsf@thalassa.informatimago.com>
"Jack" <············@msn.com> writes:
>> Macros are mere functions!
>
> Ah, but a macro "function" allows one to transform code at compile
> time, instead of run time. If I wanted to evaluate something at run
> time I'd use a function definition. Yes?

Of course, but you can start with a function, and encapsulate it in a
macro when it works as you want:



[133]> (eval-when (:compile-toplevel :load-toplevel :execute)
   (defun f (parameters body)
      `(progn (print 'begin) (prog1 (let ,@parameters ,@body)  (print 'end)))))

F
[134]> (f '(x (y 1) (z 0)) '((setf x y) (incf y) (print (list x y z))))
(PROGN (PRINT 'BEGIN)
 (PROG1 (LET X (Y 1) (Z 0) (SETF X Y) (INCF Y) (PRINT (LIST X Y Z)))
  (PRINT 'END))) ;;; Oops there's a bug...
[135]> (eval-when (:compile-toplevel :load-toplevel :execute)
   (defun f (parameters body)
      `(progn (print 'begin) (prog1 (let ,parameters ,@body)  (print 'end)))))
F
[136]> (f '(x (y 1) (z 0)) '((setf x y) (incf y) (print (list x y z))))
(PROGN (PRINT 'BEGIN)
 (PROG1 (LET (X (Y 1) (Z 0)) (SETF X Y) (INCF Y) (PRINT (LIST X Y Z)))
  (PRINT 'END)))
[137]> (defmacro m (parameters &body body)
   (f parameters body))
M
[138]> (macroexpand '(m (x (y 1) (z 0))  (setf x y) (incf y) (print (list x y z))))
(PROGN (PRINT 'BEGIN)
 (PROG1 (LET (X (Y 1) (Z 0)) (SETF X Y) (INCF Y) (PRINT (LIST X Y Z)))
  (PRINT 'END))) ;
T
[139]> (m (x (y 1) (z 0))  (setf x y) (incf y) (print (list x y z)))

BEGIN 
(1 2 0) 
END 
(1 2 0)
[143]> 



You cannot expand a macro to itself unless you eventually expand it to
something else.

(elide-cue ...) --> (elide-cue ...) is no good.

(elide-cue to ...) --> (elide-cue ...) could be ok, if you specified
what (elide-cue ...) expands to.

(defmacro elide-cue (&body body)
  (if (eq (car body) 'to)
      `(elide-cue ,@(cdr body))
      `(progn ,@body)))
 
Then:

[144]> (macroexpand '(elide-cue to to))
(PROGN) ;
T

which is perhaps not what you want.  You could write directly:

(defmacro elide-cue (&body body)
  (if (eq (car body) 'to)
      `(progn ,@(cdr body))
      `(progn ,@body)))


[149]> (macroexpand '(elide-cue to to))
(PROGN TO) ;
T

Or, to generalize:

(defmacro elide-cue (&body body)
  (%elide-cue body))

(defun %elide-cue (body)
  (if (eq (car body) 'to)
      `(progn ,@(cdr body))
      `(progn ,@body)))

[159]> (macroexpand '(elide-cue to to))
(PROGN TO) ;
T




Now, if you want to define additionnal identity operators, you don't
need a macro:

(defun to   (x) x)
(defun from (x) x)
(defun with (x) x)
(defun by   (x) x)

(+ 2 (with 3))
(* 4 (by (- (from 3) 1)))

But this doesn't mean anything.


But perhaps a cue doesn't mean the same thing in another context.
Then you'd have to define them not globally, but locally within a
macro:

(defmacro with-cue-language-number-1 (&body body)
  `(macrolet ((to (x) ...)
              (from (x) ...))
     (flet ((with (x) ...))
            (without (x) ...))
        (progn ,@body)))


(defmacro with-cue-language-number-2 (&body body)
  `(macrolet ((the  (x) ...)
              (a    (x) ...)
              (an   (x) ...)
              (some (x) ...)
              (no   (x) ...)
              (any  (x) ...)
              (to   (x) ...))
     (flet ((eat (x) ...))
            (grow (x) ...))
        (progn ,@body)))

Then you can write:

(with-cue-language-number-1
    (move (from x) (to y) (with energy)))

(with-cue-language-number-2
    (do (to eat)
      (if (eat (some (animal x)) (no animal))
         (progn (grow (any (plant y)))
                (eat x y)))))




-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
The rule for today:
Touch my tail, I shred your hand.
New rule tomorrow.
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132037363.974861.208710@z14g2000cwz.googlegroups.com>
I see the source of the confusion. I tried to correct it in a
subsequent post, responding to my original post.

I wrote:

>PS: The last example,

>> (move-object (FROM p1) (TO p2))

>> would mean the same as

>> (move-object (TO p2) (FROM p1))

>> and actually calls

>> (move-object p1 p2)

>is obviously flawed. As written, it would require a preprocessor.
>Assuming MOVE-OBJECT is a paraphrase of another function signature, the
>last line would read (moving-object p1 p2) or some such deviation.

I understand that the original construction was flawed, having the
macro expand to itself, which would expand to itself, etc.

That wasn't my intention.

Mr. Bourguignon wrote:

>(defmacro with-cue-language-number-1 (&body body)
>  `(macrolet ((to (x) ...)
>              (from (x) ...))
>     (flet ((with (x) ...))
>            (without (x) ...))
>        (progn ,@body)))

>(defmacro with-cue-language-number-2 (&body body)
>  `(macrolet ((the  (x) ...)
>              (a    (x) ...)
>              (an   (x) ...)
>              (some (x) ...)
>              (no   (x) ...)
>              (any  (x) ...)
>              (to   (x) ...))
>     (flet ((eat (x) ...))
>            (grow (x) ...))
>        (progn ,@body)))

>Then you can write:

>(with-cue-language-number-1
>    (move (from x) (to y) (with energy)))

Now we're getting somewhere! I suggested using the macro (elide-cue
cue) to allow me to omit the contextual cue with a simple (elide-cue
TO).

In my first reply to you, I suggested the following malformed
construction:

* (defmacro elide-cue (cue) `(progn (defmacro ,cue (&rest body) body)))

ELIDE-CUE
* (elide-cue to)

TO

Of course this failed with use:

* (to 42)

because it expands to  (42) instead of 42.

Instead of splicing the body into the expansion, it appended the list,
which (if I understand correctly) tries to call the function #'42. I
played with elide-cue in different forms, i.e. substituting ,body and
,@body. It kept giving me warnings about body being undefined, but I
don't remember if I tried it after wrapping the inner defmacro in the
progn. I decided to show my effort, in order to clarify my intent. I'll
need to experiment in REPL some more.

Basically, this would afford me

(elide-cue to)
(elide-cue from)
...

And if I wanted to get fancy, modifying the elide-cue could afford me

(elide-cues to from)

for which

(to 42) --> 42
(to x) --> x
(to (perform-some-function 42)) --> (perform-some-function 42)

These one-liner elisions offer both succinctness and expressiveness. At
a glance, I know that (elide-cue to) defines TO as a contextual cue
which will not have any effect on the evaluation of forms in which it
appears, due to its elision.

I do see the value of having elisions defined locally and might
formulate it as

(eliding (to from)
  ...)

or even

(with-elisions (to from)
  ...)

where (eliding...) or (with-elisions...) would expand to some form of
macrolet + flet (forms with which I'm not yet very familiar).

I'll need to work with it some more.

I sincerely appreciate your efforts, and your Lisp fluency truly
impresses me.

- Jack
From: Lars Brinkhoff
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <85br0mte55.fsf@junk.nocrew.org>
"Jack" <············@msn.com> writes:
> (defmacro elide-cue (cue) `(progn (defmacro ,cue (&rest body) body)))

I believe you want something like this:

    (defmacro elide-cue (cue)
      `(defmacro ,cue (form)
         form))
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132071211.345359.211770@o13g2000cwo.googlegroups.com>
Lars Brinkhoff wrote:

>I believe you want something like this:

>    (defmacro elide-cue (cue)
>      `(defmacro ,cue (form)
>         form))

Here, I was thinking that I might need to splice in body with reader
character macros, as in (untested):

(defmacro elide-cue (cue) `progn (defmacro ,cue (&rest body) #\,··@
body))

But that doesn't look right to me.

Then I considered that I might quote it, as in (untested):

(defmacro elide-cue (cue) `progn (defmacro ,cue (&rest body) ',@body))

I haven't groked the syntax enough to know whether or not it would
work. I guess I should test it before adding noise to the discussion,
but your suggestion looks so much simpler! So simple I should have
thought of it! Thanks! I'll give it a try.
From: RPG
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132068770.287370.74710@g47g2000cwa.googlegroups.com>
A little off-topic, but when I was reading your post, I was wondering
why TICKET and TARGET-PATH --- since they have all that "if not NIL"
stuff in their description --- were made to be mandatory arguments.
Now, if this function is to be an "internal" function, one that is only
called in a specific context that is well known in advance, then this
is quite a reasonable design.  But if this function is to be called
commonly from "outside," why not make those two arguments keywords as
well?
Cheers,
R
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132075183.788196.54260@o13g2000cwo.googlegroups.com>
RPG wrote:

>A little off-topic, but when I was reading your post, I was wondering
>why TICKET and TARGET-PATH --- since they have all that "if not NIL"
>stuff in their description --- were made to be mandatory arguments.
>Now, if this function is to be an "internal" function, one that is only
>called in a specific context that is well known in advance, then this
>is quite a reasonable design.  But if this function is to be called
>commonly from "outside," why not make those two arguments keywords as
>well?

That's a perfectly valid question. The answer has to do with my own
mental model and the arbitrary ordering of the parameters.

In (defun unzip (ticket zipfile target-path &key (if-exists :error)
verbose) ...), zipfile is the only mandatory argument. Of course, I
could have defined it as (defun unzip (zipfile &key files-listed-in
to...)...), and a call would be (unzip zipfile :files-listed-in ticket
:to target-path). Do you see my personal dilemma? Such keywords would
make the body of the function less readable.

My reasoning, regarding the succinctness of the expression, does break
down (with stray keywords, as recently suggested by Mr. Bourguignon)
for (unzip :files-listed-in NIL :from zipfile :to NIL).

Of course, to make the semantics clear in the function definition, I
could go overboard with the following:

(defun unzip (zipfile &optional files-listed-in-ticket
to-target-path...)
  (let ((ticket files-listed-in-ticket)
        (target-path to-target-path))...))

A properly constructed paraphrase macro could solve the inconvenience
with the following:

(defun unzip (zipfile &optional ticket target-path &key (if-exists
:error) verbose) ...)

#| which unfortunately removes the cues from the function definition |#

(paraphrase (unzip zipfile ticket target-path...)
            :as (unzip :files-listed-in ticket :from zipfile :to
target-path...))

#| I might be satisfied with the function signature above, given a
paraphrase immediately
   following the function definition. It clarifies the meaning of the
function signature
   locally and allows me to call the function with all of the cues
remotely.

   As constructed here (i.e., local to the function definition), I like
to think of the
   paraphrase as a functional comment.
|#


I admit that I'm being anal about it. I said as much from the very
beginning. I just find that otherwise the lack of texture makes the
meaning more difficult to parse, and I'm developing a style that adds
the missing texture, for my own benefit.

- Jack
From: drewc
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <eotef.508089$oW2.8582@pd7tw1no>
Jack wrote:
> RPG wrote:
> 
> 
>>A little off-topic, but when I was reading your post, I was wondering
>>why TICKET and TARGET-PATH --- since they have all that "if not NIL"
>>stuff in their description --- were made to be mandatory arguments.
>>Now, if this function is to be an "internal" function, one that is only
>>called in a specific context that is well known in advance, then this
>>is quite a reasonable design.  But if this function is to be called
>>commonly from "outside," why not make those two arguments keywords as
>>well?
> 
> 
> That's a perfectly valid question. The answer has to do with my own
> mental model and the arbitrary ordering of the parameters.
> 
> In (defun unzip (ticket zipfile target-path &key (if-exists :error)
> verbose) ...), zipfile is the only mandatory argument. Of course, I
> could have defined it as (defun unzip (zipfile &key files-listed-in
> to...)...), and a call would be (unzip zipfile :files-listed-in ticket
> :to target-path). Do you see my personal dilemma? Such keywords would
> make the body of the function less readable.

I don't see your dilemma at all. Of all the code you've posted, "(unzip 
zipfile :files-listed-in ticket :to target-path)" is the first thing 
that i've found readable, in that i understand what the code is supposed 
to do.

With the rest of the idea's you've posted, i've spent a few minutes 
deciphering your intent, another few trying to decipher how your code 
actually performs your intent, a few minutes scratching my head, and a 
few seconds shaking my head and moving on.


> My reasoning, regarding the succinctness of the expression, does break
> down (with stray keywords, as recently suggested by Mr. Bourguignon)
> for (unzip :files-listed-in NIL :from zipfile :to NIL). 

I don't understand this one either ... why not simply (unzip :from 
zipfile) , and drop the explicit NIL, which is the default value of a 
keyword that was not provided anyway. Heck, even if your unzip is 
defined as (unzip (&rest args) ...) and you are manually getting the 
values from the plist ARGS, GETF defaults to NIL as well.


> Of course, to make the semantics clear in the function definition, I
> could go overboard with the following:
> 
> (defun unzip (zipfile &optional files-listed-in-ticket
> to-target-path...)
>   (let ((ticket files-listed-in-ticket)
>         (target-path to-target-path))...))
> 
> A properly constructed paraphrase macro could solve the inconvenience
> with the following:
> 
> (defun unzip (zipfile &optional ticket target-path &key (if-exists
> :error) verbose) ...)
> 
> #| which unfortunately removes the cues from the function definition |#
> 
> (paraphrase (unzip zipfile ticket target-path...)
>             :as (unzip :files-listed-in ticket :from zipfile :to
> target-path...))

I still don't quite get what it is you are trying to do. From what i can 
gather, you want to 'overload' the unzip function to have different 
behaviours based on the number, order, and type of arguments passed to 
it. What i don't understand is how this makes things more 'clear' and 
succinct. It is not going to make it easier to read you code (for me) if 
every time i see 'unzip', i have to guess (or, even worse, read the 
source to see) what this particular call to unzip is actually doing.

> 
> #| I might be satisfied with the function signature above, given a
> paraphrase immediately
>    following the function definition. It clarifies the meaning of the
> function signature
>    locally and allows me to call the function with all of the cues
> remotely.

But what about when i'm reading your code? i can't M-. to inspect the 
function, as any given invocation of the function may or may not refer 
to anything related to the actual function. So then, i have to decipher 
your 'paraphrase' macro, and once i know all the rules of that, figure 
out just which, if any, of your 'paraphrases' applies in the current 
situation. How is this more 'clear' than keywords!

Also, your messing with things like SLIME, which shows the function's 
signature when i type in the name. Your function has many possible 
signatures, making this tool not only useless, but in fact harmful.

>    As constructed here (i.e., local to the function definition), I like
> to think of the
>    paraphrase as a functional comment.
> |#

Well written lisp code is clear, concise, and readable. Most of the 
time, i do not need to look at the definition (or even the docs) of a 
function when reading code, as it's functionality is obvious from the 
name or context.

With your PARAPHRASE macro, this will not be the case.. You'll have me 
running around your source to find out which of the 'functional 
comments' applies to my given situation. In my opinion, it would be 
significantly more clear if you were to simply define different 
functions (with different names! cause they are different!) with the 
desired behaviour :

(unzip file ...)
(unzip-using-ticket file ticket ...)
(unzip-using-ticket-to-path file ticket path ...)

Or, even better, use keyword arguments and be done with it.

> I admit that I'm being anal about it. I said as much from the very
> beginning. I just find that otherwise the lack of texture makes the
> meaning more difficult to parse, and I'm developing a style that adds
> the missing texture, for my own benefit.

Your idea of superfluous 'cue' forms (rather than keywords, or in some 
cases , like BE in your original post, no good reason at all) reduces 
the concision of the language by adding things that don't need to be 
there. Lisp is verbose, yes, but never (rarely) unnecessarily so.

Maybe i don't fully understand what it is you are trying to do here, so 
i apologize in advance if my post is overly critical, But from what i 
can see, your style makes things harder to read, and therefore harder to 
maintain, and therefore, IMHO, is a Bad Thing (tm).

I could just be missing the 'essence' of what you are trying to do, and 
for all i know CUE and PARAPHRASE are the next CONS and LAMBDA, or it 
could be that you are making a classic LISP newbie mistake, which is to 
start designing a language, based on lisp, without understanding the 
design of LISP itself. Yes, lisp makes it really easy to change the 
language, and this is one of its most powerful features. But with great 
power comes great responsibility :).


again, sorry if i seem grumpy, but i'm only on my first cuppa here and 
it just ain't working.

drewc

> - Jack
> 


-- 
Drew Crampsie
drewc at tech dot coop
  "... the most advanced use of lisp in the field of bass lure sales"
	-- Xach on #lisp
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132112903.789528.36150@g44g2000cwa.googlegroups.com>
drewc wrote:

>I don't see your dilemma at all. Of all the code you've posted, "(unzip
>zipfile :files-listed-in ticket :to target-path)" is the first thing
>that i've found readable, in that i understand what the code is supposed
>to do.

Sure, at the call site, it almost looks pretty. ALMOST. (UNZIP
ZIPFILE...) isn't what the caller wants when the caller has specified
(unzip zipfile :files-listed-in ticket). The caller wants to (unzip
:files-listed-in ticket...) Calling it (unzip zipfile...) hides the
most significant information (psst! the ticket) after the lesser
information.

This relates to one of the many complaints I have about Java. Whether
you look in the code or the javadocs, every single non-package member
and every single non-package method lists the visibility first, the
type second and the name last. (Of course, package members drop the
visibility.) In the code, even classes start with
"(public|private|protected)* class". Which is most significant? When
I'm scanning the code or the doc for a member or a method I am not
looking for the visibility or the type; I am looking for the NAME! I'm
looking for the most significant piece of information, and they bury it
behind the secondary and terciary attributes of the object. It's
backward!

And everytime I wanted to call the UNZIP function with this arbitrary
argument order and every other function with arbitrary argument order,
I must remember the ordering. It's just another annoying map that I
need to put atop all of my other layers of knowledge in order to read
and write code. It's backward! Does the computer work for me, or do I
work for the computer?

Futhermore, the keywords named in the UNZIP example create a problem in
the readability of the function definition.

(defun unzipped (source-path &key :files-listed-in :to (if-exists
:error) verbose)
  (declare (ignorable if-exists verbose source-path files-listed-in
to))
  (when (and to (or (pathname-name to) (pathname-type to)))
    (error "The target is not a directory or lacks a trailing slash."))
  (with-zipfile (zip source-path)
		(values (list source-path to)
			(extracted-files files-listed-in zip to
					 :if-exists if-exists
					 :verbose verbose))))

It makes absolutely no sense without a lot of mental mapping. Sure, I
could rename the key arguments with a LET, but that's an unnecessary
layer one must add for each function in which one wants to give the
[human] reader semantic cues, AND it still fouls the first thing you
see when you look at the function definition: its signature.

Some people find this kind of mapping natural or accept it as a
consequence of choosing to work with computer code. I could do it. I
have done it for years. It's exasperating. It's a ridiculous way to do
things. Does the computer work for me, or do I work for the computer?

When I posted the above example, I thought that Mr. Bourguignon
intended to say that the compiler would skip "stray keywords" in all
cases, but I discovered that I had misunderstood him. It doesn't work
in function calls (even with &allow-other-keys). Now I'm back to
paraphrasing and eliding semantic cues, which you don't seem to like.

>I don't understand this one either ... why not simply (unzip :from
>zipfile) , and drop the explicit NIL, which is the default value of a
>keyword that was not provided anyway. Heck, even if your unzip is
>defined as (unzip (&rest args) ...) and you are manually getting the
>values from the plist ARGS, GETF defaults to NIL as well.

I admitted in the same post from which you quoted that the NILs run
counter to how I want my code to look. Of course, the keys default to
NIL. Again, due to a misunderstanding, I thought the compiler would
munge stray keywords, leaving only the arguments in the defined order.
I have seen code in third-party libraries with NIL arguments. It looked
funny to me when I saw it there, and it still looks funny to me when I
write it myself. I thought I could live with it, but this still isn't
set in stone. I'm working toward a practical solution to a problem. It
will evolve inevitably as I see better ways to approach the problem in
the given [Lisp] framework, which is still relatively new to me, though
I have thought about the problem for much longer.

>I still don't quite get what it is you are trying to do.

And I flubbed the paraphrase, which just made it more difficult to
understand.

>>(paraphrase (unzip zipfile ticket target-path...)
>>            :as (unzip :files-listed-in ticket :from zipfile :to
>>target-path...))

Unless I wanted to transform the source code with a mechanism other
than Lisp's macro expander, I'd need to change the function name of
either the real function or the paraphrase. Otherwise, the macro UNZIP
produced by PARAPHRASE would expand indefinitely. (I knew this before
Mr. Bourguignon mentioned it, yet I made the mistake again when I tried
to demonstrate how paraphrase would be used.) In fact, I would need to
change either unzip and have the one expand to the other.

>From what i can
>gather, you want to 'overload' the unzip function to have different
>behaviours based on the number, order, and type of arguments passed to
>it. What i don't understand is how this makes things more 'clear' and
>succinct. It is not going to make it easier to read you code (for me) if
>every time i see 'unzip', i have to guess (or, even worse, read the
>source to see) what this particular call to unzip is actually doing.

In fact, I was thinking about refactoring it. However, this one
function represents something I can control. What of all of the other
mish-mashed, messed-up ugly-looking constructs I might want to use from
third-party libraries. With a paraphrase macro to reorder arguments to
something meaningful and elided semantic cues to let me know WTF is
going on in these horrendously formulated functions, I might be able to
put a band-aid on it and avoid having to write the functionality of the
third-party library myself.

I found the Open Common Lisp Zip Library, but I'll probably rewrite
that. My project requires an XML library, and I found a few for which I
might need band-aids, because I'm not sure that I want to write an XML
parser. (I have considered the possibility of writing a parser that
only needs to handle the OpenBook document format, but I'm still
looking at my options.)

>But what about when i'm reading your code? i can't M-. to inspect the
>function, as any given invocation of the function may or may not refer
>to anything related to the actual function. So then, i have to decipher
>your 'paraphrase' macro, and once i know all the rules of that, figure
>out just which, if any, of your 'paraphrases' applies in the current
>situation. How is this more 'clear' than keywords!

Why would you ever read my code? As soon as I bootstrap the compiler of
the new language, the Lisp code is an artifact, and I won't need to
maintain it anymore. If you want to read the obsolete code, go for it,
but you won't like my style until it becomes the next best thing
anyway.

>Also, your messing with things like SLIME, which shows the function's
>signature when i type in the name. Your function has many possible
>signatures, making this tool not only useless, but in fact harmful.

Build better tools.

>Well written lisp code is clear, concise, and readable. Most of the
>time, i do not need to look at the definition (or even the docs) of a
>function when reading code, as it's functionality is obvious from the
>name or context.

One man's treasure is another man's trash.

We obviously disagree on what constitues clear, concise and readable
code. What I've seen out there is arbitrarily ordered symbols without
any semantic cues to guide the reader, which forces one to learn an
entirely new language for each and every library from each and every
author.

>With your PARAPHRASE macro, this will not be the case.. You'll have me
>running around your source to find out which of the 'functional
>comments' applies to my given situation.

Ah, but I'll be able to read it. If I can write it how I would like to
write it, I'll be able to read it when I go back to it months later,
too.

>In my opinion, it would be
>significantly more clear if you were to simply define different
>functions (with different names! cause they are different!) with the
>desired behaviour :

>(unzip file ...)
>(unzip-using-ticket file ticket ...)
>(unzip-using-ticket-to-path file ticket path ...)

Your beef isn't with just me but with the original author. The original
function had the provision for a NIL [un-keyed] target path (returning
buffers with the expanded files, if NIL). I added the ticket to the
arguments, because I know that I don't need to extract all of the files
from an OpenDoc document to process what I need from it. I defined a
NIL ticket provision for cases where I do want to unzip an entire
archive. Afterall, an OpenOffice file is just a zipfile. Why fix it
later, when it's easy enough to do correctly from the start?

I also refactored the original function to call extracted-files, which
calls a function for each case. Thus, I do have the separate functions
you described (albeit with different names), but the unzip function
performs an action common to all of them: opening the zipfile. Why
would I write the same code in three different functions?

Breaking up the function at the call site as you suggest would require
duplication of code, and it would require remembering three different
function signatures. It makes more sense to me to consolidate the
interface in this case. Is it really so difficult to understand the
semantics of NIL for each of two arguments? With functional
paraphrasing, it wouldn't be much different than calling one of three
methods with the same name.

Also, those long function names will create a lovely mess with
indentation in Emacs.

I did have a method to my madness.

> Or, even better, use keyword arguments and be done with it.

I've already explained at least one potential problem with keywords
which convey enough information for my tastes.

>Your idea of superfluous 'cue' forms (rather than keywords, or in some
>cases , like BE in your original post, no good reason at all) reduces
>the concision of the language by adding things that don't need to be
>there. Lisp is verbose, yes, but never (rarely) unnecessarily so.

These 'superfluous' cues allow me (to add) valuable information with
less #|noise|#. I thought Lispers tended to ignore parentheses.
(#|Other|# noise isn't (#|so|# easy #|to|# ignore)). These 'superflous'
cues also allow me to add this information in some places without
fouling up the message in other places.

>Maybe i don't fully understand what it is you are trying to do here.

SIGNAL:NOISE! SIGNAL/NOISE! SIGNAL to NOISE! If it still isn't clear,
I'm trying to BOOST the SIGNAL #|without|# increasing the #|NOISE|#.

> i apologize in advance if my post is overly critical

And I apologize at trying to get in a few cheap shots at you. I'm
sorry, but I can't fall in love with you. You're carrying around way
too much baggage. Can we still be friends?

>I could just be missing the 'essence' of what you are trying to do

SIGNAL:NOISE! SIG...

> for all i know CUE and PARAPHRASE are the next CONS and LAMBDA

Well... Not even close. (Wait 'til they see what I have up my sleeve...
muhahaha!)

>it could be that you are making a classic LISP newbie mistake

I don't make mistakes. *snicker*

>Yes, lisp makes it really easy to change the
>language, and this is one of its most powerful features. But with great
>power comes great responsibility

By the Power of Grayskull!...

You don't really expect me to find this awesome power and not even play
with it. Do you?

>again, sorry if i seem grumpy, but i'm only on my first cuppa here and
>it just ain't working.

I accept your apology... but PLEASE have another cup... or two.

- Jack
From: drewc
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <9_Aef.509524$oW2.377696@pd7tw1no>
Jack wrote:
> drewc wrote:
> 
> 
>>I don't see your dilemma at all. Of all the code you've posted, "(unzip
>>zipfile :files-listed-in ticket :to target-path)" is the first thing
>>that i've found readable, in that i understand what the code is supposed
>>to do.
> 
> 
> Sure, at the call site, it almost looks pretty. ALMOST. (UNZIP
> ZIPFILE...) isn't what the caller wants when the caller has specified
> (unzip zipfile :files-listed-in ticket). The caller wants to (unzip
> :files-listed-in ticket...)   Calling it (unzip zipfile...) hides the
> most significant information (psst! the ticket) after the lesser
> information.

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) ..

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?

> This relates to one of the many complaints I have about Java. Whether
> you look in the code or the javadocs, every single non-package member
> and every single non-package method lists the visibility first, the
> type second and the name last. (Of course, package members drop the
> visibility.) In the code, even classes start with
> "(public|private|protected)* class". Which is most significant? When
> I'm scanning the code or the doc for a member or a method I am not
> looking for the visibility or the type; I am looking for the NAME! I'm
> looking for the most significant piece of information, and they bury it
> behind the secondary and terciary attributes of the object. It's
> backward!

I don't see how this is related at all.

> And everytime I wanted to call the UNZIP function with this arbitrary
> argument order and every other function with arbitrary argument order,
> I must remember the ordering. It's just another annoying map that I
> need to put atop all of my other layers of knowledge in order to read
> and write code. It's backward! Does the computer work for me, or do I
> work for the computer?

Which arbitrary order? you don't have to order keywords. 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), but i certainly 
would not want to type (cons :car 'a :cdr b) , nor read it. How does 
PARAPHRASE help here?

> Futhermore, the keywords named in the UNZIP example create a problem in
> the readability of the function definition.
> 
> (defun unzipped (source-path &key :files-listed-in :to (if-exists
> :error) verbose)
>   (declare (ignorable if-exists verbose source-path files-listed-in
> to))
>   (when (and to (or (pathname-name to) (pathname-type to)))
>     (error "The target is not a directory or lacks a trailing slash."))
>   (with-zipfile (zip source-path)
> 		(values (list source-path to)
> 			(extracted-files files-listed-in zip to
> 					 :if-exists if-exists
> 					 :verbose verbose))))

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.

I have no problem reading function lambda-lists, so your "problem with 
readability" is only subjective.

> It makes absolutely no sense without a lot of mental mapping. Sure, I
> could rename the key arguments with a LET, but that's an unnecessary
> layer one must add for each function in which one wants to give the
> [human] reader semantic cues, AND it still fouls the first thing you
> see when you look at the function definition: its signature.

How does the keyword definition 'foul' the lambda list? What do you 
propose as an alternative?

The only problem i had with mapping the code above to what it should do 
was deciphering your function naming convention. 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 (if i'm 
mistaken about what those functions do, please correct me, but my point 
about it not being clear stands)... that's just odd. It's like renaming 
a MURDER function to CORPSES .. how does that convey to the reader what 
the function is doing. Functions are verbs!

> Some people find this kind of mapping natural or accept it as a
> consequence of choosing to work with computer code. I could do it. I
> have done it for years. It's exasperating. It's a ridiculous way to do
> things. Does the computer work for me, or do I work for the computer?

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.

> When I posted the above example, I thought that Mr. Bourguignon
> intended to say that the compiler would skip "stray keywords" in all
> cases, but I discovered that I had misunderstood him. It doesn't work
> in function calls (even with &allow-other-keys). Now I'm back to
> paraphrasing and eliding semantic cues, which you don't seem to like.

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.

>>From what i can 
>>gather, you want to 'overload' the unzip function to have different
>>behaviours based on the number, order, and type of arguments passed to
>>it. What i don't understand is how this makes things more 'clear' and
>>succinct. It is not going to make it easier to read you code (for me) if
>>every time i see 'unzip', i have to guess (or, even worse, read the
>>source to see) what this particular call to unzip is actually doing.
> 
> 
> In fact, I was thinking about refactoring it. However, this one
> function represents something I can control. What of all of the other
> mish-mashed, messed-up ugly-looking constructs I might want to use from
> third-party libraries. With a paraphrase macro to reorder arguments to
> something meaningful and elided semantic cues to let me know WTF is
> going on in these horrendously formulated functions, I might be able to
> put a band-aid on it and avoid having to write the functionality of the
> third-party library myself.

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? Your idea 
seem to be to create a bunch of functions with the same name that have 
different functionality ... why? how does this improve readabilitiy?

Functions can call other functions, so there is no need to write the 
functionality yourself .. you can simply wrap the exported functions in 
your own constructs as the need arises. If you really want, you can even 
SHADOW the name.

> Why would you ever read my code? As soon as I bootstrap the compiler of
> the new language, the Lisp code is an artifact, and I won't need to
> maintain it anymore. If you want to read the obsolete code, go for it,
> but you won't like my style until it becomes the next best thing
> anyway.

Ah, i see, you're one of those. I was not aware that you were creating a 
  new language here, i simply thought you were trying out common lisp. 
Common Lisp is a great environment for experimenting in language design.

> We obviously disagree on what constitues clear, concise and readable
> code. What I've seen out there is arbitrarily ordered symbols without
> any semantic cues to guide the reader, which forces one to learn an
> entirely new language for each and every library from each and every
> author.

And yet you are advocating yet-another-language of your own creation, 
which not only forces me to learn a library (which slime makes easy ... 
i shows you the name and order of the arguments as you type ... how is 
that hard?), but an entirely new language with a compiler written in 
itself that only one programmer on earth knows how to maintain!

>>With your PARAPHRASE macro, this will not be the case.. You'll have me
>>running around your source to find out which of the 'functional
>>comments' applies to my given situation.
> 
> 
> Ah, but I'll be able to read it. If I can write it how I would like to
> write it, I'll be able to read it when I go back to it months later,
> too.

Fair enough, although i wouldn't want you on my team! 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. I tend to only use two types of macros. WITH-* and DEF-*, 
and i comment very clearly when doing something hairy or tricky.


>>In my opinion, it would be
>>significantly more clear if you were to simply define different
>>functions (with different names! cause they are different!) with the
>>desired behaviour :
> 
> 
>>(unzip file ...)
>>(unzip-using-ticket file ticket ...)
>>(unzip-using-ticket-to-path file ticket path ...)
> 
> 
> Your beef isn't with just me but with the original author. The original
> function had the provision for a NIL [un-keyed] target path (returning
> buffers with the expanded files, if NIL). 

Again .. why didn't you just define your own function .. why the desire 
to change someone elses? DEFUN is a lot easier to learn than DEFMACRO, 
and both make more sense to me than PARAPHRASE.

  >I added the ticket to the
> arguments, because I know that I don't need to extract all of the files
> from an OpenDoc document to process what I need from it. 

Ah .. that's what a 'ticket' is ? a list of files? why not a new 
function EXTRACT-FILES-FROM-ARCHIVE or UNZIP-FILES?

I defined a
> NIL ticket provision for cases where I do want to unzip an entire
> archive. Afterall, an OpenOffice file is just a zipfile. Why fix it
> later, when it's easy enough to do correctly from the start?

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.

> I also refactored the original function to call extracted-files, which
> calls a function for each case. Thus, I do have the separate functions
> you described (albeit with different names), but the unzip function
> performs an action common to all of them: opening the zipfile. Why
> would I write the same code in three different functions?

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.

> Breaking up the function at the call site as you suggest would require
> duplication of code, and it would require remembering three different
> function signatures. 

But how does your macro fix that? now i only have to remember one name, 
but a possible infinite number of behaviors? 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.

> It makes more sense to me to consolidate the
> interface in this case. Is it really so difficult to understand the
> semantics of NIL for each of two arguments? 

Why should entirely different actions have the same interface? 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 :)

With functional
> paraphrasing, it wouldn't be much different than calling one of three
> methods with the same name.

So .. why not use methods? There is already a great generic function 
system in common lisp!

> Also, those long function names will create a lovely mess with
> indentation in Emacs.

You're not even trying anymore.

>>Or, even better, use keyword arguments and be done with it.
> 
> 
> I've already explained at least one potential problem with keywords
> which convey enough information for my tastes.

not really. You've pointed out that you have a problem with keywords, 
but you have not, to my satisfaction, been able to convey precisely what 
those problems are, nor have you been able to explain how your idea 
fixes them. I'm only in this thread because i'm interested in language 
design in general and always enjoy hearing new ideas.


>>Your idea of superfluous 'cue' forms (rather than keywords, or in some
>>cases , like BE in your original post, no good reason at all) reduces
>>the concision of the language by adding things that don't need to be
>>there. Lisp is verbose, yes, but never (rarely) unnecessarily so.
> 
> These 'superfluous' cues allow me (to add) valuable information with
> less #|noise|#. I thought Lispers tended to ignore parentheses.
> (#|Other|# noise isn't (#|so|# easy #|to|# ignore)). These 'superflous'
> cues also allow me to add this information in some places without
> fouling up the message in other places.

What information are you adding? I still don't understand the point of 
what you are trying to do here.

>>Maybe i don't fully understand what it is you are trying to do here.
> 
> 
> SIGNAL:NOISE! SIGNAL/NOISE! SIGNAL to NOISE! If it still isn't clear,
> I'm trying to BOOST the SIGNAL #|without|# increasing the #|NOISE|#.

Ok, you keep saying that, and you keep using the #| |# reader syntax for 
comments, and somehow that is supposed to enlighten me. I implore you to 
  boost the signal and reduce the noise in your posts.

How does allowing functions to share a name while differing in many 
other ways make comments unnecessary? if anything, you'll need more 
comments to explain what is going on. and do you have something against 
docstrings? the semicolon? Lisp code is very readable, IMO. I've read 
through many peoples code, patched many a library, and found the entire 
experience very pleasant when compared with other languages. Perhaps 
Lisp is not for you?

>>i apologize in advance if my post is overly critical
> 
> 
> And I apologize at trying to get in a few cheap shots at you.

S'ok, you missed.

> I'm
> sorry, but I can't fall in love with you. You're carrying around way
> too much baggage. Can we still be friends?

We'll see.

> 
>>I could just be missing the 'essence' of what you are trying to do
> 
> 
> SIGNAL:NOISE! SIG...

Ok, when i say 'i could be missing what you are trying to do', i am 
politely saying that your ideas seem unclear and your explainations 
incomprehensible. Yelling that mantra of yours at me is not going to 
help further my understanding of what you are trying to do.

>>it could be that you are making a classic LISP newbie mistake
>  
> I don't make mistakes. *snicker*

Ok.


> 
>>Yes, lisp makes it really easy to change the
>>language, and this is one of its most powerful features. But with great
>>power comes great responsibility
> 
> 
> By the Power of Grayskull!...

Still have most of my he-man toys somewhere. guess that dates me.

> 
> You don't really expect me to find this awesome power and not even play
> with it. Do you?

Of course not. I was under the mistaken impression that you were 
interested in learning about common lisp and how to best use it. Lisp is 
a great place to play, especially with language design. But remember 
that your ideas about what is concise and readable differ from others 
(and from what i can see from your naming conventions, _most_ others), 
so you can't just say that keywords are unreadable (or whatever) without 
backing it up in some way. We're mostly Common Lisp users here, and I 
know i'm here because i find lisp concise and readable (i _love_ 
keywords), so when presenting an alternative to the way common lisp has 
solved a problem, the burden of proof is on you.

cheers

-- 
Drew Crampsie
drewc at tech dot coop
  "... the most advanced use of lisp in the field of bass lure sales"
	-- Xach on #lisp
From: Kenny Tilton
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <kCBef.29754$u43.4073@twister.nyc.rr.com>
drewc wrote:

> Jack wrote:
> 
>> drewc wrote:

>> By the Power of Grayskull!...
> 
> 
> Still have most of my he-man toys somewhere. guess that dates me.
> 
>>
>> You don't really expect me to find this awesome power and not even play
>> with it. Do you?
> 
> 
> Of course not. I was under the mistaken impression that you were 
> interested in learning about common lisp and how to best use it. 

That is your fault. Most of us read Jack's original tome and recognized 
a nutjob when we saw it. This is so Ilias "gosh Lisp is great for my 
work, which will be to change Lisp syntax" it is not worth discussing.

Anyone with work to do is doing it.

-- 
Kenny

Why Lisp? http://wiki.alu.org/RtL_Highlight_Film

"I've wrestled with reality for 35 years, Doctor, and I'm happy to state 
I finally won out over it."
     Elwood P. Dowd, "Harvey", 1950
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132186963.280726.178270@z14g2000cwz.googlegroups.com>
Ooh, that's harsh! Whacko!

-nutjob
From: Kenny Tilton
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <C_Tef.30195$u43.27632@twister.nyc.rr.com>
Jack wrote:
> Ooh, that's harsh! 

Did you do your research and find out who Ilias was? He created the role 
you are playing.

> Whacko!

Try to imagine how a sane person would react to your response to Drew. 
You might figure out why in a few days no one any longer responds to 
you. The length itself screams "lunatic".

btw, as per Ilias we are The Savages of c.l.l., not Lisp Bullies. But 
you were close enough for me to be thinking reincarnation.

-- 
Kenny

Why Lisp? http://wiki.alu.org/RtL_Highlight_Film

"I've wrestled with reality for 35 years, Doctor, and I'm happy to state 
I finally won out over it."
     Elwood P. Dowd, "Harvey", 1950
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132273622.630465.97630@g47g2000cwa.googlegroups.com>
Mr. Tilton wrote:

> Did you do your research and find out who Ilias was? He created the role
> you are playing.

No, I didn't research Ilias, until you suggested it. Now, I see that
calling your reaction harsh is the understatement of the year. You guys
were ferrocious! To compare me to him is the biggest insult yet somehow
the greatest compliment that you could bestow upon me.

> Try to imagine how a sane person would react to your response to Drew.

Try to imagine how a sane person would react to his responses to me. I
felt as though I was speaking a foreign language, when Mr. Crampsie
clearly had a strong command of the English language.

Calculated derision seemed to be the only logical move to counter his
buffoonery.

-- Jack
From: Kenny Tilton
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <mTgff.13197$ek6.11025@news-wrt-01.rdc-nyc.rr.com>
Jack wrote:
> Mr. Tilton wrote:
> 
> 
>>Did you do your research and find out who Ilias was? He created the role
>>you are playing.
> 
> To compare me to him...

Easy: both doing no observable work yet agonizing over how to alter Lisp 
to make them more productive.

Also in common: antagonistic responses to those silly, er, kind enough 
to try to help.

Finally: if you found the "savage" quote, you may understand why I got 
such a kick out of the "Lisp bully" paranoia.

-- 
Kenny

Why Lisp? http://wiki.alu.org/RtL_Highlight_Film

"I've wrestled with reality for 35 years, Doctor, and I'm happy to state 
I finally won out over it."
     Elwood P. Dowd, "Harvey", 1950
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132186863.876848.85870@g44g2000cwa.googlegroups.com>
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. You ignored my example here, when I explained clearly why
that would foul up the function definition, so that you could fight it
to the bitter end. When you finally address the example, you ignored
the obvious, and instead complained about me not naming functions with
an imperative verb. 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?

>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
UNZIPPED from the zipfile.

If you use Linux and KDE, Konqueror gives you access to archives. In
Windows, My Computer and Explorer both do the same. Each file manager
allows you to copy individual files from an archive. Do the file
managers decompress all of the files in the archive just to copy a
single file chosen by the user? Given a large archive, that could take
much longer than necessary.

You go into a diner. The server comes to your table and writes down
your order. Does the kitchen prepare everything on the menu to give you
what you ordered? Of course not! The diner wouldn't be in business for
very long. The server gives a TICKET to someone in the kitchen, and a
cook prepares only what's listed on the ticket!

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.

Are you familiar with grep? If you want grep to search
case-insensitively, do you call with-case-insensitive-matching-grep
'foo' *? I'm glad the authors decided instead to let us specify grep -i
'foo' *!

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. 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.

>> This relates to one of the many complaints I have about Java....

> I don't see how this is related at all.

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? 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?

> 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!!!!!!!!

> 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.

> 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:

* (first (cons 'a 'b))

A
* (car (cons 'a 'b))

A
* (rest (cons 'a 'b))

B
* (cdr (cons 'a 'b))

B

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.

> 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, 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?

>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!

>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.
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.

We already have the maps, but formal languages pull the rug out from
under us.

>How does the keyword definition 'foul' the lambda list? What do you
>propose as an alternative?

OH, PUHLEAZE! Do you mean to tell me that you don't see anything weird
in the example I gave:

>(when (and to (or (pathname-name to) (pathname-type to)))
>     (error "The target is not a directory or lacks a trailing slash."))

(and to...

To what?

(or (pathname-name to...

To what?

(pathname-type to...

To what?

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.

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.

(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.

>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.

>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. IIRC car and cdr
were the NAMES of the registers, Content Address Register and Content
Decrement(?) Register. And I suppose (first bar) firsts bar and (rest
bar) rests it. Does (second baz) second it?

> (if i'm
>mistaken about what those functions do, please correct me, but my point
>about it not being clear stands)... that's just odd. It's like renaming
>a MURDER function to CORPSES .. how does that convey to the reader what
>the function is doing. Functions are verbs!

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)

(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?

>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.

>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. 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.

>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.

>Your idea
>seem to be to create a bunch of functions with the same name that have
>different functionality ... why? how does this improve readabilitiy?

It compresses information. Whether I want to unzip only the files
listed on a ticket or the entire file, I still want to UNZIP something.
If Lisp will let me say (unzip (files-listed-on ticket) (from zipfile)
(to path)) and (unzip (all-files-in zipfile)) by specifying two lines
of code instead of 12, and I can do this in any case that makes code
easier for me to comprehend, then why shouldn't I use that power.

>Ah, i see, you're one of those.

Yeah, I'm one of those [weirdos].

> 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.

If I was fluent in the languages, I could compose these c.l.l. posts in
Spanish or Latin and probably not lose any information in the
translation. Would you understand it? However, programming languages
map concepts with huge losses in information on the surface level, in
the human interface. I am working on that problem.

>i simply thought you were trying out common lisp.

Why should my motives affect the discussion.

>Common Lisp is a great environment for experimenting in language design.

Of course, it is, or I wouldn't be looking at using it.

>And yet you are advocating yet-another-language of your own creation,
>which not only forces me to learn a library

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 doubt
that paraphrasing as I defined it will become part of the standard. I
don't expect that it will start showing up in every project I see on
the internet. If it does, so what? You'll have to learn a new concept,
which is a lot easier than the scads of concepts you need to remap to
understand code in its present form.

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.

> (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, 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. 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. So I don't always use XEmacs + Slime to
read or write code.

>but an entirely new language with a compiler written in
>itself that only one programmer on earth knows how to maintain!

Lisp was new at one time. Lisp was new to you at one time. Lisp has
more than one implementation with more than one programmer who knows
how to maintain it.

Java was new at one time. Java has more than one programmer who knows
how to maintain it.

C, C++, Python, Perl, etc., were all new at one time. Some of them have
more than one implementation. Most of them have more than one
programmer on earth who knows how to maintain it.

Knowledge isn't proprietary. It grows. It spreads.

There is more than one programmer on earth.

I think I've dispelled another one of your fallacies.

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.

>Fair enough, although i wouldn't want you on my team!

I would presume that the feeling is mutual.

>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 bullshit. 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. Just because my
preferred style doesn't follow convention doesn't make this style
unreadable. 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. 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.

>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.

>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.

>.. why the desire
>to change someone elses?

Hell is other people--Sartre, I believe,

>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?

>and both make more sense to me than PARAPHRASE.

I apologize. What was I ever thinking when I decided to foist this
monstrosity onto the world? Oh, wait. I didn't. I only asked for ideas
about how to go about it.

Have you never paraphrased what someone else said in order to add
clarity to the message?

>> arguments, because I know that I don't need to extract all of the files
>> from an OpenDoc document to process what I need from it.

>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 ... 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.

>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.

>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!

>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.

>Why should entirely different actions have the same interface?

So to search for string in a directory, without regard to case, should
require

~ $ ignoring-case-grep 'foo' *

instead of

~ $ grep -i 'foo' *

If I want it to report line numbers

~ $ reporting-line-numbers-ignoring-case-grep 'foo' *

instead of

~ $ grep -in 'foo' *

If I want to search recursively

~ recursively-reporting-line-numbers-ignoring-case-grep 'foo' *

instead of

~ $ grep -inr 'foo' *

With paraphrasing and compiler-elided cues, I have a complete
expression (with semantic cues) at the function call and a lot of
compression on top of that!


>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.

>So .. why not use methods? There is already a great generic function
>system in common lisp!

I don't need methods here. The problem doesn't require run-time type
checking to dispatch the function. I have three different functions
with very similar semantics. It uses a consolidated interface and
paraphrases to hide the details.

>not really. You've pointed out that you have a problem with keywords,
>but you have not, to my satisfaction, been able to convey precisely what
>those problems are, nor have you been able to explain how your idea
>fixes them.

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.

>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?

>Ok, you keep saying that, and you keep using the #| |# reader syntax for
>comments, and somehow that is supposed to enlighten me. I implore you to
>  boost the signal and reduce the noise in your posts.

Then take off the blindfold and remove the earplugs.

>How does allowing functions to share a name while differing in many
>other ways make comments unnecessary?

McFly! Allowing function to share the same name... has nothing to do
with making comments unnecessary. The code is the comment. The function
is the same: Open a zipfile and extract one or more files. Why should I
name everything differently when the connectives can convey the
difference.

>I was under the mistaken impression that you were
>interested in learning about common lisp and how to best use it.

What would make you think otherwise? Is your way the only best way to
use it?

>But remember
>that your ideas about what is concise and readable differ from others

Must remember. Must remember. Oh, wait! That's already pretty obvious
to me.

>(and from what i can see from your naming conventions, _most_ others),

(car foo)
(rest bar)
(first last)
(second third)

> so you can't just say that keywords are unreadable

I never said any such thing. I said they don't map well for connective
use.

> without backing it up in some way.

I've backed up my bull. You've come back with fallacies, twisted logic
and whining--I don't understand; I don't understand.

>when presenting an alternative to the way common lisp has
>solved a problem...

I didn't present anything for anyone's approval. I asked questions. A
couple of people helped my understanding. You questioned my reasons for
implementing something you don't understand.

>the burden of proof is on you.

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.

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.

You want more? Bring it on!

--Jack
From: drewc
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <UjVef.515216$oW2.444136@pd7tw1no>
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 shit. 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 ;)

>>but an entirely new language with a compiler written in
>>itself that only one programmer on earth knows how to maintain!
>  
> Lisp was new at one time. Lisp was new to you at one time. Lisp has
> more than one implementation with more than one programmer who knows
> how to maintain it.
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.

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 bullshit. 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 bullshit 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
From: Thomas A. Russ
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <ymiveyrp0h2.fsf@sevak.isi.edu>
drewc <·····@rift.com> writes:

> 
> 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.

Wouldn't an easier solution be to use the existing mechanisms of Common
Lisp to provide different keywords from the variable names?

(defun move-contents (&key ((full-container :from))
                           ((empty-container :to)))
   (put-contents empty-container (find-contents full-container)))


-- 
Thomas A. Russ,  USC/Information Sciences Institute
Sometimes, you just gotta feed the troll.
From: drewc
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <gE6ff.526647$tl2.343063@pd7tw3no>
Thomas A. Russ wrote:
> drewc <·····@rift.com> writes:
> 
> 
>>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.
> 
> 
> Wouldn't an easier solution be to use the existing mechanisms of Common
> Lisp to provide different keywords from the variable names?
> 
> (defun move-contents (&key ((full-container :from))
>                            ((empty-container :to)))
>    (put-contents empty-container (find-contents full-container)))
> 
> 

man ... what a punchline!

drewc

-- 
Drew Crampsie
drewc at tech dot coop
  "... the most advanced use of lisp in the field of bass lure sales"
	-- Xach on #lisp
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132271330.209133.289780@g44g2000cwa.googlegroups.com>
>> Wouldn't an easier solution be to use the existing mechanisms of Common
>> Lisp to provide different keywords from the variable names?

>> (defun move-contents (&key ((full-container :from))
>>                            ((empty-container :to)))
>>    (put-contents empty-container (find-contents full-container)))

> man ... what a punchline!

And it is so ironic that it is backward!

Granted, the construct fits into the formal notation of the init-form,
binding the parameter variable of the first specifier to the value of
the second item of the argument pair (3.4.1.4), as in the init-forms of
a LET...

Granted, there is much debate on the usefulness or wisdom of trying to
map natural language directly to formal descriptions....

This is a special form for a special case, i.e. &key. The syntax still
confines the keyword to serve as a placeholder. Why would the
specification define a special init-form for a special case such as
&key and still treat it as a placeholder, if it is going to assign it
away in the init-form? Doing so admits that one might prefer to remap
the surface level between the call and the function definition, and the
only reason I can fathom for doing so is to use the keyword as a
functor, i.e. a connnective. Defining the keyword as a connective but
constraining the form to that of an init-form makes very little sense,
when the special form resembles a function instead of an assignment. A
connective is a function!

Furthermore, in English, Spanish... and other languages--sure, I'll
give you that it doesn't include ALL natural languages--the connective
comes before the object. It might be argued that because we tend to map
symbols to the objects to which the symbols point, with the names which
point to the actual concepts in the de facto lingua franca of
programming, i.e. English, the only logical convention is to map the
concepts more directly to the de facto lingua franca.

(function-to move-contents (&key ((:from full-container))
                                         ((:to empty-container)))
   ; where contents-of is an accessor
   (put (contents-of full-container) :into empty-container))

(funcion-para mover-contenidos (&llave ((:de contenedor-lleno))
                                         ((:a contenedor-basillo)))
   ; donde contenidos-de es un accessor
   (meter (contenidos-de contenedor-lleno) a: contenedor-basillo))

Of course, to make this work in Common Lisp, one would need to
translate function-to defun.

The order of the argument pair for &key, as specified in Common Lisp,
makes it awkward for English speakers as well as for Spanish speakers.
In Latin, it probably wouldn't matter, because in Latin the surface
form of a word changes depending on its use, and you wouldn't need the
connective keywords. Does the specification make it awkward in Chinese
or Japanese? I don't know. I just know it makes it hella crude in
languages with which I do have some knowledge.

I hope I'm not an English snob any more than you're a [Savage] Lisp
snob. It just doesn't make sense to me to specify a language in a way
that forces one to write code which requires awkward translations in
the de facto lingua franca, among others.

I'm not trying to fix complaints I have with Java... or C... or
Python... etc.--though I have even more complaints with those languages
than I do with Lisp. We're discussing Lisp. I see that I might have the
opportunity to massage Lisp into a shape that suits my whims.

-- Jack
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132271854.880593.274610@f14g2000cwb.googlegroups.com>
I wrote:

> (funcion-para mover-contenidos (&llave ((:de contenedor-lleno))
>                                          ((:a contenedor-basillo)))
>    ; donde contenidos-de es un accessor
>    (meter (contenidos-de contenedor-lleno) a: contenedor-basillo))

Correction:

Actually, FUNCION-PARA would be FUNCION-A. My hillbilly Spanish is
showing--not that it truly matters, for the purpose of this discussion.

-- Jack
From: Peter Seibel
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <m2d5kxn2x7.fsf@gigamonkeys.com>
"Jack" <············@msn.com> writes:

>>> Wouldn't an easier solution be to use the existing mechanisms of Common
>>> Lisp to provide different keywords from the variable names?
>
>>> (defun move-contents (&key ((full-container :from))
>>>                            ((empty-container :to)))
>>>    (put-contents empty-container (find-contents full-container)))
>
>> man ... what a punchline!
>
> And it is so ironic that it is backward!
>
> Granted, the construct fits into the formal notation of the init-form,
> binding the parameter variable of the first specifier to the value of
> the second item of the argument pair (3.4.1.4), as in the init-forms of
> a LET...
>
> Granted, there is much debate on the usefulness or wisdom of trying to
> map natural language directly to formal descriptions....
>
> This is a special form for a special case, i.e. &key. The syntax still
> confines the keyword to serve as a placeholder. Why would the
> specification define a special init-form for a special case such as
> &key and still treat it as a placeholder, if it is going to assign it
> away in the init-form? Doing so admits that one might prefer to remap
> the surface level between the call and the function definition, and the
> only reason I can fathom for doing so is to use the keyword as a
> functor, i.e. a connnective. Defining the keyword as a connective but
> constraining the form to that of an init-form makes very little sense,
> when the special form resembles a function instead of an assignment. A
> connective is a function!
>
> Furthermore, in English, Spanish... and other languages--sure, I'll
> give you that it doesn't include ALL natural languages--the connective
> comes before the object. It might be argued that because we tend to map
> symbols to the objects to which the symbols point, with the names which
> point to the actual concepts in the de facto lingua franca of
> programming, i.e. English, the only logical convention is to map the
> concepts more directly to the de facto lingua franca.
>
> (function-to move-contents (&key ((:from full-container))
>                                          ((:to empty-container)))
>    ; where contents-of is an accessor
>    (put (contents-of full-container) :into empty-container))
>
> (funcion-para mover-contenidos (&llave ((:de contenedor-lleno))
>                                          ((:a contenedor-basillo)))
>    ; donde contenidos-de es un accessor
>    (meter (contenidos-de contenedor-lleno) a: contenedor-basillo))
>
> Of course, to make this work in Common Lisp, one would need to
> translate function-to defun.

You mean like this:

  (defun move-contents (&key ((:from full-container)) ((:to empty-container)))
    (format t "Moving from ~a to ~a~%" full-container empty-container))

  CL-USER> (move-contents :from 'a :to 'b)
  Moving from A to B
  NIL

I'm still missing what your problem with keyword parameters is; they
seem to do exactly what you want.

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132351697.972809.177670@f14g2000cwb.googlegroups.com>
> You mean like this:

>  (defun move-contents (&key ((:from full-container)) ((:to empty-container)))
>    (format t "Moving from ~a to ~a~%" full-container empty-container))

>  CL-USER> (move-contents :from 'a :to 'b)
>  Moving from A to B
>  NIL

PETER! MY SAVIOR! THANK YOU!

If I had known it was that SIMPLE, I wouldn't be trying to change
it!!!!!

These Lisp Meanies have been messing with my mind all this time!

> I'm still missing what your problem with keyword parameters is; they
> seem to do exactly what you want.

I checked the HyperSpec. I even referenced it. The language of
(3.4.1.4) is so dense--or I AM--that it never occurred to me to try it
the other way. And Mr. Russ wrote the punchline backward just to mess
with my head.

AY CARAMBA! For the last four hours I've been playing with LOOP, in an
effort to swap the keyword init-form pair, in order to translate it in
a macro... in order to produce something that Mr. Tilton might call
work, to show that I'm serious about my endeavor to use Lisp if it will
allow me to express descriptions in a clear manner... and all this time
these Savages have been toying with me!

Well, I guess the joke's on me. Sheesh!

Thanks again for enlightening me.

--Jack
From: Brian Downing
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <cTKff.343867$084.138891@attbi_s22>
In article <························@f14g2000cwb.googlegroups.com>,
Jack <············@msn.com> wrote:
> I checked the HyperSpec. I even referenced it. The language of
> (3.4.1.4) is so dense--or I AM--that it never occurred to me to try it
> the other way.

What, you mean:

| Thus 
|    (defun foo (&key radix (type 'integer)) ...)
| means exactly the same as 
|    (defun foo (&key ((:radix radix)) ((:type type) 'integer)) ...)

    - <http://www.lisp.org/HyperSpec/Body/sec_3-4-1-4.html>

That seems pretty straightforward.  :-)

-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132438195.187925.209010@g47g2000cwa.googlegroups.com>
Mr. Downing offered:

>What, you mean:

>| Thus
>|    (defun foo (&key radix (type 'integer)) ...)
>| means exactly the same as
>|    (defun foo (&key ((:radix radix)) ((:type type) 'integer)) ...)

>    - <http://www.lisp.org/HyperSpec/Body/sec_3-4-1-4.html>

>That seems pretty straightforward.  :-)

I admit my confusion. The example given in the Hyperspec is redundant,
and it doesn't address giving the variable a name which is distinct
from the keyword parameter specifier. Given the punchline, for which I
didn't see the joke immediately, even given Mr. Crampsie's hint, I
ignored the redundant example and tried to interpret the text of
3.4.1.4 given Mr. Russ's example, assuming his example was valid.

Had I referred to the section on keywords in Chapter 5 of Mr. Seibel's
"Practical Common Lisp", I might have experienced less confusion.
However, that text again treats both the keyword and variable as mere
placeholders, naming the apple to a, the box to b and charlie to c, and
it does nothing to shine light on the different possible abstractions.
The example shows us that we can use keywords to shorten references to
variables. An alternative example would more clearly show that we can
(move-contents :from full-container :to empty-container) or
(move-contents :to empty-container :from full-container), and that's
the most valuable abstraction that the keyword mechanism allows.

Regardless of whether the Lisp reader treats it as such, semantically
the keyword is not a placeholder. Even the symbol &key and the
arbitrary ordering of keys should make it abundantly clear that &keys
[especially when specified by a pair in the function definition] cue
both the Lisp reader and the human reader to the position and function
of the argument. Why do all of the texts seem to want to treat it
otherwise?

Perhaps, I would have had less difficulty with the concepts had I tried
to learn them at an hour other than one o'clock in the morning. It's
not necessarily a good time to read the Hyperspec without first sipping
on a strong cup of coffee.

Now, in light of the evidence, I admit that Hyperspec does seem more
straightforward.

- Jack
From: Brian Downing
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <2kRff.344966$084.223911@attbi_s22>
In article <························@g47g2000cwa.googlegroups.com>,
Jack <············@msn.com> wrote:
> Had I referred to the section on keywords in Chapter 5 of Mr. Seibel's
> "Practical Common Lisp", I might have experienced less confusion.
> However, that text again treats both the keyword and variable as mere
> placeholders, naming the apple to a, the box to b and charlie to c, and
> it does nothing to shine light on the different possible abstractions.
> The example shows us that we can use keywords to shorten references to
> variables. An alternative example would more clearly show that we can
> (move-contents :from full-container :to empty-container) or
> (move-contents :to empty-container :from full-container), and that's
> the most valuable abstraction that the keyword mechanism allows.
> 
> Regardless of whether the Lisp reader treats it as such, semantically
> the keyword is not a placeholder. Even the symbol &key and the
> arbitrary ordering of keys should make it abundantly clear that &keys
> [especially when specified by a pair in the function definition] cue
> both the Lisp reader and the human reader to the position and function
> of the argument. Why do all of the texts seem to want to treat it
> otherwise?

I admit I'm still not sure what you're getting at here, but again, the
first example in the keyword section in Practical Common Lisp is:

(defun foo (&key a b c) (list a b c))

(foo)                ==> (NIL NIL NIL)
(foo :a 1)           ==> (1 NIL NIL)
(foo :b 1)           ==> (NIL 1 NIL)
(foo :c 1)           ==> (NIL NIL 1)
(foo :a 1 :c 3)      ==> (1 NIL 3)
(foo :a 1 :b 2 :c 3) ==> (1 2 3)
(foo :a 1 :c 3 :b 2) ==> (1 2 3)

IMHO, the keyword mechanism provides two abstrations:

1. Arguments are position-independent.
2. Arguments need not be present, and may be present in any combination.

The example above demonstrates both.  I'm not sure how a proposed
(move-contents (&key from to)) example would help more than that.

And of course the keyword is not "just" a placeholder.  Otherwise &key
would be totally redundant and we would just write:

(defun foo (&optional junk-a a junk-b b junk-c c)
  (declare (ignore junk-a junk-b junk-c))
  (list a b c))

I don't understand where you are going with your linguistic experiments,
but I'm happy that CL's keyword mechanism seems to get you further than
you expected.

(To complete your knowledge of the &key feature, you should look at how
&key interacts with &rest, how &key interacts with &optional [hint -
badly!], and the &allow-other-keys and :allow-other-keys t features.)

Good luck,
-bcd
-- 
*** Brian Downing <bdowning at lavos dot net> 
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132467039.980250.84940@z14g2000cwz.googlegroups.com>
Mr. Downing commented:

> I admit I'm still not sure what you're getting at here, but again, the
> first example in the keyword section in Practical Common Lisp is:

> (defun foo (&key a b c) (list a b c))

> (foo)                ==> (NIL NIL NIL)
> (foo :a 1)           ==> (1 NIL NIL)
> (foo :b 1)           ==> (NIL 1 NIL)
> (foo :c 1)           ==> (NIL NIL 1)
> (foo :a 1 :c 3)      ==> (1 NIL 3)
> (foo :a 1 :b 2 :c 3) ==> (1 2 3)
> (foo :a 1 :c 3 :b 2) ==> (1 2 3)

> IMHO, the keyword mechanism provides two abstrations:

> 1. Arguments are position-independent.
> 2. Arguments need not be present, and may be present in any combination.

> The example above demonstrates both.

Yes, I can see that it demonstrates both abstractions. It suffices for
demonstration purposes only if you want to make programming all about
symbols and algorithms, but it completely ignores the level of
human-computer interface. The use of the symbol foo (bar, baz, barf)
takes us even further from the target, because these kinds of symbols
have absolutely no meaning. Granted, it makes it clear that the example
demonstrates the abstraction--that a symbol can name any function--but
it fails to connect the abstraction to anything more concrete.

> I'm not sure how a proposed
> (move-contents (&key from to)) example would help more than that.

As written, this example wouldn't take us any further, because it still
treats everything as a symbol, as shown in the form (put from to) in
the following:

(defun move-contents (&key from to)
  (put (contents from) to))

Here, again, the example treats the prepositions from and to as mere
placeholders. Whereas the it clarifies the meanings of the parameters
in the defun better than (defun move-contents (&key foo bar)) AND
allows us to complete the thought more clearly in the function call
with (move-contents :from waste-basket :to garbage-can), it makes the
language in the definition very awkward.

Let's complete the thought with the following:

(defun move-contents (&key ((from source)) ((to destination)))
  (put (contents-of source) :into destination))

(move-contents :from shovel :to sandbox)

The code documents itself! It doesn't even require a docstring.
Furthermore, it doesn't require the reader to mentally map symbols foo,
bar and baz (or any other symbols) to the objects to which the symbols
refer and to the concepts that those symbols represent. Anyone who
understands English can understand the abstractions. Now, a small
effort by the author translates into huge savings in mental CPU cycles
for potentially many readers. Whereas "Practical Common Lisp" is
absolutely brilliant in other areas, for someone writing an
introductory textbook to make the abstractions so vague misses the
mark. Neglecting to demonstrate multiple uses of a single construct
misses a great opportunity to demonstrate the expressiveness of Lisp.

The example you gave from PCL shows the abstraction. The example from
the HyperSpec only expanded the short form to the long form of the
short form. The example I gave from Chapter 5 shows the possibility to
use keywords to remap parameters to other symbols in order to
abbreviate them in the function subforms. If I had reviewed Chapter 5
before I started this thread I may have not needed to ask the question,
because I probably would have mapped the one abstraction to the other,
but the first read just didn't reveal the potential expressiveness of
keywords. I did research the question from my original post in this
thread using many different sources, but they all left the question
unanswered, because I didn't happen to look in the right place.

Now that I'm aware of the details, I don't need to wonder in this case
how to shape Lisp in order to write code that documents itself and
doesn't create a burden for myself when I need to review code possibly
days, weeks or months after I originally composed it. It also offers
more possibilities for paraphrasing code from third-party libraries, so
that I don't compromise the readability of my code due to short-sighted
decisions to abbreviate everything.

> And of course the keyword is not "just" a placeholder.

Of course it isn't just a placeholder, but a majority of the examples
I've seen in a variety of sources treat them as mere placeholders.
Until I reviewed chapter 5, I didn't see any examples that demonstrated
remapping from the keyword symbol to a different symbol. (I have read
several Lisp textbooks, but I completely forgot about the usage.)

> Otherwise &key
> would be totally redundant and we would just write:

> (defun foo (&optional junk-a a junk-b b junk-c c)
>   (declare (ignore junk-a junk-b junk-c))
>  (list a b c))

I don't quite understand this hypothetical example. First of all, if
you're going to ignore the junk, why wouldn't you write (defun foo
(&optional a b c junk-a junk-b junk-c))? Defining it as you did would
require all three junk parameters in every call only interested in the
results of f(a), f(a,b) or f(a,b,c). The omission of any individual
junk parameter precludes the use of any parameter preceding it in the
order given by the definition. Granted, you're example is contrived,
but it fails to demonstrate to me any principle related to the
usefulness of keywords.

Regardless, I do understand that the position-independence and the
possibility for omission make keywords much more useful than just
placeholders. However, my point was that the demonstration of
associating a parameter keyword with an analogous symbol or the same
symbol minus the leading colon fails to elucidate for the reader more
powerful abstractions, such as using the keyword as a connective token.

> I don't understand where you are going with your linguistic experiments,

It is somewhat experimental, now that you mention it. I'm just looking
for more efficient maps which leverage pre-existing knowledge, i.e.,
outside of the domain of mathematics.

> but I'm happy that CL's keyword mechanism seems to get you further than
> you expected.

I am quite relieved, too.

> (To complete your knowledge of the &key feature, you should look at how
> &key interacts with &rest, how &key interacts with &optional [hint -
> badly!], and the &allow-other-keys and :allow-other-keys t features.)

I have cursory knowlege about possible feature interactions, but I
agree that I should explore it further. Thanks for the reminder.

-- Jack
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132468412.925984.154440@g14g2000cwa.googlegroups.com>
I wrote:

> The omission of any individual
> junk parameter precludes the use of any parameter preceding it in the
> order given by the definition. Granted, you're example is contrived,
> but it fails to demonstrate to me any principle related to the
> usefulness of keywords.

Correction: The omission of any individual junk parameter precludes the
use of any parameter which the _individual_junk_parameter_precedes_ in
the function definition... _beyond_position-independence_, it fails to
demonstrate to me any princle related to the usefulness of keywords.

I apologize for my sloppiness.

-- Jack
From: Adrian Kubala
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <slrndo4f2t.fn8.adrian-news@sixfingeredman.net>
On 2005-11-20, Jack <············@msn.com> wrote:
> (defun move-contents (&key ((from source)) ((to destination)))
>   (put (contents-of source) :into destination))
>
> (move-contents :from shovel :to sandbox)

What about (move-contents :out-of sandbox :into bucket)? Or (put
(contents-of source) :inside destination)? The reason English-like
syntax is generally bad is that, while it's easy to read, it adds extra
arbitrary information for writers to follow. The easy answer is to
use positional conventions. set functions take location, then value.
move functions take source, then destination.
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132617630.438447.173610@g47g2000cwa.googlegroups.com>
Mr Kubala countered:

> What about (move-contents :out-of sandbox :into bucket)? Or (put
> (contents-of source) :inside destination)?

How does showing different ways of saying something detract from the
usefulness of expressing a statement as a complete thoughts instead of
as an arbitrarily designed, often awkward form? If the latter proved
more efficient, contemporary spoken language might as well move toward
dropping all connective grammatical constructs (which contain much
functional information).

Given a library with a function signature (storage:move-contents :from
source :to destination), if (move-contents :out-of sandbox :into
bucket) conveys more information or otherwise feels more natural to
you, by all means, paraphrase it with (paraphrase move-contents (&key
((:out-of source)) ((:into destination))) (storage:move-contents :from
source :to destination)). (If you prefer, by all means, use a defun. A
paraphrase macro would more clearly show that the one signature offers
an alternate convention for another signature.)

By the way, (move-contents :out-of sandbox :into bucket) fails to fit
the semantics of move-contents, as previously used in this discussion,
in that it fails where the (contents-of sandbox) don't fit into bucket.
The semantics don't match. The concept might be expressed better with
(fill bucket :from sandbox).


> The reason English-like
> syntax is generally bad is that, while it's easy to read, it adds extra
> arbitrary information for writers to follow.

And arbitrarily-defined ordering of arguments doesn't? It does exactly
the same thing. However, upon happening in third-party code onto
(move-contents foo bar), one must search for the definition of
move-contents to determine whether (move-contents foo bar) follows the
convention (move source destination) or (move destination source).
(Does the author follow AT&T assembly syntax or Intel assembly syntax?)
The reader must also then remember which convention the author followed
for this function and any other function. For example, was the author
consistent?

For the purpose of opining that "English-like syntax is generally bad",
you embellished the simplest English expression of moving the contents
from a source container to a destination container, with an adverb and
a different preposition, resulting in an expression which doesn't
convey clearly the from-source-to-destination pattern. We could convey
the same information with (move-contents-of container :to destination)
or (move-contents :of container :to destination), and these also break
the from-source-to-destination pattern. These expressions are all
complete. If the user prefers one form over the other, the user can
simply define a paraphrase. The paraphrase would convey as much
information at the surface level.

> The easy answer is to
> use positional conventions.

The easy answer? How does it make it easy, and for whom does it make it
easy? The reader must remember the convention for each case, because
each expression doesn't contain adequate information. The writer almost
always will spend more time and effort reading the code than writing
it, so the writer is by definition also a reader.

> set functions take location, then value.
> move functions take source, then destination.

Two cases. Two patterns. Does everything fit into just these two
patterns? How many other patterns occur? Does the pattern always
present itself without more complete information? Is it not much
simpler to define everything more completely?

-- Jack
From: Adrian Kubala
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <slrndo4uv4.h8d.adrian-news@sixfingeredman.net>
On 2005-11-22, Jack <············@msn.com> wrote:
> Mr Kubala countered:
>> The reason English-like syntax is generally bad is that, while it's
>> easy to read, it adds extra arbitrary information for writers to
>> follow.
>
> And arbitrarily-defined ordering of arguments doesn't?

Depending on a number of factors of course, it's usually easier to
remember that one thing comes before another than to remember which of
ten different synonyms are used for each of two arguments. Do you have
any trouble remembering to say "apples are good" instead of "good apples
are"?

> It does exactly the same thing. However, upon happening in third-party
> code onto (move-contents foo bar), one must search for the definition
> of move-contents to determine whether (move-contents foo bar) follows
> the convention (move source destination) or (move destination source).

There is no substitute for thoughtful design. In this case the right
answer would be: (setf (contents destination) (contents source)). It's
extremely rare that one cannot play upon existing conventions and
patterns, and if one can't, it's no simpler to remember that the
keywords are :from and :to than to remember that the destination comes
first.

> If the user prefers one form over the other, the user can simply
> define a paraphrase. The paraphrase would convey as much information
> at the surface level.

Surely it's not controversial that there should be only ONE way to call
a given function? Anything else is a maintenance nightmare.

> Does everything fit into just these two patterns? How many other
> patterns occur? Does the pattern always present itself without more
> complete information? Is it not much simpler to define everything more
> completely?

Keywords do not obviate the need for patterns; for example, is the
convention :from :to, or :source :destination? Indeed, good naming
conventions are much harder to pin down than good argument-order
conventions, to the point that programming is very little more than the
art of choosing good names for things.
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132639197.217223.102100@g47g2000cwa.googlegroups.com>
> Depending on a number of factors of course, it's usually easier to
> remember that one thing comes before another than to remember which of
> ten different synonyms are used for each of two arguments.

In fact, it is easier to remember that _*ONE*_ thing comes before
another. How so for 100 sequences? 200 sequences? How much easier would
it be to remember that the preposition from denotes a source and that
the preposition to denotes a destination. Is it easier to remember 200
patterns or to simplify those 200 patterns with a much smaller set of
connective keywords which convey information?

Which choice creates a larger burden? Acknowledging as a truism that
code is read much more often than it is written, in reading some code
which uses one or more unfamiliar libraries with potentially many
unfamiliar functions, would it be easier for the reader where the code
expresses the process with keywords that identify the functions of
parameters [without redundancy]?

> Do you have
> any trouble remembering to say "apples are good" instead of "good apples
> are"?

Of course, I remember that the word apples is a plural noun, the word
are is a verb, the word good is an adjective and that to connect an
adjective to a noun using the verb are in a complete sentence has the
defined order NOUN VERB ADJECTIVE. This simple pattern has so many
practical uses, too. Conversely, you're offering as an example a
grammar with a relatively small set of sequences for simple expressions
to support the claim that remembering how to use a potentially very
large set of sequences is easier to remember than the use of a
comparatively small set of patterns identified by the use of a
relatively small set of prepositions and other key phrases.

> There is no substitute for thoughtful design. In this case the right
> answer would be: (setf (contents destination) (contents source)).

This argument fails when the definition of move-contents differs from
the definition of (setf (contents container) new-contents). Moving one
thing to another involves taking it from the source and putting it into
the destination. Does (setf (contents container) new-contents) modify
the owner of new-contents? If it does, many would argue that the
different semantics call for a different function.

> It's
> extremely rare that one cannot play upon existing conventions and
> patterns, and if one can't, it's no simpler to remember that the
> keywords are :from and :to than to remember that the destination comes
> first.

That assumes that for whatever reason the author hasn't justifiably
reversed the order for a specific case. In which case, one needs to
remember a new order for a special case without any cues to help one
remember which order applies to the specific case, other than the name
of the function.

> Surely it's not controversial that there should be only ONE way to call
> a given function?

Then why have &optional or &key at all?

Surely it's not controversial that a word might have more than one
meaning (function or value). Likewise, it's not any more controversial
that two words might have the same meaning.

> Anything else is a maintenance nightmare.

Anything else allows one to express a description in familiar language
which suits both the description of the problem and the author's
pre-existing maps, instead of restricting one to express the problem
with an inadequate subset of tokens which don't adequately express the
description without assuming knowledge not expressed in the description
as described with the limited subset of tokens.

> Keywords do not obviate the need for patterns;

I never claimed that they did.

> for example, is the
> convention :from :to, or :source :destination?

The former compresses information. The latter redundantly names the
parameters, instead of documenting them. For example:

(let ((full-container ...)
      (empty-container...))
  (move-contents :source full-container :destination empty-container))

The expression requires a translation of the actual meaning (from
expression to concepts, from code to documentation...), for both the
writer and the reader.

(move-contents :from full-container :to empty-container)

It requires no translation from the literal meaning of the expression
to the functional meaning, and it compresses the information without
losing any of the information that one needs to determine the full
meaning of the expression.

Whereas (move-contents shovel bucket) doesn't identify the source and
the destination without reference to the definition of the function,
(move-contents :from shovel :to bucket) contains all of the
informatinon one needs to comprehend the meaning of the expression.

> Indeed, good naming
> conventions are much harder to pin down than good argument-order
> conventions, to the point that programming is very little more than the
> art of choosing good names for things.

Whereas a good naming convention does help, finding names for
everything doesn't address all of the issues that I have identified.

Whereas I understand your position, I disagree with it. If I happen
upon your code and want to use it, I'll (paraphrase
my-function-signature-containing-all-the-information-I-need-at-a-glance
:to
your-function-signature-forcing-me-to-refer-to-its-definition-for-its-semantics).
If you want to (defun my-stubborn-attempt-to-understand-my-own-code ()
your-prerogative-to-memorize-everything-in-order-to-apply-it), I won't
stop you.

-- Jack
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132263148.111470.237900@g14g2000cwa.googlegroups.com>
drewc wrote:

>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...

If I'm not mistaken, you initiated the game. You admitted that you were
egging me on. Before your latest post, you pretended that I spoke a
foreign language. I responded with my own brand of derisive
facetiousness. I meant no foul, and I won't apologize, given the
circumstances.

I appreciate your latest post.You intelligently explored the problem
space and presented some nice visuals that let me see the shape of
possible solutions to it. Whereas it still seems as though you want to
twist the problem into Lisp, where I would instead prefer to massage
Lisp to my whim, I have started to understand the solution on your
terms. Thank you for the enlightening perspective.

How could I lose any credibility, when from the beginning I had none to
lose?

I'm off to play with symbols, to see how they can work for me...

- Jack
From: drewc
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <yvtef.508147$oW2.245730@pd7tw1no>
drewc wrote:

> With the rest of the idea's you've posted, 

THWAAP! that should be 'ideas'. i suck.

drewc


i've spent a few minutes
> deciphering your intent, another few trying to decipher how your code 
> actually performs your intent, a few minutes scratching my head, and a 
> few seconds shaking my head and moving on.
> 
> 
>> My reasoning, regarding the succinctness of the expression, does break
>> down (with stray keywords, as recently suggested by Mr. Bourguignon)
>> for (unzip :files-listed-in NIL :from zipfile :to NIL). 
> 
> 
> I don't understand this one either ... why not simply (unzip :from 
> zipfile) , and drop the explicit NIL, which is the default value of a 
> keyword that was not provided anyway. Heck, even if your unzip is 
> defined as (unzip (&rest args) ...) and you are manually getting the 
> values from the plist ARGS, GETF defaults to NIL as well.
> 
> 
>> Of course, to make the semantics clear in the function definition, I
>> could go overboard with the following:
>>
>> (defun unzip (zipfile &optional files-listed-in-ticket
>> to-target-path...)
>>   (let ((ticket files-listed-in-ticket)
>>         (target-path to-target-path))...))
>>
>> A properly constructed paraphrase macro could solve the inconvenience
>> with the following:
>>
>> (defun unzip (zipfile &optional ticket target-path &key (if-exists
>> :error) verbose) ...)
>>
>> #| which unfortunately removes the cues from the function definition |#
>>
>> (paraphrase (unzip zipfile ticket target-path...)
>>             :as (unzip :files-listed-in ticket :from zipfile :to
>> target-path...))
> 
> 
> I still don't quite get what it is you are trying to do. From what i can 
> gather, you want to 'overload' the unzip function to have different 
> behaviours based on the number, order, and type of arguments passed to 
> it. What i don't understand is how this makes things more 'clear' and 
> succinct. It is not going to make it easier to read you code (for me) if 
> every time i see 'unzip', i have to guess (or, even worse, read the 
> source to see) what this particular call to unzip is actually doing.
> 
>>
>> #| I might be satisfied with the function signature above, given a
>> paraphrase immediately
>>    following the function definition. It clarifies the meaning of the
>> function signature
>>    locally and allows me to call the function with all of the cues
>> remotely.
> 
> 
> But what about when i'm reading your code? i can't M-. to inspect the 
> function, as any given invocation of the function may or may not refer 
> to anything related to the actual function. So then, i have to decipher 
> your 'paraphrase' macro, and once i know all the rules of that, figure 
> out just which, if any, of your 'paraphrases' applies in the current 
> situation. How is this more 'clear' than keywords!
> 
> Also, your messing with things like SLIME, which shows the function's 
> signature when i type in the name. Your function has many possible 
> signatures, making this tool not only useless, but in fact harmful.
> 
>>    As constructed here (i.e., local to the function definition), I like
>> to think of the
>>    paraphrase as a functional comment.
>> |#
> 
> 
> Well written lisp code is clear, concise, and readable. Most of the 
> time, i do not need to look at the definition (or even the docs) of a 
> function when reading code, as it's functionality is obvious from the 
> name or context.
> 
> With your PARAPHRASE macro, this will not be the case.. You'll have me 
> running around your source to find out which of the 'functional 
> comments' applies to my given situation. In my opinion, it would be 
> significantly more clear if you were to simply define different 
> functions (with different names! cause they are different!) with the 
> desired behaviour :
> 
> (unzip file ...)
> (unzip-using-ticket file ticket ...)
> (unzip-using-ticket-to-path file ticket path ...)
> 
> Or, even better, use keyword arguments and be done with it.
> 
>> I admit that I'm being anal about it. I said as much from the very
>> beginning. I just find that otherwise the lack of texture makes the
>> meaning more difficult to parse, and I'm developing a style that adds
>> the missing texture, for my own benefit.
> 
> 
> Your idea of superfluous 'cue' forms (rather than keywords, or in some 
> cases , like BE in your original post, no good reason at all) reduces 
> the concision of the language by adding things that don't need to be 
> there. Lisp is verbose, yes, but never (rarely) unnecessarily so.
> 
> Maybe i don't fully understand what it is you are trying to do here, so 
> i apologize in advance if my post is overly critical, But from what i 
> can see, your style makes things harder to read, and therefore harder to 
> maintain, and therefore, IMHO, is a Bad Thing (tm).
> 
> I could just be missing the 'essence' of what you are trying to do, and 
> for all i know CUE and PARAPHRASE are the next CONS and LAMBDA, or it 
> could be that you are making a classic LISP newbie mistake, which is to 
> start designing a language, based on lisp, without understanding the 
> design of LISP itself. Yes, lisp makes it really easy to change the 
> language, and this is one of its most powerful features. But with great 
> power comes great responsibility :).
> 
> 
> again, sorry if i seem grumpy, but i'm only on my first cuppa here and 
> it just ain't working.
> 
> drewc
> 
>> - Jack
>>
> 
> 


-- 
Drew Crampsie
drewc at tech dot coop
  "... the most advanced use of lisp in the field of bass lure sales"
	-- Xach on #lisp
From: Jack
Subject: Re: Macro Question: Paraphrasing
Date: 
Message-ID: <1132113197.952641.252700@g47g2000cwa.googlegroups.com>
Earlier in this thread, I actually wrote "trash been" instead of "trash
bin". *snicker*

I can't believe I didn't catch that one on the proofread.... Trash
been.... How stupid am I?