P
Pascal J. Bourguignon
Series Expansion said:Why should I? It's a useful job skill.
Because we're talking about lisp macros and they have nothing in common with C macros.
Series Expansion said:Why should I? It's a useful job skill.
Series Expansion said:Come off it. You're grafting on something the compiler and language
weren't originally designed for, so it's going to necessarily suck
compared to the real deal.
Series Expansion said:For example, the variable-capture thing. Making a local scope within a
macro will avoid it, except that the scope inside the macro will
shadow same-name variables in the enclosing scope (the call-site) and
if the macro evaluates an argument in that nested scope, and that
argument is an expression that uses the same-name variable, poof! This
is an unavoidable consequence of how scope nesting works, combined
with how macros work, and is physically unavoidable on anything that
even has the concepts of local variables and a call stack and that
also has macros.
Series Expansion said:Except that macros lack the natural encapsulation barrier that
surrounds functions, as explained elsethread. With all the
consequences for debugging straightforwardness that that implies.
Series Expansion said:It's a text editor. A text editor won't know Lisp source from Java
source, or either from a letter to Grandma.
gugamilare said:It could. Instead of opening a new balloon or a message, it could only
divide the screen and show the help on half of it. It can also provide
a sequence of keys (Control-X plus right or left arrow) that works
like changing the window. It is certainly not fancy or beautiful, but
it works pretty well, I assure you.
But emacs can also show "balloons": (tooltip-show "Hello world"). But
I don't like when it does, I prefer it to use the mini-buffer or split
a new window.
Series Expansion said:They weren't commonplace, aside from the clunky old black-and-white
Macs.
You mean, more productive. GUIs provide a lot of productivity
benefits:
* Increased screen real-estate for text. Instead of a smallish rigid
rectangular grid of ASCII characters you can have quite a large
grid, and you can use a proportional font and ditch the grid
constraint.
Text.
* Ability to display much larger character sets, foreign characters
for instance. The best pre-graphics systems could display sometimes
several of the European languages, though only one at a time, by
supporting a choice of code pages. GUIs can display the whole of
Unicode, including the very large character sets used in
far-Eastern languages, and mix them all seamlessly (modulo
reading-order differences).
Text.
* A picture is worth a thousand words. GUIs can display symbols like
a dangling plug instead of taking up much more space with the
slower-to-comprehend word "disconnected", allowing more compact and
informative status areas.
* The same thing lets GUIs put a dangling plug symbol onto a
push-button to clearly and concisely do all of these at once:
- tell you you can disconnect
- tell you one way of doing so
- provide that way of doing so
In a terminal you're stuck putting the first item in a status line
at the bottom (say, the word "connected"), the second buried in a
long help file somewhere out of immediate view, and the third bound
to some probably unguessable hotkey without browsing the help
(screen-oriented) or by typing "disconnect" and enter at some
prompt (line-oriented). The latter can still be subject to
usability problems:
- guess-the-verb, if there are several synonyms; a common culprit
is when exactly one of "quit" and "exit" works, or worse,
neither, and different ones don't work in different apps, with
none working in all
- it takes eleven input actions to type "disconnect" and hit enter
versus two, a flick of the mouse and a click, to hit a button.
For frequently-used commands the difference adds up rapidly.
* Flexibility of workflow. The user can open and arrange various
windows to suit, move data around via copy and paste, and the like.
A terminal constrains the user to using a linear sequence of
applications, and of screens within an application, and working out
some cumbersome system of scratch files to move data around.
Copy/paste doesn't work across applications and only one screen of
one application can be used at a time.
* Web access. The web is largely unusable with lynx nowadays.
* A GUI can place your current actions and work in context in various
ways. For example, a file list can be accompanied by a directory
tree, and the image files in formats your file manager recognizes
can be displayed as thumbnails, so you can find images by what you
remember them looking like and not just by what you remember their
filenames to be. Every additional way to view or find things helps,
and a lot of ways are inherently incompatible with displaying in an
ASCII terminal.
[...] Users want to write code, fix the red-eye in
their photos, or whatever, [...]
* A window system also supports *user* multitasking.
If point-by-point arguments bore you, here's the nutshell,
metaphorical version too: after using a GUI, using anything more
primitive feels like flying a plane with no instruments, a keyhole-
sized cockpit window to peer out of, and a control stick you have to
talk to rather than simply pull, push, and turn with your hands.
It can be quite disconcerting to tell a CLI to move some files and
just have the prompt reappear: did it even do anything? Even more so
to tell it to move some files and have it appear to hang.
Versus seeing the files appear one by one in the destination folder,
and if it's taking long enough, a clock counting down the estimated
time remaining until the job's done. And being easily able to do
something else (except if it involves those files) in the meantime.
This is problematical. Writing program code is a largely un-
automatable task,
aside from generating parser skeletons from grammars
and GUI code from forms. We have bison for the former, and if you're
generating GUI code you're generally doing it from an actual GUI!
So your dream of being able to just type "write the implementation of
the Foo.bar() method for me" and enter at a prompt and get useful code
out if it is not likely to be fulfilled anytime soon.
Many major GUI applications provide equivalent capabilities. In Word
for example you can write VBScript to do something novel to a document
and then give it an icon and add it to your toolbar, or bind it to a
control-shift-foo type hotkey, or both. NetBeans has a templating
language for customizing its code generation, and is open source, so
you can hack NetBeans itself if hacking in the templating language
won't suffice. New templates appear in appropriate places in the
menus. Eclipse is even more modular and reprogrammable, using Java and
SWT. It can even be turned into a non-IDE tool such as a word
processor.
If the Lisp code you're editing can be generated automatically,
shouldn't you be using a Lisp macro instead of having your editor
churn it out? Then you can just change the macro later instead of
every spot where the editor did whatever it did.
Your arguments in favor of a command-driven editor instead of a normal
one appear to contradict your arguments in favor of Lisp macros. I'm
afraid you'll have to pick exactly one of those to continue to
support, or else lose credibility in both debates.
Series Expansion said:Another hand-wave. Macros are macros are macros.
Macros are a symbol, possibly with formal parameters, that is expanded
where it is called in the code, with the formal parameters in turn
expanded into copies of the actual parameters.
It immediately follows that an actual parameter with side effects may
end up having those side effects multiple times, and that certain
other problems can arise. It also follows that the macro's internals
can be rewritten, without altering the semantics it would have if the
arguments were side-effect free, and yet cause changes in the
program's semantics if some call site uses an argument with side
effects.
Furthermore, the variable capture problems follow automatically as
well. If the macro assigns to a variable in the outermost scope in its
body, it will clobber the value of any variable of the same name
existing at the call site, since when the macro is expanded in place
at that site, the variable name in the macro becomes a reference to
that other variable. Likewise, if the macro contains a structure in
its body that creates a smaller local scope and defines a variable in
that, when expanded at the call site that becomes a nested local scope
at the call site, and the variable will hide any variable of the same
name existing in the scope enclosing the call. If the macro uses a
formal parameter inside that nested scope, and the call site uses that
variable in the corresponding actual parameter, the expansion will use
the macro's local variable instead of the one the coder intended it to
use, because the latter is hidden by the former.
This again causes an encapsulation failure: merely changing the names
of variables internally used in the macro, without altering anything
else, may cause it to behave very differently at some call sites.
And all of the above is extrapolated from the definition of "macro"
without reference to any particular language, implementation, or
anything.
The only way for the above not to happen is for the "macro"
involved to violate in some manner the generic, language-independent
definition of a macro, i.e. for it not to be a macro at all but rather
something else, such as a plain-Jane function call.
This is not denial. It's damage control. We wouldn't want to let
innocent nearby readers believe your lies.
Kenneth Tilton said:Damn. I was looking forward to that, sounded kinda kinky.
Damn. I suppose now I have to start answering your questions about
Cello.
Did you grok the coordinate geometry yet? One guy working for me
characterized it as a system only Kenny could
understand. Unfortunately he was gone before I discovered the prior
example of a little thing called OpenGL.
kt
Pascal said:I can't wait when Haskell and type inference will be discussed here![]()
Pillsy said:How the heck can you "explain" something you quite clearly know
nothing about?
Paul said:Series Expansion said:Except that macros lack the natural encapsulation barrier that[...]
It's strange to be told, repeatedly, that things I do routinely,
without a great deal of difficulty or aggravation, are in fact
ridiculously hard and painful.
Real debugging or some sort of cargo-cult debugging, going through the
motions and having faith that it will have the intended effect?
Real debugging. Lisp macros are a good deal less arcane than you seem
to think; the ones you write 95% of the time are really just
straightforward Lisp functions that act on a tree made up of conses.
surrounds functions, as explained elsethread. With all the
consequences for debugging straightforwardness that that implies.
You're talking nonsense. Lisp macros /are/ functions!
Pascal said:Lisp language designers don't think lisp programmers are dumb.
Frank said:Well, I was looking for the right tone in my response and came up short
and dry. This sounded about right and appropriate to the unbelievable
arrogance of Seamus and of Series Idiocy, ah, Series Expansion.
Dude, it's been said 5 or 6 times already --
a) it's free
b) we've pointed you to a specific chapter to look at
c) it's right here -- the ENTIRE BOOK FOR FREE.
<http://www.gigamonkeys.com/book/>
If you just don't want to learn about Lisp, just say so. However, at
that point, we'll probably start ignoring you, rather than trying to
show you where you can fill in gaps in your knowledge.
gugamilare said:You already saw them. The only thing is that you don't understand them
because you don't understand Lisp.
Series said:That's it. Flame on, fuckwad.
I am not a liar, and I resent you publicly badmouthing me by calling
me one. Your behavior is reprehensible and you appear to be an
asshole. Good day, sir.
Damn. I'm way out of practice being genuinely rude.![]()
Adlai said:I'm pretty sure that our dear Mr Expansion is unaware of the
differences between
- Martin Luther
- Martin Luther King, Sr.
- Martin Luther King, Jr.
Series, go read about some history before you go read about Lisp,
ok?![]()
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.