Re: Link time optimization in D

2010-06-01 Thread Michiel Helvensteijn
Walter Bright wrote:

 The link-time optimization is essentially compiling the whole project
 anyway,

That makes no sense.

 so I don't see how you're saving any time with it over D's approach.

You save time by recompiling only files that have changes.

More importantly, what if you only have access to the object files?

-- 
Michiel Helvensteijn



Re: Link time optimization in D

2010-06-01 Thread Michiel Helvensteijn
Adam Ruppe wrote:

 You save time by recompiling only files that have changes.
 
 But, then the whole program goes through the process again anyway to
 perform the optimization. You save a little time in skipping parts of
 the front end for unchanged file, but the whole backend process has to
 happen anyway.

That `backend' process is not the compilation process all over again. It's
not even the optimizer phase all over again. It's just the extra
optimizations that could not be performed on a file-by-file basis.

Or at least it should be.

-- 
Michiel Helvensteijn



Re: The D license

2010-03-10 Thread Michiel Helvensteijn
Jesse Phillips wrote:

 There is really nothing wrong with the opening of the license other than
 it being more direct than any other license.

Yeah.

The Software was not designed to operate after December 31, 1999.

That's not wrong.

Hehe. I still find that part of the license so ridiculously funny. I'm
actually thinking of writing a new software license myself:

Do not use it in a box.
Do not use it with a fox.
Do not use it with a mouse.
Do not use it in a house.
Do not use it here or there.
Do not use it anywhere.

-- 
Michiel Helvensteijn



Re: The D license

2010-03-10 Thread Michiel Helvensteijn
Jesse Phillips wrote:

  There is really nothing wrong with the opening of the license other
  than it being more direct than any other license.
 
 Yeah.
 
 The Software was not designed to operate after December 31, 1999.
 
 That's not wrong.
 
 It isn't wrong, just because it is after 2000 doesn't mean the software
 was designed to work in this millennium. Sure, the software has proven
 itself, but doesn't make the statement invalid.

The language and compiler are still now being worked on under this license,
aren't they? Yet the statement is not invalid?

Since we are now living after December 31, 1999 (and we haven't invented
time travel), that suggests to me that the software is not being designed
to operate at all. That's, if not wrong, completely silly.

-- 
Michiel Helvensteijn



Re: The D license

2010-03-10 Thread Michiel Helvensteijn
Nick Sabalausky wrote:

 Michiel's rhyme is a reference to, and slight modification of, the
 children's book by Dr. Seuss Green Eggs and Ham (I had that as a kid).

I didn't know it as a kid. But it is referenced so often in popular
television series and such, I eventually had to look it up. It's a catchy
rhyme.

The Scarlet Pimpernel is often referenced too. He's mentioned in at least
Black Adder the Third and The Simpsons (where he is pitted against Zorro).
Who says people need literary education? We just need TV. ;-)

-- 
Michiel Helvensteijn



Re: Good Contract programming idiom?

2010-03-02 Thread Michiel Helvensteijn
bearophile wrote:

 What do you think? Do you agree that's better to use exceptions like this
 to test arguments in public methods (instead of using asserts in
 preconditions)?

Short answer: No!

Longer answer:

It depends. With exceptions, your methods and constructors basically double
as a test of input validity. You can catch the exception and recover. And
if this is part of the behavioral specification, that's fine.

But I suspect these exceptions are not supposed to be caught, and are only
used as makeshift release mode assertions. That's not nice. Preconditions
are part of the public interface, and D should treat them better.

Even in release mode, I'd want to keep the runtime checks, except if we have
static proof of total correctness at every call site, in which case runtime
checks are redundant. If the programmer is deadset on removing runtime
checks for unproven assertions, he should have to compile with
the --dangerous-unchecked-assertions flag.

-- 
Michiel Helvensteijn



Re: Evaluation order

2010-02-25 Thread Michiel Helvensteijn
Walter Bright wrote:

 This is because to me, any asymmetric choice of evaluation order would be
 arbitrary and wrong. What's so special about left-to-right?
 
 Arbitrary, yes. Wrong? no - specifying it removes another source of
 potential user bugs. Left-to-right is natural because that's the way we
 read things.

I'm sure you are aware that entire cultures read things right-to-left.

Anyway, don't think I don't see your reasoning. I can argue your point:

* Even though both are equally well-defined behavioral contracts, many
people will understand a fixed sequential order better than
non-deterministic choice, so might cause more bugs in the latter case.

* D already contains English keywords and English libraries. It's already
dominantly western, so left-to-right won't be unexpected.

I just have this quest for a beautiful and elegant programming language. In
such a language, the order of side-effects should not matter in any
operation (not just function calls).

Operators that are commutative in math (and, or, +, *) should be commutative
in the programming language too, regardless of side-effects and
short-circuiting (which would still be possible, ask me how).

But I understand why D places more value on practicality than beauty and
elegance.

-- 
Michiel Helvensteijn



Re: Evaluation order

2010-02-24 Thread Michiel Helvensteijn
bearophile wrote:

 C specifications do not define the order of evaluation for function
 arguments. It can be left-to-right, right-to-left or anything else and is
 unspecified. Thus any code which relies on this order of evaluation is not
 portable.
 
 D can solve this problem as I think Java has done, just specifying it, and
 forcing the compiler to produce hypothetically a bit less efficient code
 in some situations.
 
 Another strategy to solve this problem that's possible in D (and not
 possible in C) is to allow only pure expressions inside function calls. So
 in a function call you can put pure expressions like x+5 or calls to pure
 functions. And then the D compiler is free to leave unspecified the order
 of evaluation of function arguments.

I would prefer that the evaluation order be officially specified as
non-deterministic. That is, the standard guarantees that the observable
behavior be equivalent to some sequential order of evaluation.

For example:

void f() {}
f(x = 1, x = 2);
assert(x == 1 || x == 2);

It's the same as what C does, just more formally defined. The compiler is
free to choose the most efficient implementation that satisfies the
contract.

This is because to me, any asymmetric choice of evaluation order would be
arbitrary and wrong. What's so special about left-to-right?

-- 
Michiel Helvensteijn



Re: Array operation for computing the dot product?

2010-02-03 Thread Michiel Helvensteijn
bearophile wrote:

 Indeed. The difficult question is, what would the syntax be?
 
 What about the simper:
 x.dot(y)

I don't like symmetric operations with an asymmetric syntax.

Better:  dot(x, y)
Even better: dot_product(x, y)
Funner:  sum(x .* y)

-- 
Michiel Helvensteijn



Re: Function calls

2010-01-28 Thread Michiel Helvensteijn
Bill Baxter wrote:

 byLine() is a function. It changes the state of stdin. Calling it
 consecutively will in general result in different return values. If there
 were two guys: stdin.currentLine (property) and stdin.nextLine(), it
 would be a different story.
 
 That's not how it works, I think.
 Just calling byLine() by itself only returns a range struct.
 Consuming things from that range is what changes the state of stdin.

Ah, my bad. I was guessing. Still, returning a handle from a property that
can change the state of the originating object is.. iffy.

-- 
Michiel Helvensteijn



Re: Function calls

2010-01-28 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 I agree. So where's the consensus? Things seemed so clear when people
 were beaten with @property over their head.

If I read the TLP correctly, @property seems not to be working correctly.

@property (or any other notation marking property getters/setters) should be
enforced. Functions that have it must only be invoked using property
syntax. Functions that don't have it must be called with parentheses.
That's the whole point. To give the designer of the class control over how
it is used.

The problem is people blurring the line between what's supposed to be a
function and what's supposed to be a property, by abusing property syntax
to invoke actions without parentheses.

In reality, I believe there's not only a clear line between the two
intentions, there's a demilitarized zone. You just need to enforce it. You
can't have your cake and eat it too.

-- 
Michiel Helvensteijn



Re: Google's Go

2010-01-23 Thread Michiel Helvensteijn
Bane wrote:

 It looks like to me they are making Google Goo for prestige. Search
 engine, browser, now programming language... Whats next? OS?

Google has designed two operating systems already.

 Laptops?

Google Laptops, Google Phones. Sure. They're just not building the hardware
themselves. I myself have a Google Experience phone.

 Fast food franchise?

I was at a programming contest once where Google sponsored the catering.
Does that count? :-)

-- 
Michiel Helvensteijn



Re: yank unary '+'?

2009-12-08 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 I can't imagine a use for it and removing it makes the language
 simpler.
 
 I disagree

(...)

 I was mostly talking about overloading operator +. Operator + has a long
 history of being available for overloading in C++, which we can use to
 our advantage. It has been used to emulate DSLs, but I think we have
 much better means to define DSLs in D than to redefine all operators to
 mean some convention-chosen things.

Ok, so it's: I can imagine only one use for it -- but I think we have a
better way to do that -- and removing it will make the language simpler.

How is that a better reason?

I'll ask you again, because I'm really curious. Why would you remove unary
plus?

* I can't imagine it would make the compiler simpler to any significant
degree. If the compiler is well written, unary plus will simply occupy a
standard spot in a couple of lists (parser, op-function-names, ...). I
doubt removing it would even make a dent in the complexity of the code.

* Assuming for the moment that the D language and the D compiler are
different things (which they aren't), would it make the language simpler?
It would probably only confuse programmers who expect the natural
counterpart to unary minus to be present. As for documentation, again, it's
a matter of a single spot in a list somewhere.

* It doesn't, as far as I can see, take up syntax-space that might be
occupied by another more useful feature.

* There are even known use-cases. Though for a simple, expected, symmetric
feature such as this one, that wouldn't even be a requirement for me.

(Note that I'm not especially interested in the unary plus operator per se.
I'm just using it as a convenient case-study. I'm more curious about your
opinion on why language features should be adopted/tossed/kept.)

Best regards,

-- 
Michiel Helvensteijn



Re: yank unary '+'?

2009-12-07 Thread Michiel Helvensteijn
Andrei Alexandrescu Wrote:

  What will removing it gain you?
 
 Sancta simplicitas.

Hm.. I don't really buy that argument.

I see you and Walter removing/witholding things (incomparability operators, 
logical operator overloading) from the language, because: I can't imagine a 
use for it and removing it makes the language simpler.

Meanwhile, you're keeping C syntax for function-pointers around, and I'm 
missing syntactic sugar for my tribool.

The fact that you or I think there isn't a use for a feature, doesn't mean 
there isn't one. Programmers keep finding new and unintended uses for language 
features, which is a good thing. And if you want to simplify the language, I 
wouldn't start with the unary + when you've still got all that C stuff around.

-- 
Michiel Helvensteijn



Re: should postconditions be evaluated even if Exception is thrown?

2009-12-03 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 This may sound crazy, but if you just follow the facts that distinguish
 regular error handling from program correctness, you must live with the
 consequences. And the consequence is - a function's postcondition must
 be designed to take into account exceptional paths. Only in case of
 unrecoverable errors is the function relieved of its duty.

You don't want the regular postcondition to express exceptional outcomes.

However, there *should* be an exception-postcondition clause, which
describes the conditions which are guaranteed to hold after an exception is
thrown.

int f() throws (SomeException, SomeOtherException)
pre { }
body { }
post(int result) { }
epost(SomeException x) { }
epost(SomeOtherException)x) { }

I believe JML does something like this.

-- 
Michiel Helvensteijn



Re: How Nested Functions Work, part 1

2009-09-02 Thread Michiel Helvensteijn
language_fan wrote:

 I agree it would be better to allow forward references for nested
 functions, I just wished to point out that the current behavior is not a
 bug, it was built that way.
 
 That's great news actually. It might even mean that this might change
 some day.

I still find it silly that it was built that way. Seems to me you should be
able to forward-reference *any* symbol that has a value that can't change
over its lifetime. Functions, const/immutable vars, typedefs, classes, etc.

-- 
Michiel Helvensteijn



Re: How Nested Functions Work, part 1

2009-09-02 Thread Michiel Helvensteijn
Rainer Deyke wrote:

 I still find it silly that it was built that way. Seems to me you should
 be able to forward-reference *any* symbol that has a value that can't
 change over its lifetime. Functions, const/immutable vars, typedefs,
 classes, etc.
 
 That can lead to subtle problems in the case of functions:
 
 int i = f();
 int f() { return i; }

You're right, I forgot about that. You can conservatively statically forbid
this. But I admit it makes the 'constant data should obviously be
forward-referenceable' thing less convincing. :-)

-- 
Michiel Helvensteijn



Re: How Nested Functions Work, part 1

2009-09-02 Thread Michiel Helvensteijn
Jarrett Billingsley wrote:

 It wouldn't even be that difficult. Basically if you treat
 forward-referenced nested functions as a sort of goto, the same rules
 should apply: a call to a nested function may not skip the
 initialization of any variables it depends on. When i's initializer is
 evaluated, it has not been declared yet, so the call to f is illegal.
 It also prevents other invalid use.

That's what I meant, yes.

Basically, any function that reads i may not be called before i is declared,
nor in i's initialization. Of course, in reality, it depends on the control
flow within the function. But that's holy grail stuff. So: conservatively.

-- 
Michiel Helvensteijn



Re: How Nested Functions Work, part 1

2009-09-02 Thread Michiel Helvensteijn
Michiel Helvensteijn wrote:

 Basically, any function that reads i may not be called before i is
 declared, nor in i's initialization. Of course, in reality, it depends on
 the control flow within the function. But that's holy grail stuff. So:
 conservatively.

Oh, you may also not take a delegate of the function before i is declared.
Same reason.

-- 
Michiel Helvensteijn



Re: With block proposal

2009-08-27 Thread Michiel Helvensteijn
Freeman wrote:

 Example:
 
 with(a)
 {
:x = x;  // Unambiguously means a.x = x
:x = .x; // Unambiguously means a.x = .x
 }

I think the plan is to get rid of 'with', and I can't say I disagree.

If you can say

with(a) { :x = f(); :x = g(); }

you can also say

{ auto w = a; w.x = f(); w.x = g(); }

or similar.

Hardly any longer, and without the need for a whole language construct.

-- 
Michiel Helvensteijn



Re: With block proposal

2009-08-27 Thread Michiel Helvensteijn
Daniel Keep wrote:

 you can also say
 
 { auto w = a; w.x = f(); w.x = g(); }
 
 or similar.
 
 Unless a is a value-type member of something else.

That's why I said 'or similar'. Doesn't D have anything to create an
alias/reference to a value-type variable?

-- 
Michiel Helvensteijn



Re: D should disallow forward references

2009-08-26 Thread Michiel Helvensteijn
Adam D. Ruppe wrote:

 I can't take your GPL program and arbitrarily change the license to
 proprietary, and similarly (I assume) he can't take his proprietary
 license and change it to GPL.

Without following the rest of the conversation: Yes, the copyright owner can
release his work under more than one license, including both open and
closed licenses. GPL + proprietary is fine. Qt does it, for example.

-- 
Michiel Helvensteijn



Re: D should disallow forward references

2009-08-26 Thread Michiel Helvensteijn
Michiel Helvensteijn wrote:

 Without following the rest of the conversation: Yes, the copyright owner
 can release his work under more than one license, including both open and
 closed licenses. GPL + proprietary is fine. Qt does it, for example.

I'm sorry. It seems I *should* have followed the conversation first. :-)

My comment seems to be a bit irrelevant.

-- 
Michiel Helvensteijn



Re: D should disallow forward references

2009-08-25 Thread Michiel Helvensteijn
grauzone wrote:

 Conclusion: other than trying to keep a buggy feature, that isn't going
 to be fixed, remove it from the language.

A bit silly, since it's really quite easy. It just requires an extra
compiler pass.

Any constant data should be forward referenceable. That means functions,
types and const (immutable, enum, etc.) symbols/vars.

Seems to me like reference resolving is one of the first things that should
work correctly. I'd drop everything and fix this bug before working on
anything else. :-)

-- 
Michiel Helvensteijn



Re: OT - Which Linux?

2009-08-19 Thread Michiel Helvensteijn
Paul D. Anderson wrote:

 I'm going to add Linux to my PC to get a dual-boot configuration. (I'm
 tired of slw start ups and want to tap into the great tools
 available.) The tutorial I'm looking at suggests Ubuntu. Is there a
 significant difference in Linux implementations? Is Ubuntu one of the
 better ones? Does it make a difference for running D2?

It depends on what you want and how much experience you have. Ubuntu is
certainly a good one to start with. Or one of its flavors. E.g. if you like
KDE, go for Kubuntu.

I myself have never looked back since I started using Gentoo. A bit more
advanced. But a great way to learn the internals of Linux. It has a lot of
online documentation and a helpful community. It also makes my system
blazing fast, since every package is compiled from source.

There's really no difference between distro's when it comes to running,
well, most any linux application.

-- 
Michiel Helvensteijn



Re: It's awfully quiet

2009-08-18 Thread Michiel Helvensteijn
Lars T. Kyllingstad wrote:

 I'm done!

 Congrats! Did your opponents give you a hard time?

Congrats Andrei!

 Still two years to go, here. :)

Four here. I'm starting September 1 this year.

-- 
Michiel Helvensteijn



Re: Explicitly saying ref or out when invoking a function

2009-08-11 Thread Michiel Helvensteijn
Ary Borenszweig wrote:

 In C# when you define a function that takes an out or ref parameter,
 when invoking that function you must also specify ref or out. For example:
 
 void fun(ref uint x, double y);
 
 uint a = 1;
 double b = 2;
 fun(ref a, b);
 
 What do you think?

I see what you mean, however:

-

swap(ref a, ref b);

I think that's overly verbose for a call with very descriptive function name
to begin with.

-

Perhaps an IDE can use formatting to show you the ref parameters.

-

The designer of the function can always request pointers, so the caller has
to explicitly pass addresses.

-- 
Michiel Helvensteijn



Re: Void-safety (and related things)

2009-08-11 Thread Michiel Helvensteijn
bearophile wrote:

 You can't ask a single person to be able to do everything. Are you able to
 implement that thing? Probably I am not able. If someone here is able and
 willing to do it then I suggest such person to ask Walter permission to
 implement it.

I doubt it's the direction D wants to go. Because proving correctness at
compile-time requires the holy grail, and testing correctness at runtime
requires extra space for each variable and extra time for each access.

-- 
Michiel Helvensteijn



Re: Void-safety (and related things)

2009-08-11 Thread Michiel Helvensteijn
Ary Borenszweig wrote:

 I doubt it's the direction D wants to go. Because proving correctness at
 compile-time requires the holy grail, and testing correctness at runtime
 requires extra space for each variable and extra time for each access.
 
 What do you mean by holy grail?

You missed that discussion, did you? Basically, if you want to know at
compile-time whether a variable is initialized, there are several
possibilities:

* Be overly conservative: Make sure every possible computational path has an
assignment to the variable, otherwise give an error. This would throw out
the baby with the bathwater. Many valid programs would cause an error.

* Actually analyze the control flow: Make sure that exactly all reachable
states have the variable initialized, otherwise give an error. Dubbed holy
grail, because this sort of analysis is still some time off, and would
allow some very cool correctness verification.

-- 
Michiel Helvensteijn



Re: T[new]

2009-08-09 Thread Michiel Helvensteijn
Walter Bright wrote:

 But I know, unique isn't easy to implement to fit all the use cases we'd
 like to solve. I'm just sharing a dream.
 
 We explored unique at length, and trying to make it work would render
 the rest of the language nearly unusably complex.

I've heard 'unique' mentioned on this group now and then. What does it mean
in the context of programming languages?

-- 
Michiel Helvensteijn



Re: proposed syntax change

2009-08-06 Thread Michiel Helvensteijn
Paul D. Anderson wrote:

 I was browsing the Python spec yesterday and came across this interesting
 and useful syntax:
 
 / (one slash) means floating point division, e.g. 5/2 = 2.5 even though
 5 and 2 are integers
 
 // (two slashes) means integer (floor) division, e.g. 5.0//2.0 = 2.0
 even though 5.0 and 2.0 are floats.

Yeah, I love that distinction. As a matter of fact, I've added it to my own
language. Same syntax, too, though there was some thought about using
the div keyword instead.

 I've always been a little troubled by the standard division operator being
 dependent on the types of the operands. (I understand the need for it, I
 just didn't like it much.) Now here is an elegant (IMHO) solution.

I agree. It's one of those C idiosyncrasies the world could do without.

 It seems to me that this could be added to D with very little effort and
 would add a feature to the language.

Seems like trouble to me. If we ignore for the moment the fact that // is
used for line comments (D could use div, for example), changing the
meaning of / for integer operands would probably break many programs.

 Oh wait...I think // is used elsewhere. Well, we could still use it but
 mark it as a breaking change. Then users could simply remove all previous
 uses of // from their code. If they REALLY need to retain the old //
 functionality we could replace it with a new symbol. How about --, like
 Ada? Oh wait...

Line-comments are very useful. My language uses |.

-- 
Michiel Helvensteijn



Re: reddit.com: first Chapter of TDPL available for free

2009-08-04 Thread Michiel Helvensteijn
The compiler allows omitting type declarations only when types can be
unambiguously inferred from context.

That's not exactly true, is it? A small non-negative integer literal could
be an integer of any width or signedness. Yet 'int' is arbitrarily chosen
for some reason. There are also multiple floating point types.

My points:
* The line I quoted is incorrect. Int/float literals are not unambiguous.
* D literals can have a suffix specifying the exact type. Perhaps that's
worth mentioning.

I find your style of writing a bit too informal, though easy to read.

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-03 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 auto data = std.file.readText(filename).chomp.split;
 
 I love that too. Unfortunately, the way the water is moving, it looks
 like we'll lose some or all of that.

That's not really true. Some of those no-parameter functions are just meant
to be read-only properties instead of functions.

auto data = std.file.textFrom(filename).chomped.split;

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-03 Thread Michiel Helvensteijn
KennyTM~ wrote:

 auto data = std.file.readText(filename).chomp.split;

 I love that too. Unfortunately, the way the water is moving, it looks
 like we'll lose some or all of that.
 
 That's not really true. Some of those no-parameter functions are just
 meant to be read-only properties instead of functions.
 
 auto data = std.file.textFrom(filename).chomped.split;
 
 So to allow omission of the parenthesis of these read-only properties
 we do

No, it's not allowing omission, it's forcing omission. That's what
properties are.

 @property string chomped (string x) { ... }
 
 ? I don't think Walter's syntax is capable of introducing properties
 to these free methods, but the property attribute can.

I still think an identifier is either property or function, but not both.

And judging by the way the wind is blowing, attributes/annotations will not
be used for properties.

 (However, this may make
 
 chomped = abcd
 
 valid, which is not what we want.)

No, it wouldn't, since it'd be a read-only property. That means you can only
read, not write.

-- 
Michiel Helvensteijn



Re: My body is ugly [Re: Contextualizing keywords]

2009-08-03 Thread Michiel Helvensteijn
Pete wrote:

 I think this is much more elegant:
 
 # int foo(int a) {
 #in {
 #   assert(a2);
 #}
 #
 #return a-1;
 # }

I have to disagree. That suggests that 'in' is a scope within the body,
which would have access to its local variables. Of course, it shouldn't.

-- 
Michiel Helvensteijn



Re: My body is ugly [Re: Contextualizing keywords]

2009-08-03 Thread Michiel Helvensteijn
 I think this is much more elegant:

 # int foo(int a) {
 #in {
 #   assert(a2);
 #}
 #
 #return a-1;
 # }
 
 I have to disagree. That suggests that 'in' is a scope within the body,
 which would have access to its local variables. Of course, it shouldn't.
 
 If you make 'in' clauses 'pure' (which they are, conceptually), it works
 fine.

But 'in' still needs read-access to the actual parameters and every visible
symbol in a scope shallower than that of the function.

 I agree with Pete, I think that's a greatly superior syntax to what we
 have now.

Then I assume you still want to restrict the precondition to being the first
element in the body? Because putting it in there suggests that it may
appear anywhere a statement can.

-- 
Michiel Helvensteijn



Re: My body is ugly [Re: Contextualizing keywords]

2009-08-03 Thread Michiel Helvensteijn
Denis Koroskin wrote:

 Then I assume you still want to restrict the precondition to being the
 first element in the body? Because putting it in there suggests that it
 may appear anywhere a statement can.
 
 Why not?

Because a function precondition indicates the set of admissible states
before execution of a function. Emphasis on *before* and *function*.

-- 
Michiel Helvensteijn



Re: My body is ugly [Re: Contextualizing keywords]

2009-08-03 Thread Michiel Helvensteijn
Denis Koroskin wrote:

 Because a function precondition indicates the set of admissible states
 before execution of a function. Emphasis on *before* and *function*.
 
 Allowing them anywhere inside a function body will only improve the
 feature.
 
 BTW, it is already allowed, just use 'debug' instead of 'in':

Or just use an assertion without an enclosing scope?

The difference between a precondition (in) and an arbitrary assertion inside
the function body is that the precondition is part of the public interface,
whereas the function implementation is not.

 TBH, I'd just drop the whole DBC feature from a language, it creates more
 problems than solves.

I, on the other hand, believe it's the future of program verification.

-- 
Michiel Helvensteijn



Re: My body is ugly [Re: Contextualizing keywords]

2009-08-03 Thread Michiel Helvensteijn
Don wrote:

 It would be strange to put outer function statements before the
 precondition, but that's true of any inner function.

I don't see it as an inner function, but as a part of the public interface.
It's an enforceable documentation of the function.

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-03 Thread Michiel Helvensteijn
Steven Schveighoffer wrote:

 So your answer is, there is no ambiguity because it's not possible to
 access the getter/setter directly?  That poses a problem for existing code
 which uses delegates to such functions.  I'm not sure we want to lose that
 ability.

I agree. But it's hardly up to me, is it? :-)

-- 
Michiel Helvensteijn



Re: Contextualizing keywords

2009-08-03 Thread Michiel Helvensteijn
Michael Mittner wrote:

 For future extensibility it should be
 
 keyword type=pure SomeType foo() { /* ... */ }
 
 ;)

You forgot the closing tag.

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
Walter Bright wrote:

bool empty { ... }
void empty=(bool b) { ... }
 
 The only problem is when a declaration but not definition is desired:
 
bool empty;
 
 but oops! That defines a field. So we came up with essentially a hack:
 
bool empty{}
 
 i.e. the {} means the getter is declared, but defined elsewhere.
 
 What do you think?

It is quite hack-ish. There are ways to have your cake and eat it too. I
wouldn't settle for 'bool empty{}'.

--
bool empty {
void set(auto value) { ... }
auto get() { ... }
}

empty = false; // empty.set(false)
auto b = empty; // auto b = empty.get()
--

for example, requires no hacks and no keywords. And has the added advantage
that you can still use the getter and setter methods directly. To call them
or get delegates from them.

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
Michiel Helvensteijn wrote:

 --
 bool empty {
 void set(auto value) { ... }
 auto get() { ... }
 }
 
 empty = false; // empty.set(false)
 auto b = empty; // auto b = empty.get()
 --
 
 for example, requires no hacks and no keywords. And has the added
 advantage that you can still use the getter and setter methods directly.

It should be noted that there is an ambiguity if the type of the property is
a struct/class with members named 'get' and 'set'. As I see it, there are
three ways to resolve it:

* Disallow properties with such a struct/class. This seems a little bit
excessive and silly. But it is one way.

* The 'set' and 'get' from the property are only used for the
property-calling syntax. They can not be referenced directly. The members
of the struct/class would all be accessable. This would work about the same
way as, for example, the suggestion from John C in this thread. And if you
go down this path, you might as well condense the syntax, as he did.

* The 'set' and 'get' from the property are accessable functions and they
overshadow possible member functions with those names.

My language uses the third way, but there is no problem with overshadowing.
The 'set' and 'get' functions have the same special purpose for every type,
and the property is meant to override them.

I guess D could do something similar using, instead of my 'get' and 'set',
D's 'this' and 'opAssign' respectively.

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
JPF wrote:

 There's at least one more solution:
 define the property as
 --
 bool empty {
 void set(auto value) { ... }
 auto get() { ... }
 }
 --
 but rewrite empty.get/set to empty.__get/__set. As far as I know names
 beginning with __ are reserved, so the returned type of the property
 couldn't define it.

This may be acceptable. I don't much like that the double-underscore is
necessary, but it may be the best solution there is.

 auto getter = empty.__get()

You meant without the parentheses here, right?

 As an addition
 --
 auto b = empty
 --
 would then return a pointer to the returned value.

That would be a pointer to a temporary value, though. Not very useful. But
lexically, it works, yes.

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 I'd like to have an easy enough syntax for defining read-only properties
 (often in my code). With the proposed syntax, one writes
 
 bool empty { ... }
 
 and calls it a day, but with the elaborate getters and setters there are
 two scopes to get through:
 
 bool empty { auto get() { ... } }
 
 which is quite some aggravation.

The point is not really the grouping of elements within brackets. That just
eliminates some redundancy. It can also look like the following:

void empty.set(bool value) { ... }
bool empty.get() { ... }

and have the same meaning as my earlier example.

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 void empty.set(bool value) { ... }
 bool empty.get() { ... }
 
 Yah, I was thinking the same. This is my #1 fave so far.

You should read my reply to myself, though. It describes an ambiguity in the
approach. Several solutions are discussed. (Just translate them from
grouping to non-grouping solutions.)

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 You should read my reply to myself, though. It describes an ambiguity in
 the approach. Several solutions are discussed. (Just translate them from
 grouping to non-grouping solutions.)

 My reader does not show that message.

How strange.

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=94712

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 Then in a later message you mention:
 
 bool empty.get() { ... }
 void empty.set(bool b) { ... }
 
 which I like and which does not seem to have difficulties; the names
 get and set will be never used as such.

Yes, those are two notations for the same thing, and they have the same
problem. Let me demonstrate:

--
struct S {
int get() { return 42; }
};

struct T {
S _s;
S property.get() { return _s; }
void property.set(S s) { _s = s; }
}

T t;

auto X = t.property.get();
--

What is the type of X? It can be either S or int, depending on how D handles
the situation.

The ambiguity is in the possibility to directly reference the getter and
setter methods. In that other subthread (the older one) I listed some
possible solutions.

The first is to make such a program an error.

The second is not to allow a direct reference to a getter/setter (so X is an
int).

The third is to let the getter/setter overshadow S members (so X is an S).

-- 
Michiel Helvensteijn



Re: Omissible Parentheses...

2009-08-02 Thread Michiel Helvensteijn
Leandro Lucarella wrote:

 Well, just take parameter-less functions then:
 
  hello   .strip.toupper.replace(O, A); // HELLA

Those would be fine candidates for read-only properties:

 hello   .stripped.inupper.replace(O, A);

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 I see. My view is that .get and .set are simply symbolic placeholders,
 but indeed some may get confused.

In my design, they are actual functions with actual names.

For D this doesn't really work. If you want symbolic placeholders, you may
want to use something other than 'get' and 'set'. For example, 'in'
and 'out' have been suggested by some. They are already keywords.

-- 
Michiel Helvensteijn



Re: property syntax strawman

2009-08-02 Thread Michiel Helvensteijn
Michel Fortin wrote:

 In my design, they are actual functions with actual names.
 
 For D this doesn't really work. If you want symbolic placeholders, you
 may want to use something other than 'get' and 'set'. For example, 'in'
 and 'out' have been suggested by some. They are already keywords.
 
 One thing with in and out makes me uneasy. Imagine a setter/getter with
 a contract:
 
 int prop.out()
 out (result) { assert(result  3); }
 body { return something; }
 
 void prop.in(int v)
 in { assert(v  3); }
 body { something = v; }
 
 Wouldn't it be a little confusing having twice the same keyword so
 close but with a completly different meaning?

I agree, it's far from ideal. Well, I'm sure a solution can be found. It's
now just down to detail.

-- 
Michiel Helvensteijn



Re: YAPP - D properties - voting

2009-08-01 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 It is ridiculous, particularly in light of the fact that no poll shows
 the landslide prevalence of everybody.

Not everyone may agree, or understand. But if you look at it objectively,
D's 'properties' cause inconsistencies, ambiguities and limitations. I'm
not listing them again, since it doesn't seem to have any effect.

I fully understand that the simple rewriting rules currently used were by
far the easiest way to get properties into D. No extra syntax or anything.
Walter probably only needed a day or two to put them into the compiler. Not
much thought had to go into it. This is evident by the fact that +=, ++,
etc. don't work. And then you could advertise that D had properties.

Then some people started to abuse property syntax to save three keystrokes
(one for the shift-key). So now all of a sudden, real properties can't ever
work for D, since you'd lose your no-parentheses function-calls, and some
backwards compatibility.

But it is a flawed design. Many people have tried to explain this to you.
But when faced with the facts, both you and Walter avoid the issue. You
focus on minor mistakes in peoples posts and then ignore their real
message. And often you simply never reply. Take, for example:

http://www.digitalmars.com/d/archives/digitalmars/D/Reddit_why_aren_t_people_using_D_93528.html#N93753

I don't think D will soon adopt the kind of properties some of us have been
advocating. You'll just treat the symptoms, I expect. This post is not
meant to convince you. It simply needed to be said. I apologize for my
confrontational tone.

-- 
Michiel Helvensteijn



Re: Omissible Parentheses...

2009-08-01 Thread Michiel Helvensteijn
Robert Jacques wrote:

 I like them too (a lot). I find they increase the clarity of my code
 (particularly function chaining).

I think that when you find you need to use function-chaining, the functions
(except possibly the rightmost) are often meant to be properties/fields.
That's why they would look more natural without parentheses.

-- 
Michiel Helvensteijn



Re: Yet a new properties proposal

2009-07-31 Thread Michiel Helvensteijn
Sjoerd van Leent wrote:

  The this rules out another symbol.
 
 Unless fields use the same new symbol.

 Yes, but won't that reintroduce the problems that are already available?

The solution is easy. You just add a second # to properties. :-)

-- 
Michiel Helvensteijn



Re: A simple rule

2009-07-30 Thread Michiel Helvensteijn
downs wrote:

 1) If it's a word, put it in the standard library.
 2) Otherwise, put it in the compiler.

What an interesting theory.

 For example:
 
 assert() - library.

Compile-time proof of assertion/contract correctness would be far more
problematic.

 complex - library.
 void - C-derived, compiler.

I believe void should be a typedef of the empty type-tuple. That would be
library.

 real - C-derived via long float, compiler.
 cfloat - library.
 for - compiler.

Might as well put this one in a library, since it's easy to simulate with a
while-loop. The only reason D can't is that, as far as I know, it doesn't
support trailing delegate literals after a function-call, that fill the
role of its last actual parameter.

 foreach - library.

Perhaps. But that would make static analysis more problematic.

 T[] - compiler.

I'd rather see dynamic arrays in a library. A template class that overloads
the T[] notation. Isn't it true that programmers don't have any control
over the allocation strategies and such of the built-in data-structures?

 T.dup, T.sort, T.reverse - library.

Agreed on that one.

But what about these:

const
immutable
class
struct
typedef
template
ref
shared

Well, you get the point. It turns out to be a bit of a silly rule, doesn't
it? Perhaps you meant: If it's a word, put it in the standard library,
unless it belongs in the core language. :-)

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-28 Thread Michiel Helvensteijn
Rainer Deyke wrote:

 For my money, the best solution is a simple property keyword as a
 function modifier. Only functions with the property modifier would be
 allowed to pose as fields (getters called without parens, setters called
 using assignment syntax). But, in all other respects, they should act
 just like functions.
 
 I like being able to distinguish between the property itself and its
 setter/getter function.

May I remind the group of a possible solution I've offered before?

Here it is, slightly modified to go along with the current no grouping of
setters and getters trend.

--
class C {
int foo.get() { ... }
void foo.set(int value) { ... }
}

C c;
c.foo = 5; // c.foo.set(5);
i = c.foo; // i = c.foo.get();
d = c.foo.get; // d = delegate to foo getter
--

It doesn't make your eyes bleed (I think). And you have a way to distinguish
between getter, setter and property.

The downside for D is that get() and set() may overshadow member functions
of the property type.

In my own language, this is not an issue, since get() and set() are special
functions that have the same meaning for each type. And overriding them is
just what a property is supposed to do.

-- 
Michiel Helvensteijn



Re: DIP4: Properties

2009-07-27 Thread Michiel Helvensteijn
BLS wrote:

 I think people got it. But it's not a property. Your one-liner seems to
 be equivalent to a field. Except, I guess, that you can't take the
 address.
 
 The whole idea of a property is that it can have non-trivial
 getter/setter functions. Like a read-only property of a Line, that
 returns its length automatically calculated from its two points. Or a
 getter and setter that keep a log of all accesses to the information.
 
 My favorite example is of a Color class, that internally stores its value
 in the RGB model, but has properties to read and change its value through
 the HSV and HSL models as well.
 
 ...

Again, what is the difference between your one-liners and simple fields?

immutable property uint theAnswer = 42;
bool has_cojones;

A property is much more sophisticated. The whole point is to write your own
setter and getter methods. Only in very few cases do you want a property
with simple field semantics. I will give you that Line class I was talking
about. Tell me how you can do this with your one-liner:

class Line {
private:

Point _a;
Point _b;

public:

this(Point a, Point b) { _a = a; _b = b; }

property float length {
auto get() {
float absX = abs(_a.x - _b.x);
float absY = abs(_a.y - _b.y);
return sqrt(absX * absX + absY * absY);
}
}

// insert trivial properties to read/write points
}

You see, the length property doesn't have its own storage. It deduces its
value from the points of the line.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-27 Thread Michiel Helvensteijn
bearophile wrote:

 Michiel Helvensteijn:
 
I don't know a compelling use-case either. But that doesn't mean there
isn't any. Nor are there any real dangers. Arbitrarily restricting the
possibilities of D doesn't seem like the right way to go.
 
 Adding random features to a language just because they look cool is a
 terrible thing to do.

This was about overloading , || and !, right?

It's not a random feature. It's a logical consequence of the operator
overloading system. Leaving them out is arbitrary. You will never convince
me that a potentially useful feature should be left out because it could
potentially be abused.

By the way, I did think of a compelling use-case just yesterday. Boost has a
three-valued bool type. true, false and maybe. Seems pretty logical to
overload the boolean operators for it.

-- 
Michiel Helvensteijn



Re: DIP4: Properties

2009-07-26 Thread Michiel Helvensteijn
Daniel Keep wrote:

 I used an example without trivial properties because... well, you just
 use member variables for that. That's why I don't see real value in
 adding default properties getter/setters.
 
 interface I
 {
 int opGet_value();
 }
 
 You cannot use fields in an interface.

You do understand that properties with automatic backing storage would
probably also not be allowed in interfaces. They'd have the same memory
layout problems as fields.

-- 
Michiel Helvensteijn



Re: DIP4: Properties

2009-07-26 Thread Michiel Helvensteijn
Daniel Keep wrote:

 You do understand that properties with automatic backing storage would
 probably also not be allowed in interfaces. They'd have the same memory
 layout problems as fields.
 
 *blink*

*blink*

 You wouldn't declare a property with automatic backing in an interface;
 that would be specifying implementation which you're not allowed to do.
 
 I was demonstrating why trivial properties exist in real code.  It's the
 *class* that would declare a property with automatic storage.

Ah, you're talking about the interface to a property, not the property
itself. I see what you mean now. My mistake.

-- 
Michiel Helvensteijn



Re: DIP4: Properties

2009-07-26 Thread Michiel Helvensteijn
BLS wrote:

 A one liner should do the trick too.
 [public] [const] property int i;
 
 I am a little bit ''' about the feedback :
 Is there really nobody who got it :

I think people got it. But it's not a property. Your one-liner seems to be
equivalent to a field. Except, I guess, that you can't take the address.

The whole idea of a property is that it can have non-trivial getter/setter
functions. Like a read-only property of a Line, that returns its length
automatically calculated from its two points. Or a getter and setter that
keep a log of all accesses to the information.

My favorite example is of a Color class, that internally stores its value in
the RGB model, but has properties to read and change its value through the
HSV and HSL models as well.

-- 
Michiel Helvensteijn



Re: DIP4: Properties

2009-07-25 Thread Michiel Helvensteijn
I think I made a few mistakes in the D code, but the point stands.

-- 
Michiel Helvensteijn



Re: DIP4: Properties

2009-07-25 Thread Michiel Helvensteijn
Daniel Keep wrote:

 Basically, the idea is that this:
 
 interface I
 {
 int foo();
 int foo(int);
 }
 
 becomes:
 
 interface I
 {
 int opGet_foo();
 int opSet_foo(int);
 }

It's a little better. But there's still ambiguity:

interface I {
int foo;
int opSet_foo(int);
}

foo = 5; // which foo is used?

To fix that one, you need to report an error when both a var and a property
of the same name are declared. Even though they don't have the same name in
the interface.

interface I {
int opGet_foo();
void delegate() opGet_opGet_foo();
}

auto x = opGet_foo;

Is that the function or the property? Well, perhaps this is not an actual
ambiguity in D. But it sure isn't pretty:

auto x = opGet_foo; // it's the property
auto x = opGet_foo(); // it may be either?
auto x = opGet_foo; // it's the function

I just don't understand this resistance against a dedicated property syntax.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-24 Thread Michiel Helvensteijn
Jarrett Billingsley wrote:

 You're suggesting adding something like 25 operator overloads to every
 property.  Can you say code bloat?

It may not be necessary in simple situations where the compiler can figure
out that it may use a more direct way. But I believe it is the right way to
go if you want more speed out of your properties, yes.

 Why not just use the following solution, which has been proposed
 God-knows-how-many-times and already has precedence in other languages
 (like C#)?
 
 obj.prop op= value;
 
 Simply becomes:
 
 obj.prop.set(obj.prop.get op value);

There are several issues with that suggestion:

* It works only if (a op= b) always behaves the same as (a = a op b).

* It would only work for op= operators. It can't do anything for arbitrary
mutator methods on the type of the property.

* In most situations, it will still be as slow as my suggested 'slow way',
without any extra operator overloads! I will repeat my 'slow'
transformation here again:

obj.prop op= value;
// auto temp = obj.prop.get();
// temp op= value;
// obj.prop.set(value);

At least with that you don't have those first two issues.

-- 
Michiel Helvensteijn



Re: What makes D, D?

2009-07-24 Thread Michiel Helvensteijn
Sean Kelly wrote:

 Compiler writers are free to add features so long as they're compatible
 with
 the base language--just look at Microsoft's C++ compiler.  What makes a D
 compiler a D compiler is that it conforms to the D language spec.

That's not exactly true, now is it? There is no D spec. A D compiler is a D
compiler if:

* it is DMD, or
* it translates D code the same way as DMD.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-24 Thread Michiel Helvensteijn
Walter Bright wrote:

 That's my problem with properties as a distinct syntax - they don't have
 distinct uses or behaviors.

You know, I don't believe I've seen you reply specifically to any of the
good points about D's properties people have been mentioning around here.

I believe the list I gave you in the 'big' subthread was fairly complete.
Would you please tell us what you think about each point? I'll repeat that
specific section of my reply here:


 Why not? Seriously, what is the semantic difference?

There are many reasons. Some have been floating around this newsgroup this
very day.

* A reference to a function should mean exactly that: a reference to the
function, for use in functional programming. Instead, just the name of a
function now invokes a call.

* In D, foo returns a function-pointer, but that means that D is context
sensitive, since its subexpression foo would return a property value. It is
confusing.

* What does D do if you have a property (p) that returns a delegate? Will
the call p() return the delegate? Or will it call the delegate?

* writefln = 5; This should just not be valid code. But it is.

* Real Properties have many advantages over what looks like D's ad-hoc
solution. They automatically document themselves as properties both to the
programmer and to IDE's (see some other posts from today). The programmer
may use them to overload certain operators and mutator functions that would
speed up the program. Months ago there was a big thread about Real
Properties. I myself offered a suggestion for their design. I don't
remember if you ever responded.

That's just a few reasons right there. D's properties lack elegance and they
lack potential.


PS: I don't mean to gang up on you. You're just not making yourself clear on
where you stand on these points and why.

-- 
Michiel Helvensteijn



Re: What makes D, D?

2009-07-24 Thread Michiel Helvensteijn
Dimitar Kolev wrote:

 Now why would someone want to make their own compiler instead of helping
 develop this one is something I do not really understand.

There may be several reasons. Most important is that Walter owns the
original compiler, and only he can decide what goes in and what goes out.
So if you and he disagree, all you can do is start a fork.

 Also what is the deal with Tango, why make another library instead of
 extending the existing one?

Same reason.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-24 Thread Michiel Helvensteijn
Walter Bright wrote:

 That's just a few reasons right there. D's properties lack elegance and
 they lack potential.
 
 Let's start with:
 1. What is a property?
 2. How is that different from, say, a pure function?

I agree with Bill's reply to this one.

Again it appears you're avoiding those specific issues I mentioned. Quite
blatantly, I might add. Many people have been asking you the same thing. Do
you not have a answer?

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
 sensibly interact with operator overloading I have no idea.

See my comments above about lazy parameter evaluation. I suggest that those
operators are defined with a lazy second parameter for bools, and
programmers should be allowed to overload them for other types as they
please.

 I know of no language that allows overloading  and ||.

C++ does. ! too.

 * Tuples (no dedicated syntax, no parallel assignment, no non-flattening
 tuples without workarounds, no returning tuples)
 
 The flattening thing is a problem. The rest can be done with better
 library support.

You cannot get a dedicated syntax with library support.

I've mentioned I'm working on a programming language myself. I haven't
mentioned its name here, because I didn't think it'd be appropriate. But
with your permission I can post a link to a page describing my tuples.

 * Unit testing (not at compile time,
 
 You can do testing at compile time with static asserts.

Not unit testing, surely.

   not possible to categorize)
 
 I agree that D's built-in unit testing is basic. But the fact that it
 exists *at all* is a huge improvement for a programming language. I
 firmly believe that its mere existence has been a big factor in
 improving the general quality of D code.

Perhaps. But all these available but underpowered features make D look like
a playground rather than a serious language. It's as if you think of a new
feature, try it out for a week, then abandon it (I know, I'm exaggerating).

 The fact that you want more from unit testing is great. Unit testing has
 raised the bar of expectations on a language, and in that it's a home run.

The fact that I want more, but you can't provide it, is a home run? :-)

 I maintain that D suffers greatly from its lack of a formal
 specification.
 
 Perhaps, but remember that most languages don't get formal specs until
 long after they become popular. Consider that C++ was defined by cfront
 for the first 10 or 12 years of its existence.

That was then, this is now. In the now, we have a C++ with classes and
templates and a very strict standards committee overseeing its
specification. You want to know why people in the now choose C++ over D?
This is one reason.

 Not only does the D specification feel really
 unstable,
 
 I admit I'm not good at writing language lawyer text. But the D1 spec
 isn't unstable. The feature set is set, it's pretty clear

Yes, but 'pretty clear' does not a spec make. I refer you to our earlier
divide/modulo discussion. You expect programmers that want details to look
at the DMD source code?

And when you change a formal specification, people at least know the
language changes as a result. When you change the compiler, we don't know
if the language has changed or not.

I know that most people can distinguish between a bug and a feature. But
when you want to play with the big boys, you need to make it unambiguous.

 Much of D's improvements appear to be small, but the aggregate is large
 enough that once you write a project in D, you'll find it pretty hard to
 go back to another language.

I don't dispute that most changes D has made to C++ are good, and that the
result is greater than the sum of its parts. And if it weren't for all my
other complaints, this one would not be enough to keep me from D.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
Nick Sabalausky wrote:

 Not apt-get easy of course,

Linux Gentoo does have DMD in portage, by the way. apt-get easy. Or, to be
more precise, emerge easy.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 So the solution in D would then be to always use struct? No, because
 value semantics seems to come at the price of inheritance. Why? C++ seems
 to handle inheritance in value types just fine.
 
 I think C++ does not handle inheritance in value types all that well, in
 fact the way it deals with the collision is pretty gruesome. It's all
 dark corners and dangers and caveats and puzzling behavior.

Walter said something similar. I'm curious, which collision are you
referring to? Which dark corners and dangers and caveats and puzzling
behavior?

Can you explain? Or perhaps refer me to a web location that explains?

Thanks.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 The issues are discussed in the book C++ Coding Standards and also in
 More Effective C++. Part of the problem is slicing, which you may want
 to google for.

I'm aware of slicing. I didn't really think of it as a problem. But now that
you mention it, I suppose it can be confusing. And perhaps violate class
invariants.

There may be a solution. What I'm thinking now is that in the background,
the heap may be used, as long as this is transparent to the programmer.
i.e. assignment still makes a copy, comparison still compares the objects,
not the addresses. But a base class value variable still has a superclass
object in the background.

This requires some thinking. Thanks for the clarification.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
 can't recall ever seeing anyone use it, though. Until there's a
 compelling use case for it, not just it being a nice idea, I'll stick
 with my belief it's a bad idea.

I don't know a compelling use-case either. But that doesn't mean there isn't
any. Nor are there any real dangers. Arbitrarily restricting the
possibilities of D doesn't seem like the right way to go.

 You cannot get a dedicated syntax with library support.
 
 Of course that's true, but why is a dedicated syntax better than Tuple!(
 ...) ?

See my link just below. If tuples are available in the core language just
like that, people will feel much more comfortable using them in any
situation.

 I've mentioned I'm working on a programming language myself. I haven't
 mentioned its name here, because I didn't think it'd be appropriate. But
 with your permission I can post a link to a page describing my tuples.
 
 Sure.

http://code.google.com/p/mist/wiki/Tuples

 You can use static asserts to, at compile time, check the result of any
 computation, including function calls, that the compiler is able to
 execute at compile time. It sounds perfectly usable as unit tests to me,
 and in fact I do use static assert that way.

Can you allocate stuff on the heap? If not, you can't do proper unit testing
at compile-time.

Perhaps I should have said that the unit-tests should be run automatically
just after compilation and they should not be part of the program
executable. They don't actually need to run 'at compile-time'.

 Yes, but 'pretty clear' does not a spec make. I refer you to our earlier
 divide/modulo discussion.
 
 We're going to fix the modulo thing. But the C++ standard leaves it
 implementation defined. How is that better?

It's not. And you understand that the modulo thing is only a symptom, right?
I've found another mistake by accident just today. See the issue report I
filed.

 Sure, the D spec has gaps in it. But the C++ standard also has large
 gaps of uselessness in it.

I agree. But at least you can count on C++ to do as specified. Where it
doesn't give any guarantees, it specifies that also. With D it's mostly
guesswork and experimentation.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
Lutger wrote:

 There have been a lot of discussions on this topic in the past but I can't
 recall any conclusions. Perhaps some brave soul would dare to write a DIP
 on properties?

Property DIPs have been offered in the newsgroup in the past, only before
they were called DIPs. I also offered a possible design:

http://www.digitalmars.com/webnews/newsgroups.php?art_group=digitalmars.Darticle_id=81759

Feel free to modify and/or DIPify it.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
Bill Baxter wrote:

 
 I've always thought properties should work somewhat like this:
 
 property int length {
 get() { return this.len; }
 set(newLen) { this.len = newLen; }
 }
 
 
 I'm curious.  Is it just a coincidence that how you've always
 thought happens to look a lot like C# properties?   Or did you mean
 to say Ever since I saw how C# does properties I've thought?

Nope. Never used C#, never seen it. I just think about language design a
lot, and this is what I came up with. From that newsgroup thread, it seems
that they are still quite different from C# properties.

 In any event I think a problem with this is that for D's simple
 grammar to remain simple and context free, get and set would both have
 to be made keywords in the language.

I don't think so. They can just be identifiers with special meaning. If you
look a bit further down the thread, I suggest adding the 'auto' keyword
where the missing types are now. Perhaps that helps.

In fact, in the design of my own language, those names have special meaning
for all types:

get(x) (or x.get()) returns x itself.

set(x, v) (or x.get(v)) assigns v to x.

If you specify them in a property, you're just overriding their meaning for
the underlying type of the property, just like you can override other
member-functions. Another upside is that you can always count on these
functions existing for every type and you can pass them around as
functions/delegates.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
Michiel Helvensteijn wrote:

 set(x, v) (or x.get(v)) assigns v to x.

Small correction: x.set(v)

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-23 Thread Michiel Helvensteijn
Eldar Insafutdinov wrote:

 from your post:
 
 property int length {
 get() { return this.len; }
 set(newLen) { this.len = newLen; }
 void opIncrement() { this.len++; }
 }
 
 I don't think that's flexible to overload every operator to get the best
 performance. As Walter likes to say the best way should be the most
 obvious. Besides we forgot that D2 allows to return references, which
 eliminates the issue.

If your property really just hides a private member variable, it was
probably for encapsulation purposes or because you want redundant actions
to be taken for every access. If you return a reference, you give unlimited
and unrestricted access to that variable with only one call, and you might
as well not have used a property at all.

If your property is derived -- that is, if it doesn't directly mirror a
variable --, there is no reference to return.

Besides, in D, you can probably use mixins to copy the entire interface of a
type into the property without code duplication.

-- 
Michiel Helvensteijn



Re: Comma expressions must die [Was: Reddit: why aren't people using D?]

2009-07-23 Thread Michiel Helvensteijn
Adam D. Ruppe wrote:

 It might be my years of C bias, but the naked tuples just look wrong.

There are ways -- elegant ways, I believe -- to make it work.

Would you look at this page and give me your opinion?

http://code.google.com/p/mist/wiki/Tuples

I'm not sure if it can ever work for D, to be honest. There may be too many
differences between the two languages.

-- 
Michiel Helvensteijn



Re: Comma expressions must die [Was: Reddit: why aren't people using D?]

2009-07-23 Thread Michiel Helvensteijn
Adam D. Ruppe wrote:

 By keeping the tuple word there, it is no longer conflicting with my C
 expectations, but seems to be just as useful as your proposal.

Hm. Then I believe you haven't read the whole thing. (That's ok, it does go
on for a while.) Yes, much of the appeal is in the shorter syntax. But some
of the features proposed even require that no 'tuple' keyword is used.

Looking like C is not the be-all and end-all of programming languages. Mist
tries to follow mathematical notation wherever possible. This has had other
implications, like using - for assignment and = for equality.

-- 
Michiel Helvensteijn



Re: (Non) Nesting block comments

2009-07-22 Thread Michiel Helvensteijn
yigal chripun wrote:

 IMHO, this is an ugly trick. it's less readable IMO and it just saves a
 cuple keystrokes. readability is more important than that. more over, this
 is completely unneeded (unless you program in notepad) since even the
 simplest of the (programmer) text editors has a shortcut to
 comment/uncomment a block of code. For instance, in Eclipse it's
 Ctrl+Shift+/

The point is not the amount of keystrokes. The point is that such a
construction is automatic documentation of the fact that either the one or
the other piece of code should be activated by the programmer (probably for
debugging). Of course, you can pretty it up a little:

//*///
A
/*
B
//*///

But if you make this a convention in a project, every programmer will
immediately understand. The fact that it takes only one keystroke to make
the change is what gives the constructions its affordance.

-- 
Michiel Helvensteijn



Re: Reddit: why aren't people using D?

2009-07-22 Thread Michiel Helvensteijn
Here's the opinion of an 'outsider'. I've experimented a bit with D in the
past (years ago), but have lately just followed the newsgroup out of
general interest.

I respect the expertise and hard work of the D team, but I won't use D. And
here's an incomplete list of my reasons. I imagine there are other
programmers who share my views. Most of these issues, if not all, are well
known here. But I'll mention them anyway.

Please forgive (and correct) any factual mistakes. I'm sure there will be
some. If you reply to any point in the list, I'll be glad to elaborate.

D offers too many ways to do the same thing:

* const, enum, immutable, invariant
* structs, classes
* functions, delegates, lazy parameter evaluation
* garbage collection, manual D memory management, manual C memory management

Even with so many ways to ensure const correctness, it is still possible to
cast constness away, either making it impossible for the compiler to make
any assumptions regarding constness, or making it very dangerous to do the
cast.

D offers some cool features, but leaves them very underpowered:

* Contract programming (no contract inheritance, no compile-time static
analysis, no loop invariants / ranking functions)
* Class/Struct properties (no control over their use by class designer, no
way to use +=, -=, no global properties, no parameterized properties)
* Operator overloading (no fine control over comparison operators, fixed
commutativity, confusing rule priority to determine translation, no
overloading of !, , ||, =)
* Tuples (no dedicated syntax, no parallel assignment, no non-flattening
tuples without workarounds, no returning tuples)
* Unit testing (not at compile time, not possible to categorize)

There are two competing standard libraries for D. This has been discussed to
death and I won't go further into it. But it's a bad thing.

I maintain that D suffers greatly from its lack of a formal specification.
It is silly for a language as old and relatively popular as D to use a
compiler written by a small group of people (1 person?) as the official
reference to the language. Not only does the D specification feel really
unstable, it has a very low bus-factor. In other words: if, hypothetically,
Walter were hit by a bus, would the D language survive?

D just doesn't offer enough improvements over C++ to make it worthwhile
switching over. Its design is not very adventurous, keeping simply too
close to that of the C family, making it look like Yet Another C Language.
I believe simply filling in the gaps of C++ wasn't enough to take over the
world. There should have been a greater change.

-- 
Michiel Helvensteijn



Re: (Non) Nesting block comments

2009-07-21 Thread Michiel Helvensteijn
Robert Jacques wrote:

 Well /* */ are excellent for toggling code sections. I tend to use
 constructs such as // */ or  //* or /*/ which allows me to turn on of off
 blocks with often a single key stroke. Using /+ +/ means I have to Add
 /++/ and remove /++/ each time I want to activate or deactivate a code
 block.

Why? I believe that /++/ works exactly like /**/ in that regard. Doesn't it?

//+
code that can be turned off by removing the first /
//+/

-- 
Michiel Helvensteijn



Re: (Non) Nesting block comments

2009-07-21 Thread Michiel Helvensteijn
Michel Fortin wrote:

 /*
 A
 /*/
 B
 /**/
 
 With this, you compile B while A is in a comment. Add / at the start
 of the first line and you compile code A while B is now in commented
 out.

Aha. Interesting construction. I like it. No, you couldn't do that with
nesting comments. I do wonder how often it comes up.

-- 
Michiel Helvensteijn



Re: Casts and conversions done right

2009-07-20 Thread Michiel Helvensteijn
Lars T. Kyllingstad wrote:

int i = to!int(pi);// The to function already exists in std.conv

But what does the to function do, exactly? I'd prefer to use one of floor,
round or ceil. Wouldn't you? I'm sure they are available as well.

-- 
Michiel Helvensteijn



(Non) Nesting block comments

2009-07-20 Thread Michiel Helvensteijn
D has the old C style block comments that start with /* and end with the
first possible */. But it also has nesting block comments, starting with /+
and ending with the *matching* +/.

The nesting block comments were a great idea, since they can be used
to 'comment out' any block of code, even if other block comments are
already present.

I was wondering, though. C++ compatibility aside, is there an actual use
case for the C style block comments anymore? Has anyone here written some
code lately where they thought: I really need a comment here containing /+
or +/ without the matching delimiter! Thank deity for C style comments!

(Yes, this is bikeshed stuff, and I don't really care. I like programming
language syntax discussions. Sometimes they are low barrier discussions.)

-- 
Michiel Helvensteijn



Re: (Non) Nesting block comments

2009-07-20 Thread Michiel Helvensteijn
bearophile wrote:

 I was wondering, though. C++ compatibility aside, is there an actual use
 case for the C style block comments anymore?
 
 C compatibility is an important goal of D, so you can't put it aside.

Of course. It was mostly theoretical. It may be generally interesting.

 (Time ago I have suggested the opposite, to make the /* */ nestable and
 remove /+ +/, but this idea was not appreciated by D devs.)

I can understand that. It would break compatibility:

/* /* */ (here be code in C, comment in D)

-- 
Michiel Helvensteijn



Re: Random Suggestion: Swap Operator =?

2009-07-19 Thread Michiel Helvensteijn
Simen Kjaeraas wrote:

 I have a swap operator in my new programming language:

 x - y;

 It's syntactically consistent with the assignment operator:

 x - E;
 
 Clearly, this should be generalized to allow both right-to-left and
 left-to-right assignment. :p

I thought about that. Of course it has a certain symmetry. But having two
different syntaxes for standard assignment isn't right.

And right-to-left has its advantages. You can see at a glance which variable
is going to change value.

-- 
Michiel Helvensteijn



Re: Random Suggestion: Swap Operator =?

2009-07-17 Thread Michiel Helvensteijn
Julian Salazar wrote:

 I'm wondering, who here would use a swap operator if it were available?

I have a swap operator in my new programming language:

x - y;

It's syntactically consistent with the assignment operator:

x - E;

The swap operator is really syntactic sugar for the swap function, which can
be overloaded and templated to your hearts desire (as long as each template
type can be automatically deduced by the actual parameters).

So yeah, I'd use it.

-- 
Michiel Helvensteijn



Re: Random Suggestion: Swap Operator =?

2009-07-17 Thread Michiel Helvensteijn
Leandro Lucarella wrote:

 A more general solution is supporting tuples in the language, then you can
 do something like:
 a, b = b, a;

That's a great feature. But even if it's available, I'd use swap, because:

* I wouldn't have to mention each variable twice
* It would use move-operations rather than copy operations

Parallel assignment is still useful for other stuff, like traversing the
fibonachi sequence with two variables :-)

(a, b) - (b, a + b);

-- 
Michiel Helvensteijn



Re: cast(public)

2009-07-17 Thread Michiel Helvensteijn
dsimcha wrote:

 Could we put a feature in the language that allows private member
 variables to
 be cast to public?  The idea is that, if a class/struct designer makes
 something private, they're saying it's a bad idea to mess with it, and
 that
 you do so at your own risk.  However, I think there needs to be a back
 door to cowboy this one

In general don't believe this is a good idea. Calling private functions and
accessing private variables may violate the class invariant. That's why it
should only be done by member functions, which are bound to maintain that
invariant.

If there was such a back door, a class invariant would mean nothing. Neither
the compiler nor the programmer could ever depend upon it.

However, since D is a systems programming language, which can already cast
away constness and such, it might fit.

-- 
Michiel Helvensteijn



Re: modulus redux

2009-07-13 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 The  multiplicative expressions  are multiplication  (\ccbox{a  * b}),
 division  (\ccbox{a  / b}),  and  remainder  (\ccbox{a  \% b}).   They
 operate  on numeric types  only. The  result type  of either  of these
 operations   is  same  as   the  type   of  \ccbox{true   ?  a   :  b}
 (see~\S~\ref{sec:conditional-operator}).

either of means one of two or both of two. You're talking about three
operations, so I'd leave out either of.

Also, while the (true ? a : b) thing may be true, is this really the
clearest way to explain? Perhaps you should define a term to mean common
type of two operands and use that to explain both typeof(a mulop b) and
typeof(true ? a : b).

 ...
 
 If such  a number  cannot be found,  \ccbox{a \%  b} yields the  Not A
 Number (NaN) special value.

When is this? If b == 0? If b == NaN? Perhaps it would be better to be
precise.

-- 
Michiel Helvensteijn



Re: Oh Dear

2009-07-12 Thread Michiel Helvensteijn
Walter Bright wrote:

 I agree with you that it should be better. I just don't agree with it
 being a showstopper.

You know that the D Wikipedia article states: The official compiler by
Walter Bright defines the language itself.?

In other words, every bug in DMD is really a feature of the language. Until
you fix it. That kind of permanent instability may be part of the reason
people have been so negative around here lately.

 I invite you to contribute spec corrections to the examples you pointed
 out.

I will file those corrections. However, the MulExpression thing was only an
example. The first one I checked, too. The mentality behind compiler
first, specification later just seems wrong to me. And that's not
something I can report to bugzilla (or can I).

By the way, what kind of integer division *does* D use?

-- 
Michiel Helvensteijn



Re: Oh Dear

2009-07-12 Thread Michiel Helvensteijn
Walter Bright wrote:

 In other words, every bug in DMD is really a feature of the language.
 Until you fix it. That kind of permanent instability may be part of the
 reason people have been so negative around here lately.
 
 I don't agree with that characterization. Bugs get reported to bugzilla,
 and get fixed in a regular cycle.

Sure they do. But if it's really true that the DMD implementation *is* the D
language specification, any bug in DMD would also be part of that
specification. And as the compiler changes, so does the spec. It's the
danger of that approach.

 I will file those corrections.
 
 Thank you, I look forward to it.

Issue 3165, Issue 3166.

 By the way, what kind of integer division *does* D use?
 
 To be frank, it is what the x86 DIV instruction does.

After a quick Google search, it would seem DIV is the x86 unsigned divide
instruction. Are you sure you aren't using IDIV (signed divide) for
negative operands? If not, you'd actually be interpreting 2's complement
signed ints as unsigned ints. (And surely such a thing would have been
noticed before now?)

 But I agree that 
 the modulus should be defined, regardless of whether that makes it less
 efficient on some machines.

Good. Make sure that your divide operation and your modulo operation are
consistent. The following identity should hold:

if  a / n = q
and a % n = r

a = q*n + r

-- 
Michiel Helvensteijn



Re: Oh Dear

2009-07-12 Thread Michiel Helvensteijn
Rainer Deyke wrote:

 Actually I suspect that integer division with negative values is rare
 enough that a problem might escape notice for some time.

Yep. It's possible. I suggest someone tests this. I don't have a D compiler
installed, and I don't really have time for this.

 floor division, which is 99% of the time the type of division I want.

Agreed. I'm using floored division in my new programming language. The
quotient rounds towards negative infinity and the result of the mod
operation has the same sign as the divisor.

However, it seems D prides itself on its speed. And since truncated division
is implemented by the hardware, D will probably use that. And that's
acceptable, as long as it's guaranteed (predictable).

-- 
Michiel Helvensteijn



Re: Oh Dear

2009-07-12 Thread Michiel Helvensteijn
Walter Bright wrote:

 I don't have a D compiler
 installed, and I don't really have time for this.
 
 Thanks to Ary, there's now a one click installer for Windows:
 
 http://ftp.digitalmars.com/dinstaller.exe

That's nice. But I run Linux.

Walter, surely this test shouldn't take more than a minute for you (or
anyone else with a D compiler installed). Just see what DMD outputs for:

  8  /   3
  8  / (-3)
(-8) /   3
(-8) / (-3)
  8  %   3
  8  % (-3)
(-8) %   3
(-8) % (-3)

If D uses DIV instead if IDIV, this should be immediately visible. In any
case, we will see exactly what kind of division and modulo D uses. You can
compare with the table on the bottom of page 3 of:

http://www.cs.uu.nl/~daan/download/papers/divmodnote.pdf

That's an informative article, by the way.

-- 
Michiel Helvensteijn



Re: Oh Dear

2009-07-12 Thread Michiel Helvensteijn
Michiel Helvensteijn wrote:

 Walter, surely this test shouldn't take more than a minute for you (or
 anyone else with a D compiler installed).

Ok, ok. I'll do it. Here's the results:

--
import std.stdio;

int main() {
writefln(8/3);
writefln(8/(-3));
writefln((-8)/3);
writefln((-8)/(-3));
writefln(8%3);
writefln(8%(-3));
writefln((-8)%3);
writefln((-8)%(-3));

return 0;
}
--

outputs the following

--
2
-2
-2
2
2
2
-2
-2
--

So DMD uses truncated division. The quotient rounds towards zero and the
remainder has the same sign as the dividend. I've updated issue 3165 with
this information.

Hope that helps.

-- 
Michiel Helvensteijn



Re: Oh Dear

2009-07-12 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 Thanks, Michiel. Here's what I have in TDPL. Is it 100% in sync with you?
 
 ===
 ...
 
 i...@b@  is  zero in  \ccbox{a  /  b} or  \ccbox{a  \%  b}, a  hardware
 exception   is  thrown.    The  sign\footnote{Sign,   not  signedness,
 i.e.,~the sign of  the actual value.}  of \ccbox{a  \% b} is always
 the same as  the sign o...@a@.  That is, \ccbox{a \%  b} is the closest
 number to  zero of the same sign  ...@a@

Now that I read it again (the last words there), this is not completely
accurate. I know I made the same mistake myself just now, but the remainder
has not necessarily the same sign as 'a', since it may be zero, which is
signless.

Of course, such a triviality won't hinder anyone's understanding, but you
may as well be accurate, no?

Some thing like same sign a...@a@ (or zero), perhaps? (Also note the
word 'as' instead of 'of', which is not strictly grammatically correct.)

 that must be  added t...@a@ to 
 make it divisible b...@b@.  For  example, \ccbox{-5 \% 2} and \ccbox{-5
 \% -2} both yield~\cc{-1}.

The rest of the information is accurate, but you still neglect to mention
the type of division. D uses truncated division. The quotient rounds
towards zero. In other words, it cuts off the fractional part of the
result.

Good luck with your book.

-- 
Michiel Helvensteijn



Re: Oh Dear

2009-07-12 Thread Michiel Helvensteijn
Andrei Alexandrescu wrote:

 \dee\ also defines modulus for  floating-point numbers in the same way
 as the  IEEE~754  standard.  When  at least one  of @a@  and @b@  is a
 floating-point value in \cc{a \%  b}, the result is the floating-point
 number @r@ satisfying the relation \cc{a = b * n + r}, where @n@ is an
 integer\footnote{``integer'' in  the mathematical sense  here} and @r@
 is a positive number less than @b@'s absolute value.

Oh, about this part. I left it out because it's not about integer division,
but while I'm at it anyway.

I believe you wanted the word non-negative there, instead of positive.
However, I just ran the following test:


writefln(5.0%2.0);
writefln(5.0%(-2.0));
writefln((-5.0)%2.0);
writefln((-5.0)%(-2.0));


it outputs:

--
1
1
-1
-1
--

So the remainder can still become negative, it seems. Same as with integer
modulo. I would expect this consistency, but your paragraph there says
something different.

-- 
Michiel Helvensteijn




Re: Oh Dear

2009-07-12 Thread Michiel Helvensteijn
Walter Bright wrote:

 I'd like to emphasize that the code generator has been in
 use for 25 years for several hundred thousand users, and it is
 incredibly unlikely that nobody would notice if it is getting basic
 integer arithmetic wrong.

I didn't think the compiler would be wrong. I was just replying to your
statement that D does what x86 DIV does (you didn't mention IDIV; hence my
initial confusion).

 If you'd like to write up a formal definition 
 that can be inserted into the D specification, that would be great.

I've given an unambiguous description of D division and modulus in another
subthread here. I've also updated issue 3165 with the information. You can
use that.

-- 
Michiel Helvensteijn



Re: Oh Dear

2009-07-11 Thread Michiel Helvensteijn
Michiel Helvensteijn wrote:

 What does chopped to fit the integral type mean? What if it's a
 multiplication between two differently sized integral types?

I'm sorry. I missed the first sentence of that section, which explains this
part of it nicely:

--
They undergo integral promotions, and then are brought to a common type
using the usual arithmetic conversions.
--

But the rest of my example stands.

-- 
Michiel Helvensteijn



  1   2   >