Re: Seeking computer-programming job (Sunnyvale, CA)

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

Pascal J. Bourguignon

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.

I can't wait when Haskell and type inference will be discussed here :)
 
P

Pascal J. Bourguignon

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.

I'll try a last time. You've been explained that the macro can and
will generate unique name, that in no way may be collided. This is
absolutely impossible.


And now for the "personal insult":

Go learn Common Lisp! Or even Scheme with its hygienic macros, you
might like them better than Common Lisp macros.
 
P

Paul Foley

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.

You're talking nonsense. Lisp macros /are/ functions!

A macro is just a function of one argument (actually two, but we can
ignore the second). When you call (macro arg1 arg2 ...), the form
'(macro arg1 arg2 ...) becomes the argument to the function, and
whatever the function returns gets evaluated/compiled in place of the
macro form. The only difference between a "macro" and an ordinary
"function" is that macro-functions get executed at compile time.
 
P

Pascal J. Bourguignon

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

gugamilare

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.

I agree, the mini-buffer is the best. It does not take your attention
from what you are doing like "balloons", but it still provides the
information anyway.
 
P

Pascal J. Bourguignon

Series Expansion said:
They weren't commonplace, aside from the clunky old black-and-white
Macs.

And the Lisa, and Amiga, and the Apollo, Xerox Alto, Lisp Machines,
Xerox Star, Three Rivers PERQ workstations.

You mean, more productive. GUIs provide a lot of productivity
benefits:

No, they're much less productive.
* 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.

In reality this is wrong. Notably in the case of pictures you find in
GUIs.

* 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

Here you are explaining that GUI are good for people with poor
vocabulary. There are even some people who think that watching
pictures all day long (eg on TV) dumbs the watchers down.
Well, it's not me who said it...

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

Yes. But then you can says:

disconnect when no work done in 15 minutes
or at 18:00
or when downloading porn.

Try to say such a thing by clicking on icons.

And once you can say textual commands, you can easily put them in
script, in programs. Try to do the same with GUI!

And once you've found a system to do it with GUI (there exist some),
compare the speed and expressiveness of the GUI and CLI scripting.

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

CLI and text based interfaces can do the same.

* Web access. The web is largely unusable with lynx nowadays.

There are other text based browser.
The web usability question is not relative to the text or CLI aspects,
but on the support for things such as Flash or Javascript.
* 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.

Who talked of ASCII terminals?

Did you even watch the URI I gave showing how lisp REPL may output
both graphics and texts?

[...] Users want to write code, fix the red-eye in
their photos, or whatever, [...]

This user doesn't want to write code, fix the red-eye in my photo, or
whatever. I want the computer to do that for me, so I can go to the
beach.

* A window system also supports *user* multitasking.

No, it's the operating system that supports multi-tasking.

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.

Well after using GUIs for a few years, I came back to more textual
user interfaces, because I lose less time with them.

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.

If you want feed back you can always order it.

But I don't see what's disconcerting in having the computer execute
the orders you give it...


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.

In any case, I don't spend my time watching clocks counting down.
When I give a command that will take time to complete, I order the
computer to do it in background and go on with the rest of my tasks.

This is problematical. Writing program code is a largely un-
automatable task,

We've spent the last two days explaining you how you automate writting
code with lisp macros. You still don't get it.

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!

It's more efficient if you let the computer generate the GUI code,
from commands.

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.

Metafor Interactive Natural Language Programming
http://www.lehigh.edu/~amsp/2005/03/metafor-natural-language-programming.html
http://web.media.mit.edu/~hugo/demos/metafor-bartender-simple.mov
http://web.media.mit.edu/~hugo/publications/
http://web.media.mit.edu/~hugo/publications/papers/IUI2005-metafor.pdf

Notice how it's a text based user inteface!


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.

Good for them, they copied the feature from emacs.

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.

We're not always editing lisp code...
 
P

Pascal J. Bourguignon

Series Expansion said:
Another hand-wave. Macros are macros are macros.

Dogs are dogs are dogs. How loud does your hot-dog bark?


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.

Lisp macros are functions, not symbols. Symbols are only used to name
lisp macros.

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.

You may want to write a macro such as:

(print-and-return (incf x))

that should print the value returned, without evaluating the
expression twice. (An artificial example, since the function PRINT
already does that). Then you'd write it:

(defmacro print-and-return (expression)
(let ((value-name (gensym)))
`(let ((,value-name ,expression)) ; evaluates expression once
(print ,value-name) ; prints its value
,value-name))) ; and returns it.


On the other hand, you may want to write a macro such as:

(repeat-thrice (incf x))

that should evaluate the expression three times. Then you'd write:

(defmacro repeat-thrice (expression)
`(progn
,expression
,expression
,expression))

so expression will be evaluted three times.


If you want to do something, then do it. If you don't want it, then
just don't do it. That's what we call not being dumb.


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.

If you want to capture a variable, then you can.
If you want to capture a variable specified as parameter, then you can.
If you want to define variables that are not accessible to the subexpressions, then you can.
If you want to define variables that are accessible to the subexpressions, then you can.
If you want to define variables specified as parameter that are accessible to the subexpressions, then you can.
If you want to define variables specified as parameter that are accessible to the subexpressions but protected from any interference, then you can.
If you want to avoid capturing any variable (see print-and-return above), then you can.
If you want to have side effects, then you can.
If you want to be side-effect free, then you can.

Why would you do something that you wouldn't want? Are you dumb?


Capture a variable:

(defmacro capturing-x (y) `(- (* 157 x x) ,y))
(let ((x 42)) (capturing-x 239))
--> 276709


Capture a variable specified as parameter:

(defmacro capture (var y) `(- (* 157 ,var ,var) ,y))
(let ((x 42) (y 1))
(list (capture x 239) (capture y 42)))
--> (276709 115)


Define variables that are not accessible to the subexpressions:

(defmacro repeat-using-inaccessible-variable (n expression)
(let ((inaccessible-variable (gensym)))
`(dotimes (,inaccessible-variable ,n) ,expression)))
(repeat-using-inaccessible-variable 3
(print "whatever you do here you can't get access to the counter"))
prints:
"whatever you do here you can't get access to the counter"
"whatever you do here you can't get access to the counter"
"whatever you do here you can't get access to the counter"


Define variables that are accessible to the subexpressions:

(defmacro repeat-using-accessible-variable-named-counter (n expression)
`(dotimes (counter ,n) ,expression))
(repeat-using-accessible-variable-named-counter 4
(format t "The value of COUNTER in the ~A~:*~[th~;st~;nd~;rd~;th~] iteration is ~A~%"
(1+ counter) counter))
prints:
The value of COUNTER in the 1st iteration is 0
The value of COUNTER in the 2nd iteration is 1
The value of COUNTER in the 3rd iteration is 2
The value of COUNTER in the 4th iteration is 3


Define variables specified as parameter that are accessible to the subexpressions:

(defmacro repeat-with-counter ((counter n) expression)
`(dotimes (,counter ,n) ,expression))
(repeat-with-counter (my-counter 4)
(format t "The value of ~A in the ~A~:*~[th~;st~;nd~;rd~;th~] iteration is ~A~%"
'my-counter (1+ my-counter) my-counter))
prints:
The value of MY-COUNTER in the 1st iteration is 0
The value of MY-COUNTER in the 2nd iteration is 1
The value of MY-COUNTER in the 3rd iteration is 2
The value of MY-COUNTER in the 4th iteration is 3


Define variables specified as parameter that are accessible to the
subexpressions but protected from any interference:

(defmacro repeat-with-protected-counter ((counter n) expression)
`(dotimes (,counter ,n) (let ((,counter ,counter)) ,expression)))
(repeat-with-protected-counter (my-counter 4)
(progn
(format t "The value of ~A in the ~A~:*~[th~;st~;nd~;rd~;th~] iteration is ~A~%"
'my-counter (1+ my-counter) my-counter)
(setf my-counter 0)))
prints:
The value of MY-COUNTER in the 1st iteration is 0
The value of MY-COUNTER in the 2nd iteration is 1
The value of MY-COUNTER in the 3rd iteration is 2
The value of MY-COUNTER in the 4th iteration is 3


Avoid capturing any variable:

(defmacro print-and-return (expression)
(let ((value-name (gensym)))
`(let ((,value-name ,expression)) ; evaluates expression once
(print ,value-name) ; prints its value
,value-name))) ; and returns it.
(let ((x 0) (value-name 'toto))
(print-and-return (incf x))
(print value-name))
prints:
1
TOTO


Have side effects:

(defmacro define-typed-function (name arguments &body body)
`(defun ,name ,(mapcar (function first) arguments)
(declare ,@(mapcar (lambda (var-type)
(destructuring-bind (var type) var-type
`(type ,type ,var))) arguments))
,@body))

(define-typed-function fact ((n integer))
(if (<= n 0)
1
(* n (fact (1- n)))))
--> FACT

(macroexpand-1 '(define-typed-function fact ((n integer))
(if (<= n 0)
1
(* n (fact (1- n))))))
--> (DEFUN FACT (N) (DECLARE (TYPE INTEGER N)) (IF (<= N 0) 1 (* N (FACT (1- N))))) ;
T

(fact 20)
--> 2432902008176640000


Not have side effects:

(defmacro print-and-return (expression)
(let ((value-name (gensym)))
`(let ((,value-name ,expression)) ; evaluates expression once
(print ,value-name) ; prints its value
,value-name))) ; and returns it.
(let ((x 0) (value-name 'toto))
(print-and-return (incf x))
(print value-name))
prints:
1
TOTO


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.

Yes. So why would you do that if that's not what you want to do?

And all of the above is extrapolated from the definition of "macro"
without reference to any particular language, implementation, or
anything.

Oh! How dumb! We were discussing Lisp macros... Dog, Hot-Dog?

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.

Ok.
Assembler macros where invented in the 1950's.
Lisp macros were invented in the early 1960's.
C macros where invented in the 1970's.

All the above can be done as well in good macro assemblers, this has
already been mentionned in this thread.

We have priority on the terminology here.
 
S

Series Expansion

This is not denial.  It's damage control.  We wouldn't want to let
innocent nearby readers believe your lies.

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

Frank GOENNINGER

Kenneth Tilton said:
Damn. I was looking forward to that, sounded kinda kinky.

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.
Damn. I suppose now I have to start answering your questions about
Cello.

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

As you know I am fond of pictures and diagrams. So I am currently making
up a series of slides showing the coordinate geometry's major elements
and their effects to the different kinds of controls / widgets.

I have working the event handling, mouse tracking, and Togl of course. I
have stripped down the former Cello classes to about half the amount in
Cello NX (so far, not counting the various controls).

The one thing I am still working on is to make up a good picture
explanining the concept of an Outset... As soon as I have this done I'd
like you to review it and then we go for a very streamlined
implementation...

Thanks in advance!

Cheers
Frank
 
L

Lew

Paul said:
Series Expansion said:
[...]
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.
Except that macros lack the natural encapsulation barrier that
surrounds functions, as explained elsethread. With all the
consequences for debugging straightforwardness that that implies.

You're talking nonsense. Lisp macros /are/ functions!

Please don't feed the troll.
 
L

Lew

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.

Trolls. I recommend not feeding them.
 
L

Lew

While this answer tells us that "Series" *will* read the book, I suspect he
won't keep his word.
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.

"Series" is a troll. He doesn't want to learn anything. He just wants to
pepper you with foul-mouthed trash while claiming that you're the one getting
personal.

I got personal with him explicitly and he didn't scold me for it, I notice.
What, don't I deserve a four-letter word?

Of course, I wasn't defending Lisp, either.

I'm going to read the FREE (including shipping and tax) book.

Then I'm going to continue not using Lisp.
 
L

Lew

Series said:
That's it. Flame on, fuckwad.

Potty mouth. Potty mouth. Even if you are describing yourself.
I am not a liar, and I resent you publicly badmouthing me by calling

You are, too, a liar. Liar, liar, pants on fire, "Series".
me one. Your behavior is reprehensible and you appear to be an
asshole. Good day, sir.

You don't just appear to be one, you genuinely are one. And a hypocrite and a
liar, too, Series.
Damn. I'm way out of practice being genuinely rude. :)

Hah, good one. Every word out of your keyboard has been genuinely rude, you liar.

You're a liar, Series Expansion.
 
L

Lew

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

Ahh, he's a troll and a maroon. He also doesn't know the meaning of the word
"law"; he confused scientific law with legislative.
 

Ask a Question

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.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,436
Messages
2,571,696
Members
48,796
Latest member
Greg L.
Top