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

L

Lew


A couple of things about that site scare me, though still plan to look into
the product.

They claim that the product "interfaces Emacs to command-line Java development
tools (for example, JavaSoft's JDK)". JavaSoft hasn't been around in quite a
while, since well before a major change in the JVM's debugger interface.

"... JDEbug, the JDEE's debugger." The JVM includes a debugger interface.
Why do they need a separate one?

"Year 2000 Compliance" - aren't they a little late to the party on that one?

"make file support" - no one uses make files with Java.

"Sun's Java 2 Software Development Kit (SDK)" "... JDK 1.2 or higher ..." -
How old is this product? All of Sun's "Java 2" SDKs are obsolete. The last
version of Java 2 ceased being supported by Sun over two and a half years ago.
There's nary a mention of Java 5 (itself obsolescent) or higher on the JDEE
site.

"Copyright © 1997-2004 Paul Kinnucan" - OK, that seems to answer the "how old"
question. I'm a bit nervous that work on JDEE apparently stopped at around
the time Java 5 came out.

I suspect that JDEE might still work despite these areas of concern. Suspect,
but hardly dare hope.
 
P

Pascal J. Bourguignon

Lew said:
A couple of things about that site scare me, though still plan to look
into the product.

They claim that the product "interfaces Emacs to command-line Java
development tools (for example, JavaSoft's JDK)". JavaSoft hasn't
been around in quite a while, since well before a major change in the
JVM's debugger interface.

"... JDEbug, the JDEE's debugger." The JVM includes a debugger
interface. Why do they need a separate one?

Well do you want to work from emacs or from the JVM?
"Year 2000 Compliance" - aren't they a little late to the party on that one?

Not at all. You can't imagine the number of programmers (and users)
who are back writting years with only two digits. You know, the kind
that give you a rendez-vous on 10/08/09.
"make file support" - no one uses make files with Java.

Well, if you're using emacs, perhaps you don't like ant either...

"Sun's Java 2 Software Development Kit (SDK)" "... JDK 1.2 or higher ..." -
How old is this product?

Which begs the question, have you really searched for an emacs java IDE ever?
 
L

Lew

Series said:
I'm sure Ted Bundy's mother was proud of him, even for a while after
everyone else started telling her he was a bad seed.

Man, Series, you really are a troll, aren't you?
Don't have it and can't be arsed to blow $40 on something I'll
probably never use, sorry.

Luckily they already provided a link upthread whereby you can read it for free.
<http://www.gigamonkeys.com/book/>

Of course, acknowledging that they gave you a free link would reduce your
opportunities for trollism, wouldn't it?

Dollars to doughnuts you won't be "arsed", as you so charmingly put it, to
read it for free, either. Not that I'm any great fan of Lisp myself, but I'm
really not a fan of your behavior, Series. I think the Lisp proponents make a
fair point with the suggestion that you argue from knowledge rather than
ignorance and a nasty attitude. Now let's see if you are man enough to rise
to that challenge.
 
L

Lew

This is not Lisp vs. Java debate. We are not attacking Java at all,
because we are not the trolls here. This is more a "Java programmers
that don't understand and never programmed in Lisp before rudely,
pointlessly and with very weak arguments attacking Lisp" debate. Give

"Series" does not represent the typical Java programmer.
You Javaers are the ones
treating us like if we are a bunch of amateurs who don't know how to
program.

Now that is a very unfair generalization. Don't tar Java programmers with the
"Series Expansion" brush. I'm a Java programmer myself, but that doesn't mean
I agree with or endorse his behavior.

In fact, I don't. I assess that "Series" is a brat.

From time to time even entirely within the comp.lang.java.programmer
newsgroup we get posts from people who profess to be Java programmers but only
use the forum to exercise their nasty little egos. Does that never happen
entirely within the comp.lang.lisp group? Is everyone who posts their fair
and balanced?

Clearly, "Series Expansion" is not.
 
L

Lew

Man, your text editor must be a dinosaur! How can you program in Java with
that obsolete piece of crap?

My text editors, including emacs, BTW, are capable of handling far more than
ASCII characters. Given that Java requires more than ASCII to work, that's a
necessity.
I don't tend to comply with requests that are asked of me as rudely as
that.

No surprise there. You didn't comply with requests that were phrased
politely, either.
Another personal attack, this time accusing me of lacking integrity
and intellectual honesty?

You do lack those attributes. You are utterly devoid of integrity or
intellectual honesty.
I quoted and responded to it right there, you dipshit!

What a potty-mouth response from someone who got up on the high horse of "no
personal attacks". The name you called is the thing you are, "Series Expansion".
Please read up on etiquette, polite society, civilization, and Emily
Post before you continue posting personal attacks!

What a hypocrite thou art. How dare you call others to account for behaviors
you exceed for nastiness and unworthiness? Fie on you, "Series". Fie! Thou
blackguard, thou poltroon. Thou infamous blot on the name of humanity, and
programmers in particular. Fie!

You wouldn't know etiquette or polite society if it bit you, "Series
Expansion", and I am certain you've never read Emily Post yourself, you worm.
You are completely unqualified to speak of civilization, you vomitous slime.
Now go away, or I shall taunt you a second time.

What a maroon.
 
L

Lew

gugamilare said:
You won't see me in comp.lang.java unless I learn Java.

Actually, your posts are showing up over "here" in comp.lang.java.programmer.
And I certainly won't troll over there like you are trolling over
here, if anything I will complain of some little things I don't like
about Java.

"Series Expansion" is a worthless troll. Ignore him. He's not in any way
representative of the universe of Java programmers. He's just a nasty little man.
 
L

Lew

Well do you want to work from emacs or from the JVM?

I expect emacs to work with the JVM, or it is of no use for Java programming.
Just like I used to use emacs with C and C++ - if it didn't work with the
compiler and the run-time environment (in that case, the OS), it wouldn't have
been much use.

Perhaps I don't understand what you're driving at here. You certainly didn't
answer my question with the one you asked in response.

Lew:
Not at all. You can't imagine the number of programmers (and users)
who are back writting years with only two digits. You know, the kind
that give you a rendez-vous [sic] on 10/08/09.

But now you are speaking of "Year 2100 compliance", aren't you? The reference
Well, if you're using emacs, perhaps you don't like ant either...

I don't follow the logic on that at all. Generally, emacs users are
command-line proponents, don't you find that so? Back in my C/C++ days, emacs
and make were like peanut butter and jelly - I couldn't make a PB&J without
both. Now I'd be thrilled to find that emacs plays well with ant. I just
can't see how you'd draw the conclusion you express here.

Regardless, you seem to have missed my point altogether, which is that
everything about the JDEE site screams ancient history, which gives me concern
about its utility in a modern environment. Yes, including ant, of course, duh.

Lew:
Which begs the question, have you really searched for an emacs java [sic]
IDE ever?

It does not beg the question at all. Begging the question is the logical
fallacy of assuming a conclusion as part of the argument in favor of that
conclusion.
<http://en.wikipedia.org/wiki/Begging_the_question>

If you are asking if I have searched for an emacs Java environment, the answer
is yes, including by asking in this very forum.

If you are willing to help in that search, I am grateful. If not, well,
that's your privilege.
 
G

gugamilare

"Series" does not represent the typical Java programmer.

That is why I should have said "some" Java programmers.
Now that is a very unfair generalization.  Don't tar Java programmers with the
"Series Expansion" brush.  I'm a Java programmer myself, but that doesn't mean
I agree with or endorse his behavior.

Sorry, I didn't mean to generalize, I know that are people of every
kind and everywhere that can have actual conversations, and I bet that
most people who hang out at comp.lang.java doesn't agree with what
Series Expansion and others are doing (or trying to do) here. When I
said "Javaers" I should have said "attackers of the Lisp language".
 
S

Stefan Ram

Paul Donnelly said:
Why in the world? The chances are very good that your compiler will
transform "tt+tt" into "(+ tt tt)" before generating machine code.

I used »(+ tt tt)« not to refer the representation as an AST,
but to the arbitrary-precision semantics.
 
K

Kenneth Tilton

Frank said:
PUWAHAHAHAHA - Puwaaahahhhahaaahahaaa - Good grief, man, you're talking
to Kenny Tilton.

Damn. I was looking forward to that, sounded kinda kinky.
You are so sweet in your childish innocence.


Well, man, I can tell you, he is one of the Lisp Gods, really. Because
he is one of those who are able to help and support others in doing them
good and in doing them bad. (That's a *hint* for you !)

If he says something then you should *listen* - er, read.

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
 
P

Paul Donnelly

Series Expansion said:
On May 15, 4:07 pm, (e-mail address removed) (Thomas A. Russ) wrote:

The year is now 2009. The seeds planted by Martin Luther's speech took
root decades ago, and we now have an honest-to-god black President
sitting in the Oval Office.

Considering his opinions on Jews, I'm surprised he liked blacks much
better (if he was even aware of them).
Adding methods might be a problem then, if the generic function you
need to edit is in library code you don't control.

Then it's a good thing it's not necessary to edit any generic functions
to add methods, isn't it? That would indeed be a problem, if it were
ever necessary.
What? Surely not -- surely it blithely compiles your code, then your
program chokes on some sort of "message not understood" run-time
exception.

But that would be terrible! Please stay out of language design. I'd feel
uncomfortable even using a library written by someone who thought that
behaviour was reasonable.
I'm more concerned with being able to create objects that work with
generic functions created by others.

Be concerned no longer. What would stop you from doing that?
You wouldn't think so, to hear the howlers some of them have written
about Java here lately. I think one even insinuated that it wasn't
even Turing-complete?

Oh, will you come off it? Do you intentionally adopt the most patently
absurd interpretation of every statement? I'm sure that person (Kenny?)
never believed such a thing, and I have no idea why you think they did.
But nobody can deny that there's a big difference between catching 100
bugs after hours of bug-hunting, dozens of debugging prints, and lots
of poring over stack traces and watched-variable logs, and catching 50
bugs that way and 50 instantly when you click "build" (or even when
you write the separate buggy lines of code!).

One could deny that 50% of all bugs are stealthy type errors, but since
we already did static typing these last few weeks, I won't get involved.
 
P

Paul Donnelly

Series Expansion said:

It bears saying again that you don't have the faintest idea how Lisp
macros work.
The problem is that "the code which uses them" includes any code that
contains the text that triggers the macro and that occurs after the
macro in evaluation by the compiler.

It bears saying again that you don't have the faintest idea how Lisp
macros work.
I've written lots of macros, though, in a variety of places and
contexts.

It bears saying again that you don't have the faintest idea how Lisp
macros work. They don't work like C macros, and they don't work like you
think they do. May I suggest reading chapter 8 of "Practical Common
Lisp"? Here's a link to it:

http://gigamonkeys.com/book/macros-defining-your-own.html
Don't have it and can't be arsed to blow $40 on something I'll
probably never use, sorry.

It's free online. Do you see the link?
 
G

gugamilare

  I used »(+ tt tt)« not to refer the representation as an AST,
  but to the arbitrary-precision semantics.

You can specify it not to have arbitrary-precision if you want to (as
Paul Donnelly already stated) and Lisp programmers will do that when
they need speed. But there are places where this is a premature and
useless optimization that will make you restrict your code.
Well, ok, you can argue that there are up and down sides from both
sides, and I agree when it comes to number arithmetics. I won't agree
with you that this is the case with other kind of data manipulation,
specially generic functions and methods.
 
G

gugamilare

It bears saying again that you don't have the faintest idea how Lisp
macros work.



It bears saying again that you don't have the faintest idea how Lisp
macros work.
I am starting to think that what he fails to see is that Lisp has a
uniform interface (someone already said that, but he probably didn't
pay much attention). And he probably thinks that the compiler will
look for texts that look like macro and expand them. So there is no
place where something else can be mistaken with a macro call.

Just trying to make things clear now, lispers don't need to read it
because they already know all of what I am explaining here. Lisp code
is a bunch of nested lists - that is why Lisp has so much parenthesis
(I won't be mad if anyone say this is not very good, I respect
everyone's opinion, but I PERSONALLY prefer code filled with
parenthesis then code filled with a non-uniform syntax like C or
Java). When we type

(+ 1 (* 2 3))

this is text that actually represents a tree. There is the outer list
whose elements are the symbol +, the number 1 and another inner list.
The inner list is composed by the symbol * and the numbers 2 and 3.
The compiler and all macros work based one that tree. Assuming that m
is a macro, when you write

(m (+ 1 (* 2 3)))

the compiler will parse the outer list and see that it is composed by
two elements: the symbol m and a inner list. Then the compiler will
think "oh, the symbol m names a macro." (ok, not exactly think, but
you get the point, right?). The compiler will call that macro the
exact way that it would call a function, but, instead of evaluating
the list (+ 1 (* 2 3)) to the value 7 and call the macro with the
value 7, it will call the macro with the list itself, without
evaluating it. It is just a list, a well known and very simple data
structure that even a beginner in programming with a minimal knowledge
of data structures know how to manipulate. And what does the macro
return? Another list, to be evaluated instead of the expression (+ 1
(* 2 3)).

For instance, if the job of the macro m was to print the values
returned by the expressions returned by 1 and (* 2 3) before return
the value of the entire expression, it would probably be expanded into
something like this:

(let ((#:g1 1)
(#:g2 (* 2 3)))
(print #:g1)
(print #:g2)
(+ #:g1 #:g2))

Don't worry about scope or collisions, the symbols #:g1 and #:g2 are
what we call gensyms, they are auto-generated symbols that can't
collide with your own symbols, even if you explicitly call, for
instance:

(m (+ #:g1 #:g2))

This is because they are what we call uninterned symbols - the only
way to reference an already existing uninterned symbol is to have its
value already inside some variable and get the value of that variable.
But this is another subject I will not get into now, just take my word
when I say that this works. And the new variables #:g1 and #:g2 only
exist during the execution of the code - once the code has finished
running (that code implicitly bounded inside the macro call), they are
either garbage collected or stack deallocated or something in that
sense.

The sequence of characters "(+ 1 (* 2 3))" were previously read and
transformed into a list long before the macro was called. Yes, BEFORE,
not during nor after. The entire form is read and parsed into lists,
and only then the macros found are expanded. Only after the macros did
their job the compiler finally takes the resulting form (guess what?
another bunch of nested lists) and compiles it, produced the well
known machine code or byte code that I am sure everyone here is
familiar with and I don't need to get into details.
 
S

Series Expansion

It's not clear to me what you mean by tight coupling or how
it would make it harder to find bugs.

Then you're not qualified to give practical advice about software
development until you've learned more about these things.
So in NetBeans you can specify a multi-line region of code where
perhaps the first or last lines of the code you want to change
do not occupy the whole line and then replace it with something
else ?

In any modern text editor one should be able to do that much. But
gugamilare seemed to be thinking that it's really laborious to make
the same change to the same string in 100 different places. With
reasonably modern tools, that is not the case.
As others have pointed out it's not clear here what gugamilare
meant. Perhaps he meant that you expand the macro , see why it
doesn't work at that specific place in the code , modify the
macro code and then restore the macro call at the place in the
code where you did the expansion.

That's more or less what he said, yes, though the obvious expectation
of an experienced developer is that sooner or later, the final "undo"
step WILL get forgotten by someone, somewhere.
But once again the exact same scenario can happen if you only
use functions. Say you use foo() in 50 different places in your
code but on testing you find that it doesn't achieve the desired
result in one place. So you eliminate the call to foo() at that
particular spot and replace it with something else. Obviously
if later on you change the foo() code it won't affect that
particular place.

Or better, generalize foo() with a new parameter that parametrizes the
way in which the uses differ.
So why is it more dangerous with macros?

Everything's more dangerous with macros.
And as I pointed out above the exact same thing can happen with
functions.

Except that nobody does in-editor inlining of function calls. Not even
as an optimization, these days.

You don't have to, because if the function does the wrong thing the
error's in the function and the function's easy to locate, and if it
doesn't, nothing wacky will be happening. In particular, the
evaluation of the function's arguments is not dependent on the
implementation of the function.

With a macro, on the other hand, expressions in the arguments may end
up evaluated zero or more times in any sequence rather than once each
in left to right order, and changes in the macro's implementation may
change this. If some of the arguments at a particular call site are
expressions with side-effects, the semantics of that code will
sensitively depend on the details of the macro's innards. Furthermore
the macro might be capturing local variables or otherwise interacting
with its environment in ways that functions never do. If a local
variable name happens to clash with a name used internally by the
macro, kaboom! And then you have to do the kludgy expand-in-place
thing to find out what's going wrong, and if you leave it like that,
you've fixed one kaboom but you've got another ticking bomb in exactly
the same spot.

Consider local-variable capture.

Functions: safe, because the function's own local variables are a
separate scope.
Closures: safe; though the closure can alter variables in a larger
scope, the closure's code is lexically contained in that
larger scope, and any unintended interactions are easy to
spot and fix. If the same closure may be evaluated at
many locations, it still can't muck with those locations'
local variables.
Macros: Unsafe. Suppose the macro names some internal variable foo.
Any code that calls the macro and has a local variable named
foo will have problems, and the problems depend on the
innards of the macro. If the macro is changed to make no
outward modification in its normal behavior, but with
internal variable renamings, it might suddenly cause bugs at
call sites that formerly worked. If the macro and the call
site are in separately-managed pieces of code, rather than
one person's code, this is especially problematical.

Now consider side effects:

Functions: safe. Function argument expressions are evaluated left
to right and then assigned to the function's formal
parameters, then the function body is run. Changes to the
number of times and sequence of use of the formal
parameters within the function body have no effect at the
call site, given the function's own return value and side
effects don't change.
Closures: safe. Closures are exactly like functions in this regard,
and though closures can have side effects locally in the
enclosing code, so can the contents of an if branch or a
loop body (and some languages implement these with
closures!).
Macros: Unsafe. Macro arguments are evaluated as they are
encountered in expanding the macro and then executing the
expanded code, so if parameters a, b, and c are used in the
sequence c, a, a, the expressions at the call site are
evaluated in the same order -- so the third argument
expression is evaluated, then the first is evaluated twice,
while the second is never evaluated. If these have side
effects, there's a problem. Furthermore, side effects of
the macro body and of the arguments can be interspersed
arbitrarily. Worse, changes to the macro's implementation
that nominally don't change its semantics can and will
rearrange these side effects.

Worse still, it's hard to fix these problems with macros.

Variable capture: this one is easy to avoid, though the recipe for
avoiding it is easy to forget. In C macros intended to be statements
rather than expressions, you can use a brace-delimited block inside
the macro with its own local variables, for example:

#define FOO(x) {int t = (x); foo1(t); foo2(t);}

will not clobber a local variable named "t" at a call-site, but will
without the braces. Lisp may have an equivalent way of creating a more-
local scope to brace blocks that can be exploited similarly, and if it
does it can probably be used in expression-equivalent macros and not
just statement-equivalent macros, but forgetting to do it will be no
easier to avoid.

Barring a way to create a local scope block inside the macro, the only
way out seems to be to use a global variable. Ugh.

Order of side effects: this one is harder. Again in statement-
equivalent C macros you can use code like the above; in that code,
side effects of x will occur only once and before any side effects of
the macro code, since "int t = x;" has no side effects.

#define FOO(x) foo1(x); foo2(x)

would have run into this problem however, with side effects of x
happening twice, once before and once after the side effects (if any)
of foo1.

Lisp macros surely allow a way out analogous to "t = x;" at the cost
of causing variable capture. As noted above, they *may* provide some
way to prevent variable capture. Both things will be easy to forget,
and the problems caused by macros that forget one or both will be
difficult to diagnose and fix.

If the only way to avoid variable capture is to use a global variable,
though, ugh.

Even if not, there's still yet another problem: consider calling the
following macro:

#define BAR(x,y) {int s = (x), t = (y); foo1(s); foo2(s); foo1(t); foo2
(t);}

in this context:

int s = 17;
int a = 34;
BAR(a,s);

This expands to

int s = 17;
int a = 34;
{int s = (a), t = (s); foo1(s); foo2(s); foo1(t); foo2(t);};

Uh-oh! The intent was surely to invoke

foo1(34); foo2(34); foo1(17); foo2(17);

but the effect in this case will be to invoke

foo1(34); foo2(34); foo1(34); foo2(34);

because the internal local variable s hides the s that's local to the
call site, and it was a parameter. Change the names from a and s to a
and b and the problem goes away, so the problem depends on the names
of the variables near the call site. Arrrrgh!!

Macros in pure-functional languages are only half as evil, since order
of side effects are not a concern, but the problems with variable
capture remain, and as can be seen above simply cannot be made to go
away entirely, except by using global variables with all the problems
that THOSE entail. I doubt most pure functional languages will allow
that dubious escape hatch either, so using one to evade the order-of-
side-effects problem actually makes the variable capture problem
marginally worse.

Only marginally. Once you resort to global variables, you give up
reentrancy for the affected macro, you give up thread-safety or add
some lock contention at every site the macro gets used, and you create
potential name pollution and side effect issues. There's a reason
they're considered harmful.

Macros: the "goto" of the Lisp family of languages.
Now if you want to make the argument
that there are better IDEs available for Java than for Lisp that
may be true but I'm only commenting on whether Lisp macros are
inherently more dangerous than other programming constructs.

So am I, in the extensive discussion immediately above.
And code which calls a function will break if the function
implementation is not correct.

It won't generally be the case, though, that a change to the
function's innards that doesn't change its (nominal) semantics will
break things.

As already explained to gugamilare, if a function takes a and b and
returns the sum of a and 2*b, it doesn't tend to matter (except maybe
for obscure overflow or fp roundoff related cases, and maybe
performance-wise) whether it's implemented as a + b + b or a + 2*b. It
also doesn't matter if the compiler optimizes both cases to a + (b >>
1).

If it's a macro instead, all hell breaks loose. The a + b + b version
causes the expression that supplies b to be executed twice, and
therefore any side effects of that expression to happen twice. For
example, if it's x++, x gets incremented twice instead of once because
of an *implementation detail*. Worse, if a coder expects x to be
double-incremented and accounts for that, then it's recompiled with
aggressive optimizations that replace x + x with x >> 1, the double-
increment goes away and you've got problems again.

Ultimately, the problem is that macros lack encapsulation while
functions don't. The caller of a function doesn't care what names are
used inside a function, nor does the function care what names are used
at any of its call sites. They're not nested scopes, but rather sister
scopes; neither sees the other's locals. There's an encapsulation
barrier of sorts between a function and all of its call sites; except
for intentional side effects, all influences go in through the
argument expressions and out through the return value.

Another form of encapsulation is that the call site code before the
function call runs, then each argument expression runs in left-to-
right order, then the function runs, and then the call site code after
the function call runs. There's a neat separation into blocks: all the
call site code before the function call, then the function call, then
all the call site code after. The timing, number of evaluations, and
sequence of evaluations of call site code depend solely on the
arrangement of the call site code and not one whit on the arrangement
of the code in the function body.

Neither of these holds any more with macros. The argument expressions
and macro code are chopped up, mixed, and evaluated in a sequence
dependent on the macro body. Variables in the macro can either clobber
or hide local variables at the call site, and will do so depending on
the names; changing the names in the macro or at the call site may
alter behavior drastically. Macros lack encapsulation.

Closures also lack encapsulation from their construction site, but the
problem is absent there because these are lexically nested scopes; the
bits of code that are not encapsulation-separated are also physically
proximate in the code base. It's no more of a problem than loop bodies
being able to affect or hide variables in the enclosing function body.
Macros, by contrast, have these same effects *nonlocally*.

If a closure is like a loop body in terms of its effects on code
readability, modularity, and coupling, then a macro is more like a
goto in these terms.

And all of this is *ignoring* the possibility of a macro quietly
replacing a function and altering its semantics, an issue that I
discuss elsethread.
Even if a macro had to use car and cdr to take apart its
argument it could check that the argument has the correct
structure and if it didn't issue an error.

Ah, code that compiles but yields mystery runtime errors, always a fun
way to begin the day.
in which case variable a will be bound to 1, b to 2, etc.  So
the Lisp compiler automatically checks that the arguments passed
to the macro have the right structure

What if the argument is a list cons'd at runtime, whose structure the
compiler therefore cannot know in advance? The structure could, say,
depend on the results of a very complex computation.
Actually if in C you do foo(expr1 , expr2) the order in which
expr1 and expr2 will be evaluated is unspecified.

In practice it tends to be left-to-right. It always is in Java. It is
always the case, in either language, that their side effects will all
occur exactly once.
In any case the order of evaluation is precisely specified in Lisp.

I'm sure it is. The problem is that the sequence depends on the
macro's internal guts and not just on the structure of the code at the
call site. That's tight coupling.
But it will influence the order of evaluation of all the expressions
that appear inside the function.

That's not a problem. I don't mind it if the structure of the code in
foo.java affects the order of evaluation of expressions in foo.java. I
just don't want it affecting the order in bar.java, and thankfully,
unless bar == foo or foo.java is actually Sun's Compiler.java, it
won't.

Not so with Lisp.
a = expr1;
b = expr2;

may have different side effects than writing

b = expr2;
a = expr1;

That's fine. The problem is when expr1 and expr2 in

foo(expr1,expr2)

have different side effects than in

foo(expr1,expr2)

because someone changed foo a while ago, rather than because it was
changed to foo(expr2,expr1).

Now the evaluation of code HERE is changed by code over THERE and not
just by code HERE. Do you see what I'm getting at? Subtle problems
might show up here because of changes elsewhere that wouldn't have
changed the semantics of foo IF foo were a normal function, or IF
expr1 and expr2 were free of side-effects.

I don't understand why you're still not getting it. It's gotta be as
plain as the nose on your face by now that macros lack a form of
encapsulation that functions have, and the implementation details of a
macro are necessarily tightly coupled to the code at every call site,
whereas the coupling is much looser between functions and their call
sites.

I've thoroughly torpedoed your repeated claim that macros are "just as
safe as functions". It's taking on water and heading for crush depth.
Abandon ship already!
Now let's imagine that C had a special syntax which allowed you
to decide in which order the arguments of a function get
evaluated. So in a call like foo(expr1 , expr2) you could use
the special syntax to decide if expr1 gets evaluated before
expr2 or vice versa. What makes you think that this would
present any greater programming problems or potential for bugs
than what C actually does offer?

It wouldn't if it were syntax used at the call site. It would if it
were syntax used inside foo's function body in some distant chunk of
code you might not even be allowed to modify, or even have in source
form at all.
It seems to me that order of
evaluation is a central aspect of (non-functional) programming
so I don't see how having one more place where you can influence
order of evaluation makes such a great difference.

The problem is that it influences order of evaluation not locally but
through "spooky action at a distance". In quantum theory, we've
learned to accept that as unavoidable, but keep it the hell away from
my code!
Has someone mentioned variable capture in this thread?

It was mentioned, but that was about it. Until now. Now I have gone
into some detail about it, since nobody else was bothering to go into
any detail about it and since it is another powerful argument against
your "macros are no biggie, really!" nonsense.
Anyway there is a standard and easy way to avoid this

I'm sure there is, but it will have its own problems. I noted two
escape hatches above, each with problems:

1. Create a nested scope and use local variables. Now you only get
trouble if a call site uses a variable of the same name in one of
the arguments to the call, instead of all the time. But you still
can't avoid it entirely. Or:
2. Use global variables, preferably in combination with namespaces.
Of course, all of us here already know why global variables are
only slightly less evil than goto. Even with namespaces.
 
S

Series Expansion

Commercial implementations offer their libraries, and they do cover
the areas you mentioned.

And free implementations?
we're still far from the "grab from the shelf" philosophy Java strives
to achieve (and manages to, often ;).

Oh. How disappointing.
No, I'm not talking about the overhead of static typing here. The
"tangent about XML" you removed from the quotation was an example of
how, in big applications, Java programmers often resort to sub-optimal
means (like very complex XML configuration files) only to achieve
something they have from the start in dynamic languages - namely, more
dynamism, or if you prefer, less constraint from static types.

Getting rid of types to solve this is throwing out the baby with the
bathwater.
in Lisp you can test in isolation the single function
or macro where you have made the typo, and catch it early.

Says someone who evidently has never heard of junit.
 
P

Pillsy

Getting rid of types to solve this is throwing out the baby with the
bathwater.

It's an awfully good thing that Common Lisp didn't do that, then,
isn't it?

Cheers, Pillsy
[...]
 
S

Series Expansion

It has already been addressed.

In what quantum universe? Is the grass greener there than it is here,
too? :)
There are other ways.  We pointed out
that CLOS doesn't work like that.

Replace "class" with "generic function" then:

1. The vendor puts it in the system generic function. No
problemo.
2. Everyone rolls their own. Ugh.
3. A third party library puts it in the system generic
function. Whereas the vendor would create an automatic
standard, absent this, most likely multiple third party
libraries would develop to do the job, and would each
do it a bit differently. Code using one and code using
another one could not typically be combined without
problems.
- in CLOS, you can add methods dispatching on your own classes to any
  generic function.

Worse, sometimes you have to, even with generic functions from someone
else's namespace, even ones in the system package(s).

CLOS, and Lisp itself, seem designed for the "lone hacker in his
garage" model of software development. Very little modern software is
actually developed that way.
- in CLOS, you can redefine methods at will, but you're a big boy and
  expected to know what you're doing.  So if you want to replace a
  method defined in a library, you always can do so, for the better
  good of your program.

And then watch your coworkers tearing out tufts of hair, screaming,
sobbing, throwing office furniture around, and going prematurely gray.

If I were of a sadistic bent, I might like that idea.

As things stand ...

Well, I think my opinion has become quite clear.
Beyond that, I won't give you a CLOS lecture here, just go learn
Common Lisp, if you want to stop behaving like a fool.

And here I thought we might be settling into some semblance of a
rational discussion of the relative merits. Then you whip out this
totally gratuitous insult and sling it in a public forum. Shame on you!
 
S

Series Expansion

You're now claiming it has supra-Turing capabilities? What's the
bonus? Halting oracle? True-analog operations? The downside being:
what's the hardware requirements? I don't have a quantum computer over
here, after all, just a few ordinary Pentium workstations.

No, I mean simple things, such as doing additions or multiplications.

[pjb@galatea :0.0 tmp]$ cat add.java
class Add
    extends Object
{

    static public void main(String[] args)
    {
        int tt=2100000000;
        System.out.println("2,100,000,000+2,100,000,000 = "+(tt+tt));
    }

}

[pjb@galatea :0.0 tmp]$ javac add.java  && java Add
2,100,000,000+2,100,000,000 = -94967296

[pjb@galatea :0.0 tmp]$ clisp -norc -q -x '(let ((tt 2100000000)) (format t "~A + ~A = ~A~%" tt tt (+ tt tt)))'
2100000000 + 2100000000 = 4200000000
NIL

Ignoring the spurious NIL here, have you forgotten a) Turing
completeness and b) java.math.BigInteger?
 

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,434
Messages
2,571,688
Members
48,796
Latest member
Greg L.

Latest Threads

Top