Re: Consistency, Templates, Constructors, and D3

2012-08-27 Thread Chris Nicholson-Sauls
Before we go proposing something like replacing 'new Foo( val )' 
with 'Foo.new( val )' ... which is just so Ruby-esque, but that's 
okay with me ... we need to consider that 'new' is not used only 
for classes.  Okay, so presumably structs would work the same 
way, but what of, say, arrays?  What would be the equivalent of 
'new int[][]( 5, 10 )' given such a change?


As it stands, 'new' behaves like an operator (behaves like, but 
is really a grammar artifact) and so is consistent with 
intuition.  How would we make something like 'int[][].new( 5, 10 
)' make sense *without* having to provide a function (presumably 
through UFCS) for each arity?  And, given the design of D arrays, 
what would such a function even look like?


Re: Trouble creating a formatted assert wrapper

2012-09-03 Thread Chris Nicholson-Sauls
On Sunday, 2 September 2012 at 23:40:01 UTC, Peter Alexander 
wrote:


Consider:

myAssert(false, "%d", 1);

What is Args? "%d", 1 could refer to the optional arguments, or 
the variadic arguments. Both match.


Easy: the variadic arguments are not, themselves, optional.  
Match the variadic.  This kind of problem is already solved in 
every language with "scattering" assignments, and other such 
features.


Re: Trouble creating a formatted assert wrapper

2012-09-03 Thread Chris Nicholson-Sauls
On Monday, 3 September 2012 at 09:24:42 UTC, Peter Alexander 
wrote:
On Monday, 3 September 2012 at 09:15:08 UTC, Chris 
Nicholson-Sauls wrote:
On Sunday, 2 September 2012 at 23:40:01 UTC, Peter Alexander 
wrote:


Consider:

myAssert(false, "%d", 1);

What is Args? "%d", 1 could refer to the optional arguments, 
or the variadic arguments. Both match.


Easy: the variadic arguments are not, themselves, optional.  
Match the variadic.  This kind of problem is already solved in 
every language with "scattering" assignments, and other such 
features.


The variadic arguments are optional, as you can have zero 
arguments count as variadic.


Also, how can I override the optional arguments in this 
function if all arguments are matched as variadic?


They are not really optional.  That the language fails to enforce 
this (or provide an eforcement, rather) is a shortcoming.  
Pretending for a moment that D supports one of two things:


1) Empty array stands in for empty variadic.  Then, given 
arguments like func(R, V..., O=D) you would call it with 
func(foo, [], bar).  Since a typesafe variadic is effectively a 
sugar-laden array (well a tuple really), I see no reason this 
shouldn't be feasible.  First-class tuples would likely be even 
better.


2) Named parameters.  Then it's func(foo, O: bar), and the 
variadic argument can indeed be optional, although the meaning is 
no different than in (1).


In reality, though, we have neither of these things.  Even so, 
how often does this actually arise in practice (never has for 
me)?  And given the OP's specific case (__FILE__ and __LINE__ 
params) I don't foresee any useful case for overriding the 
defaults.


Honestly, I sometimes think that the special treatment of 
__FILE__ and __LINE__ when used as defaults was not the best way 
to go.  It might've been better implemented as hidden params, 
only generated by the compiler when actually used in the body.




Re: Trouble creating a formatted assert wrapper

2012-09-03 Thread Chris Nicholson-Sauls
On Monday, 3 September 2012 at 11:17:39 UTC, Chris 
Nicholson-Sauls wrote:

1) Empty array stands in for empty variadic. [snip]

In reality, though, we have neither of these things. [snip]


Turns out, I was quite wrong, and I'm happy to be.  Empty array 
is accepted for typesafe variadics just fine ... I'm not sure now 
why I thought otherwise.


Of course, our tangent is really sort of moot, since the brackets 
would be required for any pattern with a suffix matching the 
optional arguments anyhow, at which point there's little point in 
having the variadic argument.  I reiterate my impression that 
magical __FILE__ and __LINE__ should be provided by some other 
means.


Re: Trouble creating a formatted assert wrapper

2012-09-04 Thread Chris Nicholson-Sauls

On Tuesday, 4 September 2012 at 09:24:26 UTC, Don Clugston wrote:

On 03/09/12 23:48, Chris Nicholson-Sauls wrote:

I reiterate my impression that magical __FILE__ and
__LINE__ should be provided by some other means.


It was a special-case hack to fix a special-case need. It was 
extremely easy to implement (about 2 hours work) and has been 
very successful in fixing that need. Everything else that 
anyone has talked about is at least ten times as complicated, 
and doesn't seem to offer significant advantages.


It's really easy to come up with over-engineered solutions to 
these sorts of things.


How difficult would hidden params, triggered by usage, be?  Ie: 
my function makes use of __CALL_FILE and __CALL_LINE variables by 
name, therefore they are tacked on  (as const, presumably) and 
always passed, thanks to diabolic compiler sorcery.  The current 
solution is fine in a majority of cases, at least so far, but 
there are going to be moments like what the OP had, and these 
moments are discouraging especially to newcomers.


I won't pretend to know if it would be easy or not; you're a heck 
of a lot more familiar with the compiler's code than I am.  But 
it certainly seems straightforward.


Re: scope for array parameters

2012-09-05 Thread Chris Nicholson-Sauls

On Wednesday, 5 September 2012 at 12:05:40 UTC, Timon Gehr wrote:


TDPL does not prescribe this.



Truth; I just checked this and indeed TDPL only mentions 
@property functions disavowing themselves of parentheses.  
Although I've always had the distinct impression that strict 
property syntax was the intended future, and the current 
situation was just due to inheriting D1's clumsier 'property' 
concept.  I don't even mind all those "ugly" parens in UFCS 
chains, but I'm kinda crazy like that.


Re: Trouble creating a formatted assert wrapper

2012-09-05 Thread Chris Nicholson-Sauls

On Tuesday, 4 September 2012 at 11:28:23 UTC, Don Clugston wrote:
I don't know how that could be done. You need to know the 
function signature whenever you call the function. If you make 
the signature dependent on the function body, it cannot work 
unless you have the source code of the function. The compiler 
is able to add hidden variables for things like 'this' because 
it can work out if it is required just by looking at the types 
involved in the function declaration. But in this case, it 
can't get it from the signature.


The default argument method we are currently using is a nice 
trick, because even though default arguments aren't part of the 
function type, the compiler still sees them in the function 
signature, so it knows to do a bit of magic.


It's also easy to get nasty forward reference errors when you 
do that sort of thing.




Fair enough; I hadn't considered the case of having only the 
signature to go by.  Maybe an @attribute for it?  ;)  Okay okay, 
I give.  For now there's making file/line template params, which 
is fine for something like a custom assertion meant for debug 
builds, although horrid for release builds.


Re: Would like to see ref and out required for function calls

2012-09-08 Thread Chris Nicholson-Sauls

Given:

void func (ref int[], int)

If ref/out were required at the call site, this destroys UFCS.

int[] array;
array.func(0); // error, ref not specified by caller

Or would one expect something like:

(ref array).func(0);

...put simply, I hope not.

This suggestion has come up a couple times before, and each time 
failed to gain traction.  I wouldn't mind it as an option -- 
possibly even as a recommendation in most library code -- but as 
a requirement it honestly just gives me a headache.  Generally 
speaking, if a parameter being ref/out is surprising, there is 
something wrong with the design.  (There are times it is 
non-obvious in otherwise good code, this seems uncommon.)


For example, calling one of the *InPlace functions from Phobos, I 
immediately expect 'ref' -- otherwise, how to modify "in place" 
in a reliable (ie, non-allocating) manner?  Likewise, 'out' -- 
used pretty rarely in the first place -- sits in the same place 
pointers typically do, as auxiliary returns.  The category of 
functions/methods which use them is pretty self consistent.  
(What few corner cases remain would be better served by cleaning 
up tuples to make them more sane as return values.)


Given:

bool checkedEmitJ (Op, Params, ref const(Scope), Address, out 
Address)


I really don't want to have to call it as:

auto handled = checkedEmitJ(Op.CJmp, parms, ref _scope, suggest, 
out lval);


When the 'ref' and 'out' parameters listed are specified by the 
design and consistent across all the "-emit-" functions.


Re: [OT] Was: totally satisfied :D

2012-09-18 Thread Chris Nicholson-Sauls
On Tuesday, 18 September 2012 at 08:27:31 UTC, Nick Sabalausky 
wrote:
Regarding HDDs, I've sworn I will *never* run a main system 
again

without a GOOD always-on SMART monitor like Hard Disk Sentinel
. In fact, that's one of the main 
reasons I
haven't switched my primary OS from Win to Linux yet, because I 
can't

find a good Linux SMART monitor. (Manually running a CLI program
- or writing a script to do it - doesn't even remotely count.) 
Oooh!
Actually, now that I've looked up that link, it looks like they 
do
have an early Linux version now. Awesome, I'm gonna have to try 
that

out.


I do believe conky can provide SMART monitoring.
http://conky.sourceforge.net/

Although periodically running GSmartCtl (GUI front-end to the 
command line tool) isn't a bad idea, either, to see the specific 
details (spin-ups, heat stress, etc) and/or execute the drive's 
self-test.


Re: Import improvement

2012-10-15 Thread Chris Nicholson-Sauls
On Monday, 15 October 2012 at 15:37:06 UTC, Andrei Alexandrescu 
wrote:
I don't think imports from a specific package have been 
considered.


In my personal opinion, imports are a necessary evil and it's 
sort of a bummer that the most accessible place in any source 
file - the top lines - is occupied by the crappy legal 
disclaimer (which, after having talked to a lawyer, I always 
put at the bottom since being at the top is not a requirement), 
and the litany of imports that the module is using. I'd make 
all imports local or put them at the bottom of the file if it 
weren't too much of a shock to others.


Three remarks on this particular problem.

1. I expect large packages to introduce a module "all.di" or 
"_.di" to publicly import everything in the package. That could 
help some use cases.


It is a common practice (usually all.di) but perhaps it could 
help to establish an official convention.  Nothing in the 
language, just the styleguide.  (I know this has already come up 
and been discussed.)


2. The import declaration accepts a list of modules, and 
several may be on one line. I think that's a significant 
positive difference from C, C++, or Go, all of which force one 
imported module per line. I always advocate imports from the 
same package in the same "import" declaration, ordered 
alphabetically:


import fuji.filesystem, fuji.font, fuji.material, fuji.matrix,
fuji.primitive, fuji.render, fuji.system;
import std.algorithm, std.conv, std.random, std.string, std.xml;
...

That makes the existing system much more palatable.


I've done this very thing for eons, and yes you are quite right!  
(Although my formatting is different, but I digress.)  That said, 
I think the OP still has a valid, even quite strong point.  
Consider, in comparison to your sample:


import fuji.( filesystem, font, material, matrix, primitive, 
render, system );

import std.( algorithm, conv, random, string, xml );

Certainly less visual noise.  An even *better* level of 
improvement comes if we provide an alternate and similar syntax 
for selective imports, so that they no longer have to be 
separated.


import std.( algorithm, conv, random, xml,
stdio:( write, writef, writefln ),
string:( munch, splitLines, xformat, xsformat )
);

As for implementation, how difficult is it for the compiler to 
internally expand something like this into the traditional litany?


3. I think local imports are currently underutilized. It would 
be interesting to see what kind of project dynamics they enable.


I can agree with this.

-- Chris Nicholson-Sauls



Re: alias A = B; syntax

2012-10-17 Thread Chris Nicholson-Sauls
I would generally be pretty 'meh' on an enhancement like this, if 
not for the umpteen times I've aliased rather complex (read: 
long) types/template-instances and found myself thinking it would 
be nice for the new name to be at the (visually grep'able) 
beginning of the declaration.


Consider simple example:

alias pipe!( readText, splitLines, map!( e => e.splitter( ',' ) 
), array ) readRows;


alias readRows = pipe!( readText, splitLines, map!( e => 
e.splitter( ',' ) ), array );


So ultimately I'm happy to see the change, even if it isn't high 
on the priority list imho.


-- Chris Nicholson-Sauls



Re: Anyone have D protobuf?

2012-10-20 Thread Chris Nicholson-Sauls
On Saturday, 20 October 2012 at 07:28:07 UTC, Nick Sabalausky 
wrote:
Not a big deal, but does anyone have or know of a usable 
up-to-date

protocol buffers implementation for D? All I've found is this:

https://256.makerslocal.org/wiki/index.php/ProtocolBuffer

But it's old, says its status is only "mid-implementation", has 
no

license info, and I think it might be D1.


It has been started at least three times that I know of, but I 
don't think anyone ever finished such a beast (I'm guilty of one 
of those myself).  But in related news, in case it fits what 
you're hoping to do, I've written a binding, and am in the 
process of a wrapper, for zeroMQ: https://github.com/csauls/DZMQ


It is usable in the simplest sense as is; so maybe if you're 
willing to roll your own object<->string conversions, this would 
be a start.


-- Chris Nicholson-Sauls


Re: [OT] ZeroMQ (Was: Anyone have D protobuf?)

2012-10-20 Thread Chris Nicholson-Sauls

On Sunday, 21 October 2012 at 02:34:03 UTC, Matt Soucy wrote:

On 10/20/2012 09:55 PM, 1100110 wrote:
On Sunday, 21 October 2012 at 00:13:30 UTC, Chris 
Nicholson-Sauls

wrote:
On Saturday, 20 October 2012 at 07:28:07 UTC, Nick Sabalausky 
wrote:
Not a big deal, but does anyone have or know of a usable 
up-to-date
protocol buffers implementation for D? All I've found is 
this:


https://256.makerslocal.org/wiki/index.php/ProtocolBuffer

But it's old, says its status is only "mid-implementation", 
has no

license info, and I think it might be D1.


It has been started at least three times that I know of, but 
I don't
think anyone ever finished such a beast (I'm guilty of one of 
those
myself).  But in related news, in case it fits what you're 
hoping to
do, I've written a binding, and am in the process of a 
wrapper, for

zeroMQ: https://github.com/csauls/DZMQ

It is usable in the simplest sense as is; so maybe if you're 
willing
to roll your own object<->string conversions, this would be a 
start.


-- Chris Nicholson-Sauls
Hey man, If it helps you out: steal anything you want from 
these.

I didn't check how far along you were, soo...  yeah.


https://github.com/1100110/CZMQ
https://github.com/1100110/ZeroMQ


I'll definitely look through CZMQ once I get a little further 
with what I already have planned.  Thanks.




Huh. I've also been writing a D wrapper for 0mq. As it is right 
now, though, it's really just OOP wrappers for the Deimos 
bindings, because I figured that it would be easiest. I should 
check out the CZMQ stuff you have and see if any of it is 
something that I would find useful for my projects.


Up until about a week ago, I didn't even know about zeromq.  ;)  
A friend of mine requested that I write this, because the company 
he works for (iostudio.com) might then consider using D for some 
in-house work.  Crossing fingers, for D's sake.  Since I'm 
writing my wrapper as per his request, we might end up with very 
different products.  Competition is a good thing, right?


Researching and working on this leads me to think I'm going to 
want to use zeromq quite a bit myself, going forward.


-- Chris Nicholson-Sauls


Re: [proposal] version statements with multiple arguments.

2012-10-23 Thread Chris Nicholson-Sauls

On Tuesday, 23 October 2012 at 04:32:02 UTC, 1100110 wrote:
On Mon, 22 Oct 2012 22:31:43 -0500, Jesse Phillips 
 wrote:


That is true, and I do recall that version = something; now 
that I think about it.


It just seems to me that version statements are essentially 
booleans, and could be easily rewritten as:
static if(true || false || false) { } by the compiler, similar 
to how (I *think*) certain binary operators are rewritten.
(I'm just going by what I hear, I'm not really a compiler kinda 
guy...)


It would make sense to me to be able to use boolean operators 
on what is essentially

a true/false statement.

I'd be willing to see if I can hack together support for it, as 
a proof of concept,

but I wanted to see if it would be blatantly shot down first.

So... What I'd really like to know is: Would *you* welcome such 
a change?



This proposal has made a quarterly appearance since the earliest 
days of D1... and heavens yes, would I welcome it.  While the 
standard (version = Somethingable) approach is actually fine in 
many cases (self documenting, puts all the logic in one place, 
etc etc) it is also quite overkill in many cases (the logic 
matters exactly once, the logic branches differently in different 
places, etc etc).  It's the same as every toolbox having 
different types of screwdrivers.  Yes they do the same thing, but 
in different circumstances one will be clearly preferable over 
another.


-- Chris Nicholson-Sauls



Re: automatic mixin in classes

2012-10-27 Thread Chris Nicholson-Sauls
On Saturday, 27 October 2012 at 05:39:59 UTC, Gor Gyolchanyan 
wrote:
I've stumbled upon this numerous times and I wish I could 
automate this

somehow.
The idea is to have some mixin templates mixed into classes 
automatically

when they inherit from some base class.
For instance, advanced RTTI methods, which analyze the 
enclosing class at

compile-time.
Unfortunately, AFAIK, there's no way of doing it automatically 
and one
needs to both derive from a certain class and mix in a certain 
mixin

template manually.
Is there a way to avoid the boilerplate and have it done 
automatically?


Does this give you any ideas on how to solve your use cases:
https://github.com/csauls/zeal.d/blob/master/source/zeal/base/controller.d
https://github.com/csauls/zeal.d#controllers
https://github.com/csauls/zeal.d/blob/master/source/zeal/http/router.d#L93

-- Chris Nicholson-Sauls



Re: mixin functions

2012-11-01 Thread Chris Nicholson-Sauls
On Thursday, 1 November 2012 at 15:59:04 UTC, Gor Gyolchanyan 
wrote:

OR, better yet:

mixin MyMixin
{
foreach(i; 0..10)
MyMixin ~= "writeln(" ~ to!string(i); ~ ");\n"'
}

And this could be printed out as a pragma(msg, ...) or into a 
.log file or
anywhere else. This way it's easy to see what did end up being 
mixed in.





Given that template mixins are currently declared as (mixin 
template Foo () {...}), would it make even more sense to extend 
this out to a more literal interpretation of the subject line 
("mixin functions")?  I'm thinking something like this:


mixin string myMixin () {
string res;
foreach ( i ; 0 .. 10 )
res ~= "writeln(" ~ to!string( i ) ~ ");\n";
return res;
}

And later using it as:
mixin myMixin();

The same as templates.  The caveat is that the compiler treats 
'myMixin' as though it were a template containing only the 
function, so it is evaluated in the context of where it is mixed 
in.  Since it makes little sense to return anything other than a 
string, perhaps the absence of the 'template' keyword would imply 
a function with 'string' return type.


mixin myMixin () {
// ...same...
}

The mixin *expression*, of course, would be unaffected. Maybe it 
would be of limited benefit to the OP, but it might be generally 
useful.  Otherwise, while ugly, the current anonymous delegate 
approach isn't the most horrid thing imaginable.


-- Chris Nicholson-Sauls



Re: Something needs to happen with shared, and soon.

2012-11-11 Thread Chris Nicholson-Sauls
On Sunday, 11 November 2012 at 19:28:30 UTC, Andrej Mitrovic 
wrote:

On 11/11/12, Alex Rønne Petersen  wrote:
And finally, the worst part of all of this? People writing 
code that
uses shared today are blindly assuming it actually does the 
right thing.

It doesn't.


I think most people probably don't even use shared due to 
lacking

Phobos support. E.g.
http://d.puremagic.com/issues/show_bug.cgi?id=7036

Not even using the write functions worked on shared types until 
2.059

(e.g. printing shared arrays).

'shared' has this wonderfully attractive name to it, but 
apparently it

doesn't have much guarantees? E.g. Walter's comment here:
http://d.puremagic.com/issues/show_bug.cgi?id=8077#c1

So +1 from me just because I have no idea what shared is 
supposed to

guarantee. I've just stubbornly used __gshared variables because
std.concurrency.send() doesn't accept mutable data. send() 
doesn't

work with shared either, so I have no clue.. :)


Fix support for shared(T) in std.variant, and you will have fixed 
send() as well.  Meanwhile, in common cases a simple wrapper 
struct suffices.

##
module toy;
import std.concurrency, std.stdio;

struct SImpl {
string s;
int i;
}
alias shared( SImpl ) S;

struct Msg { S s; }
struct Quit {}

S global = S( "global", 999 );

void main () {
auto child = spawn( &task );
S s = S( "abc", 42 );
child.send( Msg( s ) );
child.send( Msg( global ) );
child.send( Quit() );
}

void task () {
bool sentinel = true;
while ( sentinel ) {
receive(
( Msg msg  ) { writeln( msg.s.s, " -- ", msg.s.i ); },
( Quit msg ) { sentinel = false; }
);
}
}
##

grant@aesgard ~/Projects/D/foo/shared_test $ dmd toy && ./toy
abc -- 42
global -- 999

-- Chris Nicholson-Sauls



Re: Growing a Language (applicable to @attribute design)

2012-11-13 Thread Chris Nicholson-Sauls
On Wednesday, 14 November 2012 at 00:54:07 UTC, Walter Bright 
wrote:

On 11/13/2012 12:56 PM, Walter Bright wrote:
An insightful talk by Guy Steele on what makes a language 
successful.


http://www.youtube.com/watch?v=_ahvzDzKdB0


Guy says something interesting in there that's applicable to 
one of our current discussions.


Particularly, should we allow:

   @identifier

as a user-defined attribute, in potential conflict with future 
reserved attribute words, or not?


Guy makes the argument that users need to be able to extend the 
vocabulary of a language and have those new words look like 
built-in ones. We have that today, of course, with the ability 
of defining new types. There is no special syntax that says 
"this is a user-defined type, not a keyword."


I think this is a compelling argument, and tips the scales in 
its favor. Probably we've been excessively worried about the 
problems of adding a new builtin attribute type.


Still better to worry now, only to concede later, than to develop 
a hobo stew of a language.  :)


-- Chris Nicholson-Sauls


Re: __gshared implicitly convertible to shared?

2012-11-20 Thread Chris Nicholson-Sauls
On Tuesday, 20 November 2012 at 19:15:01 UTC, Jonathan M Davis 
wrote:
Would it make sense to make it so that __gshared implicitly 
converted to
shared? It's my understanding that the main purpose of 
__gshared is to be able
to better interact with C code, but given the issues with 
shared, lots of
people have just used __gshared instead of shared. This causes 
a problem in
some cases. For instance, none of Mutex's functions are 
currently shared in
spite of the fact that it really doesn't make sense to have a 
Mutex which is
thread-local, but it can't have all of its functions be only 
shared, because
then it wouldn't work with __gshared. That means that in order 
to work with
both __gshared and shared, all of its functions must be 
duplicated, which is

obviously less than ideal.

So, given that __gshared is shared across threads like shared 
is (just with
fewer protections), would it make sense to make it so that 
__gshared
implicitly converts to shared? Then a type like Mutex which is 
intended to be
shared, can just make all of its member functions shared, and 
it'll work with

both __gshared and shared.

It may also be necessary to make shared implicitly convert to 
__gshared for
that to work cleanly (particularly when you get stuff like a 
member function
returning a reference variable which then must be shared, even 
if the original
variable were __gshared - because the function itself is 
shared), and I don't
know how big a problem that would be. But I think that the 
basic idea of
allowing implicit conversions at least from __gshared to shared 
(if not shared
to __gshared) is worth exploring. Is there a major reason why 
it would be a
bad idea? My experience with both is limited, and I may just be 
completely

missing something here.

- Jonathan M Davis


I'm short on time, and so can't double-check the online docs or 
the book, but as I recall (having never actually used 
__gshared... yet) they differ in that shared is a type 
constructor and __gshared is a declaration attribute.  So I'm 
just not sure.  On the one hand, the compiler would always be 
able to see that either the left or right side of an assignment 
(or the inside of an argument list) includes a __gshared 
variable, and could do the "right" thing...  But on the other 
hand it would be an odd special case of a type qualifier being 
cast away because of a variable's attribute.  Is this something 
we want?  Or is it intended as a short-term workaround until 
shared is more fully/correctly defined semantically?


Re: The impoliteness of overriding methods

2012-12-20 Thread Chris Nicholson-Sauls
How is this proposal significantly different from the currently 
working:


interface Base {
final void chainMe () {
if ( condition ) chainMe();
else doChainMe();
}

protected void doChainMe();
}


-- Chris NS


Re: What happened to the alias this = identifier syntax in 2.062?

2013-02-23 Thread Chris Nicholson-Sauls

On Friday, 22 February 2013 at 21:23:04 UTC, Timon Gehr wrote:
I guess the main issue is that alias blah this; shouldn't have 
made it into the grammar in the first place. But this was 
obviously done in order to establish a broken analogy to the 
other uses of alias. Either alias this=blah; must be kept or 
the alias this syntax should be deprecated in favour of a 
specially named member function.


I believe the alias syntax was based on typedef, which was 
inherited from C, and has now been removed from D; so the 
justification was there in the past, but now absent which is why 
the change is happening now.


As far as replacing 'alias...this' with a member function, that's 
precisely how it *used* to be done with opDot(), but it suffered 
from overhead. I had thought, at the time 'alias...this' was 
first introduced, that the two were meant to live side by side, 
but then the realization came that one could actually achieve 
opDot's purpose with clever use of 'alias...this' so the latter 
fell out of favor.  Alas.


Re: Filter and Map's weird return types cause frustration...

2013-02-23 Thread Chris Nicholson-Sauls
Straight from the documentation: "returns a new range" -- no 
guarantee made about the relation of return type and parameter 
type.


These functions return range objects to amortize the potential 
cost of the operation, with a very small initial cost (a 
reference to the input range), which is actually very useful in a 
great many situations. They are all written as generics operating 
on ranges as both input and output.  For better or worse, this 
has become the de facto D idiom.  If you really do just want the 
array out of it, import std.array and call the eponymous function:


example = example.filter!isLongEnough().array();

Voila. This iterates the full range and collects the results, as 
expected. What *would* be nice would be to have "InPlace" 
variations of these functions for use cases such as yours, in 
order to re-use resources.


example.filterInPlace!isLongEnough();

Bam, done; assuming the input is a random access range (which a 
basic array is, is it not?).


Re: The new std.process is ready for review

2013-02-24 Thread Chris Nicholson-Sauls

On Sunday, 24 February 2013 at 19:45:26 UTC, H. S. Teoh wrote:


Alternatively, use a version identifier:

version = newStdProcess;
import std.process; // get new version
-
//version = newStdProcess;
import std.process; // get old version

Then once the old version has gone through the deprecation 
cycle and is
kicked out, the new code can just ignore version=newStdProcess 
and
always import the new version, and existing user code needs no 
changes.




Would work just fine, *if* versions propogated across modules, 
which they do not. (And doing so creates new problems discussed 
to death and beyond in times past.)  But maybe you meant setting 
it at the command-line, which to be honest, was my first thought 
as well. The ensuing discussion baffles me.


How about this as a suggestion, even though I know it will never 
happen.


Release A:
 - New process module is available as 'future.process'
 - Old module remains available as 'std.process' but with a 
pragma(msg) warning users that it will go away next release. 
(It'd be even better to have a pragma(warn), actually.)

 - Old module is duplicated as 'past.process'

Release B:
 - New module is now 'std.process', but with a pragma(msg) 
reminding users to update code if they haven't already

 - Old module remains at 'past.process'

Release C:
 - New module remains at 'std.process' now with no special 
messages.

 - Old module remains at 'past.process' for the last time.

Ta, fricking, da.
We should have started a procedure like this ages ago for Phobos 
additions and rewrites. Not everyone is in a position to 
comfortably use pre-release compilers, so testing new code from 
git head is not an option for them. Further, this gives old code 
three whole releases before it's forced to update; that ought to 
be enough legacy support.


Legacy support is the devil.


Re: Proposal for SentinelInputRange

2013-02-28 Thread Chris Nicholson-Sauls
A use case that comes immediately to mind: a sentinal range that, 
yes wraps, an infinite (but predictable!) range, effectively 
allowing you to take a head-slice of the infinite range.


auto foo = infiniteRangeOfEvenNumbers();
auto upto1000 = GenericSentinalInputRange!1000( foo );

Yes, in this contrived example, one could use take(), but what 
about an infinite range that can be predicted to always hit 
certain points, but is not restricted to those points?



As for other cases of sentinal ranges wrapping others, in 
particular arrays, there seems to be no mention of what I expect 
would be the most common use case: wherein the code which 
instantiates the sentinal range can guarantee that the sentinal 
already exists in the source data/range, because it *put* it 
there -- the lexer remains a fine example, as it tacks the 
terminating \0 on.  There is no need for extra checks, because 
there is no need to *replace* the source data with the sentinel. 
It is naturally reduced to it through normal processing.



Other apparent use cases: list processing (Andrei has mentioned 
this already, for singly-linked lists); protocol processing with 
a terminate-transaction message, or similar; state sequences 
(which can include lexers and parsers, as it happens).  This is 
just off the top of my head.


Can we do it now, without a special type?  Yes.  Is there any 
gain from introducing the special type, versus what can be done 
now?  Yes, sometimes.  Is there any harm in introducing the 
special type?  No.  Is there significant cost in adding it?  No.  
Should this just be handled by compiler optimization?  Yes and no 
-- yes in that a great compiler should be able to optimize *many* 
(but not neccessarily all!) cases; but no in that including 
implementation details in a language spec is usually bad mojo.  
Of course, any compiler that could optimize the common cases, 
could at least as readily optimize the use of a sentinal range -- 
in fact, I'd expect it to open optimization paths for some of the 
corner cases that might otherwise not have been optimized.


So... I could live without a standard sentinal range concept 
(have so far, using sentinal injection with input ranges, which 
as Walter pointed out is really an incorrect use (abuse?) of 
input ranges), but I also know I'd be using it if it existed (and 
thereby cleaning up some code versus how I do it now).


Re: Proposal for SentinelInputRange

2013-02-28 Thread Chris Nicholson-Sauls

On Friday, 1 March 2013 at 06:33:42 UTC, deadalnix wrote:


struct GenericSentinelRange(R, Sentinel) {
R r;

@property auto front() {
return r.front;
}

void popFront() {
r.popFront();
}

@property empty() {
return r.front == Sentinel;
}
}


That's exactly what I wrote as well, when I played with the idea 
before posting.  Except I just called the sentinel constant S and 
added 'enum sentinel = S;' -- not significant extra work.


We don't need a new type of range at all. You confuse 
legitimate uses case for using a sentinel to terminate a range 
and uses case where an actual sentinel range is needed.


I'm not confused. The use case for a sentinel range /type/ is 
always going to be the same, and singular: automating legitimate 
use cases for sentinels.  So, in effect, an argument for one is 
as good as for the other, when I'm only responding to the calls 
for use case examples. My mistake was in not making it clear that 
I was responding just to those, sorry.


You can live without, and guess what : if you use LDC (and 
probably GDC) you'll get the performance boost Walter is 
talking about.


Which presupposes that I *can* use LDC (or GDC). For many people, 
it may not be an option.  And last time I tried (which has been 
months now, admittedly) I couldn't get LDC to work for me at all, 
which is a shame since I'm actually very much interested in it.  
Either way, reliance on implementation details is not a good 
thing.


Re: Array indexing/offset inline asm ambiguity

2013-03-16 Thread Chris Nicholson-Sauls

On Sunday, 17 March 2013 at 01:54:27 UTC, Walter Bright wrote:

On 3/16/2013 5:24 PM, David Nadlinger wrote:

But Walter seems to think this issue
not worth addressing: 
http://d.puremagic.com/issues/show_bug.cgi?id=9738


Not exactly. I felt:

The inline assembler uses Intel syntax, and for better or 
worse, that's what it

is.

We need to either stick with it, as it is fairly well 
understood by asm
programmers, or use D syntax. Some hybrid in between will be 
liked by nobody.


---Warning: hijack ahead---

How reasonable would it be to consider a HLA-like syntax, at 
least as a basis?
( 
http://www.plantation-productions.com/Webster/HighLevelAsm/HLADoc/HLARef/HLARef_html/HLAReference.htm#50401283_pgfId-1001263 
)


Call me crazy (everyone else does) but I prefer it over any other 
I've used.


Re: One case of array assignments

2013-03-18 Thread Chris Nicholson-Sauls

On Thursday, 14 March 2013 at 01:34:02 UTC, Marco Leise wrote:

Am Wed, 13 Mar 2013 14:31:42 -0700
schrieb "H. S. Teoh" :

Why is it bad to have to explicitly list the elements for 
static

initialization?


Because of:

struct CompressionData
{
ubyte[4096] x =
[0,0,0 /* ...ad nauseum... */ ,0,0];
}


struct CompressionData
{
ubyte[4096] x; // note this is already [0...0] thanks
   // to default init... but still:

this ()
{
x[] = 0;
}
}


--- Or even: ---

import std.range;

struct CompressionData
{
ubyte[4096] x = repeat( 0 )[ 0 .. 4096 ];
}

Assuming repeat()[] is CTFE-able (didn't test).


Re: DIP32: Uniform tuple syntax

2013-04-01 Thread Chris Nicholson-Sauls
Two different languages I've used in the distant past used @ for 
expansion.


auto t1 = {1, "hi"};
auto t2 = {2, "yo"};

auto t3 = {t1, t2}; // == {{1, "hi"}, {2, "yo"}}
auto t4 = {@t1, @t2}; // == {1, "hi", 2, "yo"}

Are there still unspecified plans for @, or is it now available 
for something like this?


Regarding the $ident syntax (which I was glad to see, since my 
first question when reading the DIP was whether a way existed to 
do that), couldn't the @ syntax then be allowed for this as well, 
with expansion of a scalar defined as the scalar itself?


int x = 1;
if ( auto {@x, y} = tmp ) // {1, y} = tmp

if ( auto {x, y} = tmp } // same as in DIP



Re: DIP33: A standard exception hierarchy

2013-04-01 Thread Chris Nicholson-Sauls
On Monday, 1 April 2013 at 23:52:52 UTC, Steven Schveighoffer 
wrote:

contrived example:

class MyException : Exception {}
class MySpecificException1 : MyException {}
class MySpecificException2 : MyException {}
class MySpecificException3 : MyException {}

try
{
   foo(); // can throw exception 1, 2, or 3 above
}
catch(MySpecificException1 ex)
{
   // code block a
}
catch(MySpecificException2 ex)
{
   // code block b
}

What if code block a and b are identical?


I was thinking about this too.  And the most obvious answer in D 
is not that great.


try {
foo(); // can throw 1, 2, or 3
}
catch ( Exception ex )
{
if ( cast( Exception1 ) ex !is null || cast( Exception2 ) ex 
!is null )

{
// recovery code
}
else throw ex;
}


Ew. The first thing that comes to mind is separating the variable 
from the condition, thus allowing multiple matches.


catch ex ( Exception1, Exception2 )
{
// recovery code
}

The necessary semantic caveat being that the type of 'ex' would 
be the nearest common base type to the named exception types.  
(The syntax is similar to some languages that have built-in error 
types and the like.)


Combined with the previous proposal of being able to attach an 
if-constraint to catch blocks, I suppose it could be rather 
elaborate (powerful though?).




Re: DIP32: Uniform tuple syntax

2013-04-02 Thread Chris Nicholson-Sauls

On Tuesday, 2 April 2013 at 06:42:00 UTC, Jacob Carlborg wrote:

On 2013-04-02 02:16, Chris Nicholson-Sauls wrote:
Two different languages I've used in the distant past used @ 
for expansion.


auto t1 = {1, "hi"};
auto t2 = {2, "yo"};

auto t3 = {t1, t2}; // == {{1, "hi"}, {2, "yo"}}
auto t4 = {@t1, @t2}; // == {1, "hi", 2, "yo"}

Are there still unspecified plans for @, or is it now 
available for

something like this?

Regarding the $ident syntax (which I was glad to see, since my 
first
question when reading the DIP was whether a way existed to do 
that),
couldn't the @ syntax then be allowed for this as well, with 
expansion

of a scalar defined as the scalar itself?

int x = 1;
if ( auto {@x, y} = tmp ) // {1, y} = tmp

if ( auto {x, y} = tmp } // same as in DIP


Won't there be a conflict with UDA's?


Oh yeah, those exist.  (I seriously forgot... just because I 
haven't gotten to play with recent D releases any.)




Re: interfaces and such

2012-08-24 Thread Chris Nicholson-Sauls
On Friday, 24 August 2012 at 14:15:28 UTC, Steven Schveighoffer 
wrote:
On Fri, 27 Jul 2012 12:48:59 -0400, David Nadlinger 


wrote:


On Friday, 27 July 2012 at 14:56:18 UTC, Gor Gyolchanyan wrote:
I have a small question: why aren't interfaces implicitly 
convertible to

Object?


Not all interfaces »originate« from D objects, they can also 
be COM interfaces. Using (cast(Object)foo) should work if foo 
is really an Object.


All Com interfaces inherit from IUnknown.  This is statically 
known.


The idea that we cannot tell which interfaces are COM and which 
are normal

is a myth.

There is no reason why interfaces (that aren't COM) shouldn't be
implicitly castable to Object.

-Steve


Technically true, however COM is not the only example of foreign 
objects used via interfaces.  The (limited) C++ compatibility, 
for example, works this way.




Re: Delegate is left with a destroyed stack object

2013-11-02 Thread Chris Nicholson-Sauls
On Thursday, 31 October 2013 at 20:56:11 UTC, Peter Alexander 
wrote:
On Thursday, 31 October 2013 at 07:41:30 UTC, Jacob Carlborg 
wrote:


I use Ruby all day with a lot of blocks (closures) and I never 
had any problem. In Ruby everything is an object and passed 
around by reference. I guess that's help.


BTW, the default iteration pattern in Ruby is to use blocks:

[1, 2, 3].each { |e| puts e }

Closest translation in D:

[1, 2, 3].each!(e => writeln(e));

But in D one would of course use a foreach loop instead.


Those aren't closures, it captures none of the environment. 
Those are just simple lambda functions.


Maybe this would be a better Ruby example?

##
module App
def self.run
register_callbacks
Other.call_all
end

def self.register_callbacks
foo = 10
Other.register { puts foo }

Other.register { puts self }

foo = 20
Other.register { puts foo }

foo = 30
end
end

module Other
@@callbacks = []

def self.register (&blk)
@@callbacks << blk
end

def self.call_all
@@callbacks.each {|cb| cb.call }
end
end

App.run if __FILE__ == $0
##

Output is:
30
App
30

-- Chris NS


Re: Thoughts about D package management on Gentoo

2013-11-08 Thread Chris Nicholson-Sauls
I think you're headed the right way, and I'd recommend studying 
how Ruby/rubygems are handled in Gentoo.  A similar pattern, with 
eselect, a set of symlinks, and versioned package directories, 
would do an awful lot.  One may end up with a mass of installed 
slots, but that sort of problem is usually resolved over time.


One thing of benefit, assuming it's being applied properly by all 
vendors, is the availability of std.compiler and a few predefined 
version identifiers so that D programs can already check what 
compiler and version they are being processed by.  This saves the 
trouble of trying to establish a USE flag convention for that.


In light of trying to support different compilers, it might be a 
good idea to have a virtual/dmd (or virtual/dc? or...?) package 
to provide dependency genericity.  I know you mentioned having a 
virtual/phobos package, but I'm not sure that's safe -- yet.  
Once we are at a stage where dynamic libraries work well enough 
that phobos is normally used as such, then it would make more 
sense.


[OT] Re: DIP 50 - AST macros

2013-11-13 Thread Chris Nicholson-Sauls
On Wednesday, 13 November 2013 at 08:26:52 UTC, Jacob Carlborg 
wrote:


I'm using a pluign to Ruby on Rails that does something similar 
but by overloading operators. The problem with this approach, 
in Ruby, is that you cannot overload operators like || and &&, 
so instead they overload | and & resulting in new problems like 
operator precedence. Example:


Person.where{ |e| (e.name == "John") & (e.address == "Main 
street") }


Is this in any way better than the basic Ruby

  where( name: 'John', address: 'Main street' )

?  Or was it just something quick and contrived to show the 
behavior, and not the utility, of the plugin?  Just curious.


Re: DMD 2.063 produces broken binaries

2013-06-10 Thread Chris Nicholson-Sauls
I just started having this problem as well, however it appears 
whether I'm using the latest DMD or older versions (I only tried 
as far back as 2.060).  Like others, the program compiled with 
2.063 dies at _d_dso_registry().  The programs compiled with 
previous versions die at gc_init().


I've made no other relevant changes recently, so I'm rather 
perplexed.


Re: More Linux love?

2013-06-16 Thread Chris Nicholson-Sauls
As far as installing/managing DMD itself on Linux, DVM will 
change your life.  Try the following:


wget -Odvm 
https://github.com/downloads/jacob-carlborg/dvm/dvm-0.4.1-linux-32

chmod +x dvm && ./dvm install dvm
 << open new terminal >>
dvm install 2.063.2
dvm use -d --64bit 2.063.2



Re: Rich Hickey's slides from jvm lang summit - worth a read?

2009-09-29 Thread Chris Nicholson-Sauls

bearophile wrote:

Walter Bright:


I've been thinking of transitioning dmd's semantic analysis to using immutable 
data structures because it will reduce allocations, not increase them.<


As usual I am ignorant about such matters, so I can't give you a good answer.
But from what I've seen in immutable-based languages, they produce a sustained 
flux of small/little immutable objects that the GC has to free and allocate all 
the time. This stresses the GC. Surely people here that know Clojure or Scala, 
Haskell or F# may give you a better answer. Maybe even numbers of the amount of 
object flux they face in normal programs. So the situation with strings may be 
not generalizable to the other immutable data structures a program may need to 
use.

Bye,
bearophile


My personal experience with Scala, at least, has been that it doesn't hurt anything.  Even 
just considering the most common kinds of operations: ( 1 :: 2 :: 3 :: 4 :: 5 :: Nil ) 
creates a Scala list of five values... but in the process creates five different lists! 
Consider it "unrolled" to something like this:

tmp = 5 :: Nil
tmp = 4 :: tmp
tmp = 3 :: tmp
tmp = 2 :: tmp
tmp = 1 :: tmp
tmp

Yipes.  BUT... think of it as a single-linked-list structure, and its not really that bad, 
 because each of those objects is quite small, and all five of them are preserved in the 
original list. Compare:

A = 3 :: 4 :: Nil
B = 2 :: a
C = 1 :: a

Here we have two lists (B & C) being made, each with four items... but only four items 
total, not eight, because the '4' and '3' cells in A are being reused between them.  I 
think that kind of capability is what has Walter interested.


-- Chris Nicholson-Sauls

P.S. -- Just to make your head hurt... "::" isn't even an operator, its the name of a 
class (& a singleton too...) defined in the stdlib as a derivative of List.  Scala is just 
weird like that.


Re: Eliminate class allocators and deallocators?

2009-10-08 Thread Chris Nicholson-Sauls

Michel Fortin wrote:

On 2009-10-07 17:53:21 -0400, Craig Black  said:


Yes, recycling is best and I'm considering it. I'm only worried about
the extra cost.

Andrei


No this is a bad idea.  Removing the possibility to delete data will 
cause serious problems with heap fragmentation in some programs.


Hum, perhaps we need to review more thoroughly how memory allocation 
works. As Andrei said himself, we now have all the necessary parts in 
the language to reimplement 'new' as a library function.


So let's say we ditch 'new' and 'delete' as keywords. Let's first 
replace the keyword 'new' with a static function of the same name in a 
class or a struct. It could be implemented this way:


static T new(A...)(A a) {
T t = GC.alloc!T(); // GC.alloc sets the T.init bits.
t.__ctor(a);
return t;
}

Usage:

Foo foo = Foo.new();

That's a static function template that needs to be reimplemented for 
every subclass (Andrei already proposed such kind of mixins) and that 
returns a garbage-collected object reference. Now, if you want manual 
allocation:


static T new(A...)(A a) {
T t = GC.allocNoCollect!T(); // GC won't collect this bit.
t.__ctor(a);
return t;
}

void dispose() {
this.__dtor();
GC.free(this);
}

Usage:

Foo foo = Foo.new();
...
foo.dispose();

But then you could do much better: 'new' could return a different type: 
a smart reference-counted pointer struct for instance. The possibilities 
are endless.




Prior to this post I'd been on the side of retaining "good ole" delete, owing somewhat to 
my own tendency to do Evil Things with overloaded new/delete, such as transparent 
free-lists.


I've become neutral in light of the above proposed technique, because it really doesn't 
break that kind of usage.  In fact, it technically makes it more reliable and more 
flexible since the behavior of these is more predictable (not subject to compiler 
quality/method-of-implementation, and guaranteed to be "just another function").


That said, the stdlib (or probably druntime) needs to provide good general-case support 
for this, which should include some sort of IDisposable interface (as mentioned repeatedly 
by others) otherwise we're jumping into the abyss (of massive repetitive coding) rather 
than over it (into the Elysian fields).


One consideration is that new(), perhaps, ought not be a static member of its class at 
all, but rather a global written along similar lines to tools such as "to".  Given that, 
one could write something like:


##
class C {...}

C new (T:C, A...) (A a) {
auto c = GC.alloc!T();
c.__ctor(a);
return c;
}

auto somevar = new! C (1, 2, 3);

// free-listed
class F {...}

F new (T:F, A...) (A a) {
return F.List.length != 0
? F.List.pop
: defaultNew! F (a)
;
}
##

The latter examples shows my thinking: that the stdlib/druntime could easily provide a 
default new() that does what the current new operator does.  Class designers could then 
overload this default new() as needed.  Provide a reasonable alias for the standard new() 
(I used "defaultNew" above, but its probably not the best) and it can still be used as 
backup in custom functions, such as in the free-list example.


Incidentally... does anyone else notice that, in the static-new proposal, we've once again 
recreated Ruby?


Proposed D2:
auto foo = Foo.new;

Ruby:
foo = Foo.new

At least mine looks more like current syntax:
auto foo = new! Foo;

-- Christopher Nicholson-Sauls


Re: Amusing D facts: typesafe variadic arrays are lazy!

2009-10-13 Thread Chris Nicholson-Sauls

downs wrote:


Here is a funny consequence of this amusing fact:

if you overload opAssign in a struct with lazy T[] dgs..., you can achieve the 
following syntax



WithFlag(GL_BLEND, true) = WithDepthMask(false) = tex.With = Quads = {
  foreach (i, q; qa) {
float f = 1f*i / qa.length; Color(1f-f, f, 1f);
TexCoord(0f, 0f); Vertex(q.points[0]);
TexCoord(1f, 0f); Vertex(q.points[1]);
TexCoord(1f, 1f); Vertex(q.points[3]);
TexCoord(0f, 1f); Vertex(q.points[2]);
  }
};


That's... just beautiful...

-- Chris Nicholson-Sauls


Re: Goodbye

2009-10-14 Thread Chris Nicholson-Sauls

Saaa wrote:
"Yigal Chripun"  wrote in message 
news:hb2u2n$2if...@digitalmars.com...

On 13/10/2009 20:24, Saaa wrote:

Yigal Chripun wrote


ego has nothing to do with being smart.
you can be extremely smart without getting on people's nerves all the
time.

A smart person can choose when to get on somebody's nerves ;)


The bible says about Noah that he was the most just and moral person in 
his generation.

There are two opposed interpretations for this:
positive: his generation was so morally corrupt that managing to be moral 
in such a harsh environment is a virtue.
negative: Noah is moral relative to his generation which doesn't mean a 
lot on an absolute scale since his generation was so corrupt.


not all men are born equal so we all choose from the above points of view.
you can either decrease the value of others to feel good about yourself or 
you can strive to improve yourself and therefore increase your value in 
the eyes of others. the latter is harder but it's the only beneficial way 
for mankind. obviously, being egotistical belongs to the former.


consider this:
when a person asks a question on the NG (might be extremly stupid 
question) the (smart) person to reply can either give a snide remark and 
thereby decrease the size of this community by one or give constructive 
information, relevant links, etc and gain one more D programmer. I'd say 
that the latter is the smart choice.

we have a saying in Hebrew which translates roughly as:
a smart man knows how to avoid a pitfall which a knowledgeable person can 
figure a way out of.


Getting on somebody's nerves doesn't necessarily serve as a way to feel
better about oneself.
Also, improving oneself doesn't necessarily mean others will see this 
improvement.

And, improving oneself is sometimes easier than making somebody else
feel bad about her/his self.
A snide remark doesn't always mean the other person will leave.
The Hebrew saying is mostly about the difference between being smart and
being intelligent; a tad unrelated.

The important word in my sentence was "can": being able to choose the
emotion in which you'd like to react.
Learning how Not to let your blood boil when expecting a snide remark
is another good ability, I think. 





The most important thing is remembering that black text on a white screen carries 
absolutely no emotional information whatsoever, in either direction, in any case.  The 
exception that proves the rule, of course, is ZOMG NERD RAGE ALLCAPS.  Otherwise, there's 
nothing to go on.




Re: DIP6

2009-10-14 Thread Chris Nicholson-Sauls

Ary Borenszweig wrote:

Bill Baxter wrote:
On Wed, Oct 14, 2009 at 5:47 AM, Ary Borenszweig 
 wrote:

Kagamin wrote:

http://www.prowiki.org/wiki4d/wiki.cgi?LanguageDevel/DIPs/DIP6


Java's syntax has the advantage of having to type less when the
annotation has no arguments: @annotation vs. [annotation].

In both cases you have a two-keys overhead.

No, why?


Maybe you have a different keyboard layout than Kagamin and me.

On a US layout --
@  is Shift+2
but [ and ] are single keystrokes.

--bb


Ah, two keys. I thought two chars. But I use the pinky finger to do the 
shift, isn't that less that a full blown finger to do [ or ]?


I was thinking the same thing... but then again I don't think typing "Ctl-Alt-K [ 
Ctl-Alt-K Ctl-Alt-K" just to get an eth (ð) is a big deal...


-- Chris Nicholson-Sauls


Re: Communicating between in and out contracts

2009-10-14 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Consider a Stack interface:

interface Stack(T) {
   bool empty();
   ref T top();
   void push(T value);
   void pop();
   size_t length();
}

Let's attach contracts to the interface:

interface Stack(T) {
   bool empty();
   ref T top()
   in {
  assert(!empty());
   }
   void push(T value);
   out {
  assert(value == top());
   }
   void pop()
   in {
  assert(!empty());
   }
   size_t length()
   out(result) {
  assert((result == 0) == empty());
   }
}

So far so good. The problem is now that it's impossible to express the
contract "the length after push() is the length before plus 1."

Eiffel offers the "old" keyword that refers to the old object in a
postcondition. But it seems quite wasteful to clone the object just to
have a contract look at a little portion of the old object.

I was thinking of having the two contracts share the same scope. In that
case we can write:

   void push(T value);
   in {
  auto oldLength = length();
   }
   out {
  assert(value == top());
  assert(length == oldLength + 1);
   }

Walter tried to implement that but it turned out to be very difficult
implementation-wise. We tossed around a couple of other ideas, without
making much progress. In particular inlining the contract bodies looks
more attractive than it really is. If you have any suggestion, please 
share.



Thanks,

Andrei


How hard would it be to do something like this: collect any local variables declared in 
the precondition into a structure, and make that structure transparently available to the 
postcondition.  So your push case above gets rewritten to something like this:


__magic_tmp = {
typeof( length() ) oldLength;
}
in {
__magic_tmp.oldLength = length();
}
out {
assert(value == top());
assert(length == __magic_tmp.oldLength + 1);
}

Honestly Lutger's idea of passing the data like parameters might be better, I'm just 
somehow uneasy about the look of "out(foo,bar)".


-- Chris Nicholson-Sauls


Re: Revamped concurrency API

2009-10-15 Thread Chris Nicholson-Sauls

Bill Baxter wrote:


case 1:
case 3:
  break;

should still be allowed.


--bb


Or replace with:

case 1, 3:
break;

-- Chris Nicholson-Sauls


Re: Eliminate assert and lazy from D?

2009-10-15 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Adam D. Ruppe wrote:

If not, it seems kinda weird that assert() is just a lib function, but if
you put static before it, it becomes a completely different thing.


That kinda takes the wind out of the sails of the "remove assert" ship.



It randomly occurred to me earlier today that one *could* implement static assert in the 
library, albeit with a different (sensical) name, IF the compiler guaranteed a 
pragma(halt) or pragma(exit) that prematurely terminates a compile the same way current 
static assert does.  Given that, a template in the library could output a custom message 
with pragma(msg) and then issue the halt.


Its really just taking static assert's check expression away from it and giving it a new 
name... but still.  The downside is having a pragma that every compiler would actually 
*have* to implement (to be worth using at least).


-- Chris Nicholson-Sauls


Re: The D Manifesto

2009-10-15 Thread Chris Nicholson-Sauls

Frank Fuente wrote:

Justin Johansson Wrote:


Frank Fuente Wrote:


Justin Johansson Wrote:


Where is it?

[Ed, remembering of course that ..


The most important thing is remembering that black text on a white screen
carries absolutely no emotional information whatsoever, in either
direction, in any case.

Thank goodness I use white text on a black screen, I get nothing but
emotional info!
]


The horror, the horror...

Yes, I know there are lots of horrors, but which kind of horror are you 
referring to?



white text on a black screen - its like The Heart of Darkness :-)


I still use that mode in my terminals, though... somehow black-on-white never suited me in 
that one case.  Even less so than green-on-black (always felt so "hollywood", shiver).


-- Chris Nicholson-Sauls


Re: OT Renting a dedicated Server in the US

2009-10-15 Thread Chris Nicholson-Sauls

BLS wrote:

Sorry OT,

I would like to rent a dedicated (root) server in the United States
Linux Ubuntu 8, min 4GB. so nothing special...
Do you have any recommendations ?

TIA, Björn


http://www.linode.com/

-- Chris Nicholson-Sauls


Re: dmd support for IDEs

2009-10-16 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

One cool thing is combining sshfs with autofs.


A cool thing I'd seriously never thought of.  Time to autofs half my /mnt...

-- Chris Nicholson-Sauls


Re: Goodbye

2009-10-17 Thread Chris Nicholson-Sauls

AJ wrote:

Chris Nicholson-Sauls wrote:


The most important thing is remembering that black text on a white
screen carries absolutely no emotional information whatsoever, in
either direction, in any case.

1
<-- "panic"! THAT DOES NOT COMPUTE! DANGER, DANGER, Will Robinson! 





Also remember: Red text on a blue screen carries all the ill intentions in the world -- 
not to mention eye strain.  As such, any web designer or UI designer known to be 
implementing this travesty is to be shot on sight.


-- Chris Nicholson-Sauls


Re: Who is Walter Bright?

2009-10-17 Thread Chris Nicholson-Sauls

AJ wrote:
Who is Walter Bright? 





We are all Walter Bright.


Re: Revamping associative arrays

2009-10-17 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:
Associative arrays are today quite problematic because they don't offer 
any true iteration. Furthermore, the .keys and .values properties create 
new arrays, which is wasteful.


Another issue with associative arrays is that ++a[k] is hacked, which 
reflects a grave language limitation. That needs to be replaced with a 
true facility.


Any other issues with AAs that you want to see fixed, and ideas guiding 
a redesign?



Thanks,

Andrei


Idea: the .keys and .values properties, rather than creating arrays, could create iterable 
ranges with the smallest possible footprint, internally walking the tree structure.


Re: Revamping associative arrays

2009-10-18 Thread Chris Nicholson-Sauls

BCS wrote:

Hello Chris Nicholson-Sauls,


Andrei Alexandrescu wrote:


Associative arrays are today quite problematic because they don't
offer any true iteration. Furthermore, the .keys and .values
properties create new arrays, which is wasteful.

Another issue with associative arrays is that ++a[k] is hacked, which
reflects a grave language limitation. That needs to be replaced with
a true facility.

Any other issues with AAs that you want to see fixed, and ideas
guiding a redesign?

Thanks,

Andrei


Idea: the .keys and .values properties, rather than creating arrays,
could create iterable ranges with the smallest possible footprint,
internally walking the tree structure.



what will this do?

foreach(key; aa.keys)
  if(Test(key))
 aa.remove(key);




Pre-cache a pointer to the next node in sequence; two pointers is still better than an 
arbitrarily long on-the-fly array.  Its my understanding that AA trees do not 
automatically rebalance, so the sequence isn't going to (otherwise) change on a removal. 
End of the sequence means a null "next" pointer.


For that matter: how common is looping over keys just to remove select ones versus other 
purposes in looping just the keys?


-- Chris Nicholson-Sauls


Re: The demise of T[new]

2009-10-19 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Leandro Lucarella wrote:

Andrei Alexandrescu, el 19 de octubre a las 11:16 me escribiste:

I'm missing something? Why this shouldn't work?

It may work, but I was unable to pull it off reasonably well.

What problems did you find?

I thought I explained that above and in several other posts. I have
the feeling this is going in circles, but let me add one more thing.
People would want to have a reasonable way of choosing between
T[new] and T[]. The differences between them are subtle (I have two
tables showing the primitives of T[] and T[new], which are very
similar).


If T[new] is "array" and T[] is "slice" as I described them, I see no
subtlety, they are huge differences, one is a dynamic array, the other is
a view on somebody else's memory.


Their primitives overlap 90% in syntax and semantics.


I know you probably hate when people says this (that's what I avoided
doing it before :):
I works very well in Python. You have arrays (well, lists, but the
interface is the same as an array) and slices. I never heard anybody
complaining about that being confusing.


Python lists and slices are quite different from D arrays.


That static decision concerns future appends to the array,
which doesn't strike me as something you know from the get-go
through future iterations of a design. Use of "auto" messes up
things further: a nice function may choose to return T[new] because
it just created an array (an implementation detail), but clients may
find that unexpected.


I don't see much problem. You should always return an array (T[new]) if
you have one, because you can get an slice from it (the inverse is not
true). Because of this, implicit conversion from array to slice can be
a good idea, so people expecting a slice when an array is returned will
never know an array was returned anyways. If you need to keep 
appending to

the array, you can have the original array and keep appending to it
without any performance hit (no copying, no new allocations).

What's wrong with that?


People expecting a slice and using "auto" or templates are in for a rude 
awakening.



Andrei


I would argue that, if they truly *needed* a slice and are relying on "auto" then they 
implicitly accept responsibility for putting the [] in place to guarantee that.  In other 
words:

auto foo = someFunc()[];

Or T[]'s and T[new]'s could have an alternative to .dup that does the same thing (return 
self for T[], and return self[] for T[new]).  Either way, it would be something to point 
out in the book as a best practice: when expecting a slice, guarantee a slice with []'s.


-- Chris Nicholson-Sauls


Re: LRU cache for ~=

2009-10-19 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:
I just wrote this to Sean and Walter and subsequently discussed it with 
Walter. Walter thinks this should work. Does anyone have the time and 
inclination to test this out? It would involve hacking into druntime's 
implementation of ~= (I'm not sure what the function name is). I'd 
really appreciate this; I'm overloaded as it is.


==

In wake of the recent demise of T[new], I was thinking of finding ways 
of making ~= efficient for T[].


Currently ~= is slow because accessing GC.sizeOf(void*) acquires a 
global lock and generally must figure out a lot of things about the 
pointer to make a decision.


Also, ~= is dangerous because it allows slices to stomp over other slices.

I was thinking of solving these issues by keeping an LRU (Least Recently 
Used) cache inside the implementation of ~=. The LRU would only have a 
few entries (4-8) and would store the parameters of the last ~= calls, 
and their cached capacities.


So whenever code calls arr ~= b, the LRU is searched first. If the 
system finds "arr" (both bounds) in the LRU, that means the cached 
capacity is correct and can solve the matter without an actual trip to 
the GC at all! Otherwise, do the deed and cache the new slice and the 
new capacity.


This also solves the lack of safety: if you request a growth on an array 
you just grew, it's impossible  to have a valid slice beyond that array.


This LRU would allow us to keep the slice API as it currently is, and 
also at excellent efficiency.


What do you think?


Andrei


Its an interesting idea, and if I have time tonight I'll take a crack at it.  For those 
others who may, the function you care about is "_d_arrayappendcT" in compiler/dmd/lifetime.


-- Chris Nicholson-Sauls


Re: Eliminate "new" for class object creation?

2009-10-20 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

I'm having a hard time justifying that you use

new X(args)

to create a class object, and

X(args)

to create a struct object. I wrote this:


The syntactic  difference between  the expression creating  a @struct@
object---Test(@\meta{args}@)@---and the  expression creating a @class@
object---\cc{new Test(}\meta{args}@)@---may be  jarring at first. \dee
could have dropped the @new@  keyword entirely, but that @new@ reminds
the programmer that an object allocation (i.e., nontrivial work) takes
place.
===

I'm unhappy about that explanation because the distinction is indeed 
very weak. The constructor of a struct could also do unbounded amounts 
of work, so what gives?


I hereby suggest we get rid of new for class object creation. What do 
you guys think?



Andrei


What would become the equivalent of, for example:
new uint[][][](4, 3, 8)

I can live with having to define API's for custom allocation strategies of classes and 
structures, rather than being able to hijack a language expression (the way one can with 
'new'/'delete'), but what about the non-class new'ables?


However, if we really must toss the 'new' keyword out the window, I reiterate my support 
for a 'T new(T,A...)(A a)' in the runtime.


-- Chris Nicholson-Sauls


Re: No header files?

2009-10-21 Thread Chris Nicholson-Sauls
I was comparing header files with auxiliary documentation. Not generated 
headers.


Header files with comments  are trivially transformed into 
auto-generated

docs (one-liner).
Why would I want to do that (generate more artifacts) when it's 
unnecessary?

I use header files. I find much value in them and see no reason to stop
using them (yes, even after the discussion in this thread and even with 
D).

Again, header files are an artifact,


No. They are only an artifact in a development style that choses to solely 
at the implementation level rather than at the specification and 
implementation levels.



 auto-generated docs are an artifact.


Yes, because it assumes a development paradigm.


If you have docs, you don't need headers,


Wrong. Nothing happens at the implementation level until the specification 
level has been (at least somewhat) defined. See? Get it? That's my 
development paradigm. You use yours, I'll use mine. OK?



so your notion that more  artifacts are required is false.


Your notion of artifact is incorrect.


 It takes me 1 second to generate the  docs


I start with "the docs". Has to be an egg before you can have a chicken. I 
don't build a car and then document it. I plan/design/specify it, THEN I 
build it.


(in fact, it takes me no time, since I have a svn trigger setup to 
generate them), how long does it take you to update your header file when 
you want to update a function/class?


That's a non-issue.


Don't you ever get tired of writing  every function signature twice?


I don't. I cut-n-paste, say a class definition, into the implementation 
file, get rid of those pesky semicolons and add the actual implementation 
code.



Have you ever used generated docs?


That's not the way I develop code, nor a match for my thought processes: I 
plan/design/specify/architect and implement afterwards. (I draw a lot of 
boxes and arrows on paper (yes, paper!) before I actually write any header 
code).



You might be surprised at how good they are.


N/A for me.




For what its worth, I've always drawn diagrams and written flowcharts and all that happy 
fun time stuffy myself... the wife has whapped me many a time for muttering my way through 
an algorithm or a pipeline when I was supposed to be listening to her... From what I 
gather from this discussion, you and I actually have rather similar approaches.


That said, I've never written a header in D.  Model packages with only interfaces, 
occasionally.  Headers, no.  I plan it all out, hash out the implementation-free module, 
and when I'm ready I go back and flesh the little buggers out, in place.  And I've never 
looked back.


Not really arguing one way or the other, just adding my tuppence.

-- Chris Nicholson-Sauls


Re: int always 32 bits on all platforms?

2009-10-21 Thread Chris Nicholson-Sauls

AJ wrote:
"Nick Sabalausky"  wrote in message 
news:hbonbp$to...@digitalmars.com...

"AJ"  wrote in message news:hboaeu$5s...@digitalmars.com...
"BCS"  wrote in message 
news:a6268ffbb0a8cc20817fe1f...@news.digitalmars.com...

Hello aJ,


I would think so. Anyway, what I find compelling about guaranteed
widths is the potential to eliminate alignment and padding issues
(that is, be able to control it with confidence across platforms as
one already can on a single platform via compiler pragmas or cmdline
switches).

Ah! I thought you were taking issue with something. D has that and gets 
most of the porting stuff to work.



It does? Get this to work on "all" platforms:

struct ABC
{
   byte a;
   int b; // may be improperly aligned on some platforms
   int64 c; // same issue
};



// Guarantee packed on all platforms
align() struct ABC
{
   byte a;
   int b; // may be improperly aligned on some platforms
   int64 c; // same issue
};


Well I can do the same thing with pragma or compiler switch in C++.  It 
doesn't mean that thing will work if 32-bit ints have to be aligned on 
32-bit boundaries. While nice to have one syntax to do that, it doesn't fix 
the "problem" (which I haven't expressed correctly probably). What good is a 
packed structure that has misaligned data members for the platform?




struct ABC {
version (RequireAlign4) align(4)
byte a;
int b;
int64 c;
}



Re: Targeting C

2009-10-23 Thread Chris Nicholson-Sauls

bearophile wrote:

Pelle Månsson:


Personally, I like this:
foreach (i; 0..10) list ~= i;
more. :)


While I like this more:
for (i in 0 .. 10)
list ~= i;

Bye,
bearophile


I prefer this (Scala):
list = list ++ (0 to 10)

Okay, that's not really fair.  The direct port to Scala would be more like:
for { i <- 0 to 10 } list :::= List(i)

Ultimately, syntax only really matters greatly where it provides some significant 
advantage or detours from some significant disadvantage.  Kinda like the '$' in array 
indices.  Early on in D, we had no such creature, but I threw my support fully behind it 
because of my prior experience with ColdC (and λμ, etc) and its use of the same syntax. 
Generally speaking, when a given language has an inordinate amount of syntax in some 
activity, it is probably a good sign that activity is uncommon when the language is 
properly applied.  Conversely, a terse compact syntax is a good sign that's common usage. 
 Depends on "genre"... and now I'm ranting and have no idea why.


-- Chris Nicholson-Sauls


Re: OT: Hats... Mostly unnecessary?

2009-10-23 Thread Chris Nicholson-Sauls

Jérôme M. Berger wrote:

bearophile wrote:

Bob Jones:


I dont know about you but I have severe diffculty comprehending
what people are trying to say if they have a hat upon their
head. It jars my brain.

I find berets particulary disturbing FWIW.


But putting on the hat takes time. If you need on average 5
seconds to find and put the hat on your head every day, you waste
up to 30 minutes every year, that you may use for something more
useful, like caressing your husky dog bitch. So optional hats are
better, you can use them only in winter.

Plus, if there is much wind, you will waste a lot of time running 
after your hat once it flies away!


Jerome


I only allow myself to purchase two new hats a year, therefore I just glue them to my head 
upon purchase to save time later.


-- Chris Nicholson-Sauls

PS -- Seriously, I've even gone to bed with the hat on.  It never leaves me.  I'm naked 
without it.  My hat comes even before my wife, and she'll be the first to tell you so. 
She once stole my hat, and hid it... I nearly left her.


Re: IDE for D? Recommendations?

2009-10-23 Thread Chris Nicholson-Sauls

AJ wrote:
Anyone have recommendations for which IDE to use to do an evaluation of D 
with? I don't need powerful capabilities as I'm just looking to write some 
code and get a feel for some things in D. A bundle would be great. Also, I 
think it would be fun to look at the libraries during the eval. "Eval" is 
too strong... I just wanna play around with D a little bit in my spare time. 
If I can't be up an running in less than an hour, including any reading 
necessary to get set up, I'll have to save it for another time. I definitely 
don't want to be at a commandline prompt. All 
comments/recommendations/opinions welcomed. (Thanks in advance). 





I'm strange, I just use Kate and a terminal, and my little home-brewed sandboxing utils. 
I've had Eclipse installed before... even tried out Descent a while back... used to use 
the *Builder IDE's from Borland back in the day... but I've never, ever, really come to a 
point where I just must have one.  I admit "intellisense" is nice, and it certainly came 
in damn handy with Java, but I don't really miss it all that much.


Maybe someday I'll refine my sandbox and release it for people like you who just want a 
quick-and-dirty working D environment to play in.


-- Chris Nicholson-Sauls


Re: TDPL reaches Thermopylae level

2009-10-27 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Bill Baxter wrote:

On Mon, Oct 26, 2009 at 11:51 AM, Andrei Alexandrescu
 wrote:

Bill Baxter wrote:

On Mon, Oct 26, 2009 at 8:47 AM, Jeremie Pelletier 
wrote:

Andrei Alexandrescu wrote:

303 pages and counting!

Andrei

Soon the PI level, or at least 10 times PI!


A hundred even. ;-)

Coming along. I'm writing about strings and Unicode right now. I was
wondering what people think about allowing concatenation (with ~ and 
~=) of
strings of different character widths. The support library could do 
all of

the transcoding.

(I understand that concatenating an array of wchar or char with a 
dchar is

already in bugzilla.)


So a common way to convert wchar to char might then become 
""~myWcharString?


That seems kind of odd.


Well, I guess. In particular, to me it's not clear what type we should 
assign to a concatenation between a string and a wstring. With ~=, it's 
much easier...




My intuition would be to expect the same as adding an int to a byte: you get an int. 
Concatenating a string and a wstring should yield a wstring; ie, encode to the wider of 
the two types.


-- Chris Nicholson-Sauls


Re: TDPL reaches Thermopylae level

2009-10-29 Thread Chris Nicholson-Sauls

Justin Johansson wrote:

Chris Nicholson-Sauls Wrote:


Andrei Alexandrescu wrote:

Bill Baxter wrote:

On Mon, Oct 26, 2009 at 11:51 AM, Andrei Alexandrescu
 wrote:

Bill Baxter wrote:

On Mon, Oct 26, 2009 at 8:47 AM, Jeremie Pelletier 
wrote:

Andrei Alexandrescu wrote:

303 pages and counting!

Andrei

Soon the PI level, or at least 10 times PI!


A hundred even. ;-)

Coming along. I'm writing about strings and Unicode right now. I was
wondering what people think about allowing concatenation (with ~ and 
~=) of
strings of different character widths. The support library could do 
all of

the transcoding.

(I understand that concatenating an array of wchar or char with a 
dchar is

already in bugzilla.)
So a common way to convert wchar to char might then become 
""~myWcharString?


That seems kind of odd.
Well, I guess. In particular, to me it's not clear what type we should 
assign to a concatenation between a string and a wstring. With ~=, it's 
much easier...


My intuition would be to expect the same as adding an int to a byte: you get an int. 
Concatenating a string and a wstring should yield a wstring; ie, encode to the wider of 
the two types.


-- Chris Nicholson-Sauls


Though I'm sure Shannon would say that the number of bits of intrinsic 
information
contained in the same sequence of Unicode codepoints is exactly the same whether
it be encoded as a string or a wstring.  Accordingly my intuition is that some 
rule
based upon left-to-right associativity would be more apt.  You could then 
concatenate
a wstring (on the rhs) to an empty string (on the lhs) to convert the wstring 
to a string
or vica versa.

Cheers
Justin Johansson



Granted LTR is common enough to be expectable and acceptable.  To be perfectly honest, I 
don't believe I have *ever* even used wchar/wstring.  Char/string gosh yes; dchar/dstring 
quite a bit as well, where I need the simplicity; but I've yet to feel much need for the 
"weirdo" middle child of UTF.


I would argue that string ~ wstring returning string is fine, but would suggest it be a 
warning for those like myself who might have first guessed it would "upscale to fit". 
Just so long as the foreach(dchar;string) trick is still around, char/string can cover an 
awful lot of ground.


All that said, though, I don't think I would ever use ""~wstring as a means of conversion. 
 It just feels like "there wasn't any other way to do this, so here's a cheap hack" -- 
which just isn't the case.


-- Chris Nicholson-Sauls


Re: Proposal: Replace __traits and is(typeof(XXX)) with a 'magic namespace'.

2009-11-04 Thread Chris Nicholson-Sauls

Bill Baxter wrote:

On Tue, Nov 3, 2009 at 1:27 PM, Derek Parnell  wrote:

On Mon, 02 Nov 2009 17:47:53 +0100, Don wrote:



is(typeof(XXX)) is infamously ugly and unintuitive
__traits(compiles, XXX) is more comprehensible, but just as ugly.

They are giving metaprogramming in D a bad name. I think we need to get
rid of both of them.

A very easy way of doing this is to replace them with a 'magic
namespace' -- so that they _look_ as though they're functions in a
normal module.
Names which have been suggested include 'meta', 'traits', 'scope',
'compiler'. Personally I think 'meta' is the nicest (and I suggested two
of the others ).

Thank you Don for this "voice of reason". A specific keyword for the
concept of compile-time activity/functionality is totally justified.

"meta" is very suitable. Short and to the point.


Shortness is key.  In compile-time code this keyword is going to
appear a lot.  So if it's going to be a new keyword, I vote for this
one.


"compiler" I could live with.

"traits" is unsuitable, as it is too limiting a concept.

"scope" is unsuitable, as it is already too highly overloaded with
semantics.

"static" is extremely unsuitable. This word should, at best, be only used
for things that do not change value or location during run-time.


A type doesn't change whether it "isArithmetic" at runtime.  A "static
if" doesn't change the branch it takes at run-time.  So by your
explanation static is exactly the right thing to use.


... and slightly off topic ...
now if only we could get the 'bang' out of template instantiation syntax as
well. When I see the '!' in something like "Foo!(X)()", my mind first says
"we are about to negate something" and then has to switch tracks "oh no,
this actually means we are using a template this time".


It does make template code in D look noisy, but I don't think there's
much chance it's going away.  I think if I were making a new language,
I'd seriously consider going with () for both indexing and function
calls, and use [] for template arguments.

--bb


Aka, Scala.


/* D */
T some_func (T : int) (T a, T b) { ... }
U[] another (U) (U a, U[] b) { ... }

some_func!int(1, 2)


/* Scala */
def some_func [T <:Int] (a: T, b: T) = ...
def another [U] (a: U, b: Seq[U]): Seq[U] = ...

some_func[Int] (1, 2)


-- Chris Nicholson-Sauls


Re: OT: Worthwhile *security-competent* web host?

2009-01-25 Thread Chris Nicholson-Sauls

Nick Sabalausky wrote:
Anyone know of a reliable, reasonably-priced web host that...and here's the 
key part...actually understands even the most basic security concepts?


It seems like every place out there has an IT/support department that is 
absolutely convinced of one or more of the following:


1. Unencrypted emails are secure.

2. PGP *signing* an email encrypts the entire message.

3. It is somehow possible to email users their passwords without the 
password ever being stored in either plaintext or in a reversible form (not 
counting, of course, the process that actually sets the password in the 
first place).


4. Secure access to the control panel isn't important.

5. If all of the navigation links and redirects inside of the HTTPS secure 
version of the control panel (including the URL that the login form submits 
to) all point directly to the insecure HTTP version, this somehow doesn't 
defeat the whole point of having secure control panel access.


6. Some other such silliness. 





I gave up trying to find a good one ages ago.  There's always the option 
of starting an account with SliceHost and doing it yourself, though.


-- Chris Nicholson-Sauls


Re: Lambda syntax, etc

2009-02-05 Thread Chris Nicholson-Sauls

BCS wrote:


Why use this:

"func(someInt) { |a,b| return a+b; };"

when you can reuse syntax and get this for the same amount of typeing

"func(someInt) (a,b){ return a+b; };"




While I know the compiler could (should) know the difference easily 
enough, my eyes want to parse that as a chained call followed bizarrely 
by a naked block, rather than a block.


That said, I've always found blocks to be one of Ruby's niftiest 
features (I do a fair bit of Ruby hackage on the side), and would love 
to see something like it in D2.


-- Chris Nicholson-Sauls


Re: Lambda syntax, etc

2009-02-05 Thread Chris Nicholson-Sauls

Robert Fraser wrote:

BCS wrote:

Reply to Yigal,


Personally I prefer to have syntax for "blocks" like Ruby/smalltalk.
given the following example function:
int func(int a, delegate int(int) dg) { .. }
// call func with [something in this spirit is my favorite]:
func(someInt) { | int a, int b | return a+b; };



how about require that the block arg in the called function name the args


int func(int a, delegate int(int val, int thing) dg) { .. }


and then pull in those names implicitly


func(someInt) { return val+thing; };


This would have implication in overloading and what not but it would 
be syntactically clean.


Ew, no. Aside from the technical issues, this distances the names from 
the use thereof (i.e. they'd likely be in separate files)


While I fundamentally agree, it could also be nice to /allow/ the names 
in the decleration, as they may be useful for documentation.


-- Chris Nicholson-Sauls


Re: The path to unity

2009-02-06 Thread Chris Nicholson-Sauls

Sean Kelly wrote:

== Quote from Bill Baxter (wbax...@gmail.com)'s article

On Sat, Feb 7, 2009 at 1:54 AM, grauzone  wrote:

Hm.  Name for a common namespace.. How about "common".

Every time you introduce a new standard namespace, a bunch of innocent
existing D programs might become invalid.


I do in fact have a top level package called "common" where I put a
bunch of code that is common to my various projects.   But I would
happily rename it in a heartbeat if it meant greater unification
between Phobos and Tango.  'Tis a small price to pay.


druntime already has "core", is there truly a need for a second top-level
namespace?


Agreed.  The mentioned packages (C libs + math) could even, if made part 
of druntime*, be under core.  Ie, 'core.stdc' and 'core.math'.


*I would now like to take a moment to propose that they both should in 
fact be part of druntime.  C compatibility is boasted as a feature of D, 
so the means to that end ought to be standardized (IMHO).  And math 
libraries are probably the most commonly used in the widest spectrum of 
programs.


My only concern is druntime turning into a "third stdlib."  Have to draw 
a line somewhere.


-- Chris Nicholson-Sauls


Re: Why version() ?

2009-02-10 Thread Chris Nicholson-Sauls

Tim M wrote:

On Wed, 11 Feb 2009 00:28:21 +1300, bobef  wrote:

I was thinking... what is the point of version() ? It is so 
inflexible. There is no even version(!...). Why not "static 
if(version(DMD))" or static if(is(version == DMD))?


Regards,
bobef


You could try something like this:


module Vers;

template vers(char[] V)
{
  mixin("version(" ~ V ~ ")
  {
const bool vers = true;
  }
  else
  {
const bool vers = false;
  }");
}

int main()
{
  static if(vers!("X86_64"))
  {
long a;
pragma(msg, "64 bit");
  }
  else
  {
int a;
pragma(msg, "32 bit");
  }

  a = 2;

  return a;
}



You beat me to it.  I actually use this a little here and there.  But 
honestly, I find that the cases where I just want 
'version(X){...}else{...}' far outweigh the cases where I want 'X && Y' 
or the like.  While it is technically a hack/workaround, I've been 
perfectly happy with it.


Now, what would be nice, would be if version() could appear in places it 
currently can't, following a few rules.  In mid-statement, for example, 
so long as its body is a complete expression.  And then the same for 
mixin expressions.  Might be daydreaming too much, there.


Imagine though...

template vers (char[] V) {
const vers = mixin("version("~V~") {true} else {false}") ;
}

Add to that a deep shorthand syntax a la:

template vers (char[] V) = mixin("version("~V~") {true} else {false}") ;

Okay, I'll come down from the clouds now.

-- Chris Nicholson-Sauls


Recursive discriminated unions [Phobos2]

2009-02-10 Thread Chris Nicholson-Sauls
Okay, we all [hopefully] know what a discriminated union is, and those 
of us who are trying out D2 can probably generally agree that 
std.variant.Algebraic makes life a good deal easier in this arena.  The 
actual usage is different, but it is definitely a gift from heaven. 
Except there's one thing it can't do: recursive types.



// D1
struct MyVar {
// ...
union {
int i;
double f;
char[] s;
MyVar[] l;  // lists good to go
MyVar[MyVar] h; // hashtables good to go
}
// ...
}


// D2
alias Algebraic!(int, double, string, MyVar[], MyVar[MyVar]) MyVar;

Bzt!  Big ole error!


Fooey.  Because I want this, badly (its absolutely necessary for a 
program I'm working on).  I asked Andrei if he had any suggestion, 
especially since it is a known limitation mentioned explicitly in the 
specs.  No luck.  He did have an idea on syntax:


Algebraic!(int, double, string, This[])

Where the 'This' token is recognized specially as recursive.  It reads 
well, although my first thought was '_' similar to the way std.bind 
works.  The million dollar question is: how to make this work?


-- Chris Nicholson-Sauls

PS: Apologies, as I just got home from a very long day, so the brain is 
a bit tired and I probably came off silly.


Re: Version declaration proposal

2009-02-11 Thread Chris Nicholson-Sauls

Don wrote:

I think I have a solution to the versioning problems.
My belief is that version statements are fine, and Walter's 'rats nest' 
argument is valid. Instead, I believe that version declarations limited 
to "version = XXX;" are too weak. They also have syntax which is subtly 
different to the rest of the language.
(version = A; version = B; looks as though you're changing the value of 
the 'version' variable).

My proposal is therefore:


* Keep version statements unchanged.
* Change version declarations to make them almost identical to bool 
declarations:


version _versionidentifier_ = _versionexpression_;

where _versionexpression_ is a boolean expression involving only true, 
false, or other version identifiers, and standard boolean operators.

* If, in addition, we allow:

version _versionidentifier_ = extern;

for versions which are supplied from the command line, it can then 
become illegal to have a version statement referring to an undeclared 
version identifier.
(Any version identifier beginning with D_ is implicitly an "= extern;" 
identifier, so does not need to be declared).
Another possibile syntax is extern version _versionidentifier_; to make 
the syntax identical to normal declarations.




This addresses a few problems:
* typos in version identifiers.
* Comprehensibility. When you see something like:
version (UseLargeSize) {
}

you have no idea if that version identifier declaration is buried in the 
code somewhere, or whether it is a command-line option. It could even be 
both!
* The effect of this would be to encourage you to create a block of 
version declarations at the start of the module, where they are easy to 
analyze and refactor.
* A lint tool could even enforce this, by disallowing any version 
declarations after the first normal declaration is encountered.


I believe this would reduce rats-nest versioning, and also eliminate the 
rats-nesting we have in version declarations right now.

Is there anything wrong with it?


Looks good to me.

-- Chris Nicholson-Sauls


Re: Recursive discriminated unions [Phobos2]

2009-02-11 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:
Ok, I have a solution now. I'm not checking it in yet because I have a 
brazillion other changes in my tree and I don't want to break something. 
But I attach it to this message and it contains the following unittest:


unittest
{
alias Algebraic!(real, This[], This[int], This[This]) A;
A v1, v2, v3;
v2 = 5.0L;
v3 = 42.0L;
v1 = [ v2 ][];
auto v = v1.peek!(A[]);
writeln(v[0]);
v1 = [ 9 : v3 ];
writeln(v1);
v1 = [ v3 : v3 ];
writeln(v1);
}

The patterns This[], This*, This[U], U[This], and This[This] are 
detected, but alas, no general solution yet (I don't know how to). 
Anyhow, std.variant is starting to get interesting with this feature in 
tow.



Andrei



I've noticed a shortcoming that I somehow hadn't come across before. 
The same issue exists in the current Phobos2, so it isn't anything new. 
 Apparently (and this may be known to all but me already) in order to 
use an array type, you must also use its element type.  Doing otherwise 
results in tripping a static assert.


Example:

module test2;

import std.variant;

alias Algebraic!(void, string) var_t;

void main () {
var_t foo = "quux";
}

Shows: ../bin/../src/phobos/std/variant.d(418): static assert  "Cannot 
store a immutable(char) in a VariantN!(maxSize,void,immutable(char)[])"


Add invariant(char) to the list and all works fine, though.  The 
offending code is seemingly in VariantN.handler!(A):


case OpID.index:
auto me = cast(A*) pStore;
static if (isArray!(A))
{
// array type; input and output are the same VariantN
auto result = cast(VariantN*) parm;
size_t index = result.convertsTo!(int)
? result.get!(int) : result.get!(size_t);
*result = (*me)[index];

break;
}

Specifically the statement (*result = (*me)[index];) triggers it, by 
spawning an opAssign!(elem_type).  I'm not sure how to cleanly alter it 
right off the top of my head.


--

On the other hand, the new form This[] works fine, so far.  The only 
missing feature is an opApply().


The form This[This]... Using 'foo.get!(table_t)[k] = v;' results in a 
range violation.  For the moment, they are essentially immutable hashes. 
 Could actually be fine for a number of purposes.


--

If I get some extra free time this weekend (assuming V-day isn't the 
death of me) I'll hack away at it some and see if I can't figure some 
things out, on all counts above.


Oh, and THANKS.  :)

-- Chris Nicholson-Sauls


Re: Why version() ?

2009-02-11 Thread Chris Nicholson-Sauls

Jarrett Billingsley wrote:

On Wed, Feb 11, 2009 at 4:11 PM, Bill Baxter  wrote:

I thought he meant this:

// once at the top
version(SomeFeatureDisabled) {
} else { version = SomeFeature; }

// in rest of code ...
version (SomeFeature)
{
   codeForFeature();
}


I don't know whether or not Walter _was_ actually insinuating that but
it's a pretty good idea ;)  the only disadvantage of course being that
I have to copy the //once at the top part into every file that wants
to use the SomeFeature version, though that probably
wouldn't/shouldn't be a big issue in practice.


I had the same thought at first when reading the 'version declarations' 
proposal elsewhere in this thread, and was going to put forth having to 
write 'version Tango = extern;' at the top of modules as an example of 
what could be bad about it... but then it occurred to me how often I've 
ever had to use version(Tango) in the first place.  (Not very often at all.)


It would be the sort of thing you use just here and there, and is 
actually self-documenting in the process, as it makes it clear that 
/this/ module is going to fork on certain versions.  Despite 
reservations, its all growing on me.


-- Chris Nicholson-Sauls


Re: Why version() ?

2009-02-11 Thread Chris Nicholson-Sauls

BCS wrote:

Hello Walter,


BCS wrote:


Reply to Walter,


Leandro Lucarella wrote:


You should probably distribute meld with DMD then ;)


sudo apt-get install meld

isn't that hard .


doesn't work unless you have apt-get working, doesn't work unless you
have a net connection, doesn't work if you don't have root... OTOH a
tarball doesn't work on any other platform, but then again nether
does DMD.


You can't download dmd.zip without a net connection, either!



last I checked you cant use apt-get over sneeker net.




I believe 'apt-get install' actually will work so long as the 
sources/.deb are in the right location.  That said, I haven't ever tried 
it.  ;)  If nothing else, you should be able to use dpkg.


Lucky Gentoo users can use emerge directly.

-- Chris Nicholson-Sauls


Re: std.patterns: it was about time

2009-02-11 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:
In wake of the increasing power of templates in D2, I am starting the 
std.patterns module, which is to contain boilerplate for a number of 
common design patterns (as in the GoF book). For now I'm adding a 
Visitor implementation, which was lying in my codebase for a while.


http://ssli.ee.washington.edu/~aalexand/d/web/phobos/std_patterns.html
http://ssli.ee.washington.edu/~aalexand/d/web/phobos/std_patterns.d

Comments and suggestions are as always welcome.


Andrei


It was, indeed, about time.

Simple as it is, you might as well toss a Singleton mixin in there.  Its 
so common and so insanely simple that there may as well be an "official" 
one.


Observer should be an interesting one to try implementing.  It could 
make use of signals/slots to good effect.  The question there is in 
whether one is to observe a Foo or a particular property of a Foo.  Both 
should probably be available.


-- Chris Nicholson-Sauls


Re: Recursive discriminated unions [Phobos2]

2009-02-15 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Brad Roberts wrote:

Andrei Alexandrescu wrote:

Advantage #1 of marrying a foreigner: you get to convince her that V-day
is an artificial event created for commercial interests only because
they want to sell blood diamonds. Watching "Blood Diamond" together a
week before V-day recommended.

Andrei


Psst.. not to burst your bubble, but you're just as much a foreigner as
she is.  So cut that out and go do something nice for your wife. :)


Of course. That does not diminish the effectiveness of the technique in 
the least. The problems start of course when you share some V-Day 
equivalent in your native culture (e.g. March 8 for us). At that point I 
usually bring up the "When in Rome..." saying. :o)


Andrei


A couple of years back I introduced her to the Japanese "white day," 
which is (warning: oversimplified explanation ahead) held a week later, 
with the roles reversed as it were.  Works out well for me.


-- Chris Nicholson-Sauls


Re: Recursive discriminated unions [Phobos2]

2009-02-15 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Chris Nicholson-Sauls wrote:
On the other hand, the new form This[] works fine, so far.  The only 
missing feature is an opApply().


Ok, I filed a bug report on your behalf.


Thanks...  I somehow always forget we have that available.

The form This[This]... Using 'foo.get!(table_t)[k] = v;' results in a 
range violation.  For the moment, they are essentially immutable 
hashes.  Could actually be fine for a number of purposes.


That's because foo.get returns by value. Try using peek, which returns a 
pointer. Could you please post some code if that doesn't work for your 
case?


Will try that tomorrow after work.


--

If I get some extra free time this weekend (assuming V-day isn't the 
death of me) I'll hack away at it some and see if I can't figure some 
things out, on all counts above.


Oh, and THANKS.  :)


Advantage #1 of marrying a foreigner: you get to convince her that V-day 
is an artificial event created for commercial interests only because 
they want to sell blood diamonds. Watching "Blood Diamond" together a 
week before V-day recommended.



Andrei


Thanks for the advice, I'll try it next year.  ;)

-- Chris Nicholson-Sauls


Re: earthquake changes of std.regexp to come

2009-02-17 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Walter Bright wrote:

Andrei Alexandrescu wrote:

I was thinking of moving older stuff to etc, is that ok?


Yes. But you should also rename the new one, perhaps to std.regex. 
That way, legacy code will refuse to compile, rather than compile 
wrongly.


Terrific. I prefer "regex" to "regexp" because it's easier to pronounce, 
particularly if you're a foreigner. "Regex" sounds like a frog utterance 
by a forest lake, "regexp" sounds like nothing in particular.


Andrei


It sounds to me like a frog who, immediately post-utterance, just got 
gigged.  I guess that makes "regex" sound even better... as its still 
alive (sounding).


-- Chris Nicholson-Sauls
-- Who so far agrees with pretty much everything you've said, and 
therefore has no real contribution...


Re: earthquake changes of std.regexp to come

2009-02-17 Thread Chris Nicholson-Sauls

Jarrett Billingsley wrote:

On Tue, Feb 17, 2009 at 3:16 PM, BCS  wrote:

could this be transitioned to CTFE? you could even have a debug mode that
delays till runtime

RegEx mather = new CTFERegEx!("some regex");


class CTFERegEx(char[] regex) : RegEx
{
 debug(NoCTFE)  static char[] done;
 else static const char[] done = CTFECompile(regex);

 public this()
 {
debug(NoCTFE) if(done == null) done = CTFECompile(regex);

base(done)
 }
}


For what it's worth the Tango regexes actually have a method to output
a D function that will implement the regex after it's compiled.  So
you _could_ precompile the regex into D code and use that.


I feature which I *adore* by the way.  So long as the precompiled regex 
is "guaranteed" to run at best possible performance (hand-rolled, 
hand-optimized solutions notwithstanding) I for one prefer them.


-- Chris Nicholson-Sauls


Re: range stuff

2009-02-17 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Michel Fortin wrote:

On 2009-02-16 20:21:00 -0500, superdan  said:

a'ight i've read all range stuff n ruminated on it for a while. yer 
ranges suck goat balls. something's amiss.


yer have ranges that generate stuff.  some even ferever. then yer 
have ranges that eat stuff output ranges that is. but there's no 
range that has both input and output. some sort of filter ranges. yer 
should connect stuff together to get chains n stuff. see? i'm sayin': 
why would ya have a piehole & an asshole if yer don't have a stomach.


i/o ranges are a missing link. if yer smart u can unify range stuff 
and stream stuff together. then stream or range it's all the same. 
not sure its possible but if it is only yer can pull it. that would 
be dogs bollocks.


Interesting. In fact I started a prototype of some kind of filter 
range for tokenizing XML: takes characters and gives tokens. That 
said, what you get is an input range (you can read tokens) that you 
build from an other input range (character range). So while it may fit 
the definition of a filter range, it may not be what you're thinking 
about.


What you want, an output range linked to an input range makes me think 
of the XmlEventReaderToWriter class in BerkelyDB XML, although in 
reverse (writer to reader) since ranges aren't pushing events, but 
pulling data when requested.
<http://www.oracle.com/technology/documentation/berkeley-db/xml/api_cxx/frame.html> 





I think filtering ranges are a great idea. Some were already present 
without a formal interface, e.g. map has an input and an output. All I 
need is to define a common interface for connecting a range to another. 
To that end, I will proclaim that if a range has the primitive


setInput(SomeRange input)

then it is a filtering range. This will be very useful for e.g. 
transcoding (we'll need at some point to rewrite std.encoding): a 
newly-defined character type SomeChar must define a filtering range that 
eats ranges of SomeChar and outputs dchar, and also a filtering range 
that eats dchar and produces SomeChar. Then that filter can be used to 
transfer characters across strings but also any combination of ranges 
including files.



Andrei


Which would, incidentally, not only be a godsend for folks who still 
need to work with non-Unicode text once in a while -- typedef'ing ubyte 
just possibly became useful -- but also potentially simplifies bridging 
between protocols, incremental multiple dispatch (if each range is also 
a dispatcher for example), structure-to-structure conversions, and a 
whole host of other nifties.


-- Chris Nicholson-Sauls


Re: About switch case statements...

2009-11-15 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Chad J wrote:

So, switch-case statements are a frequent source of nasty bugs.  Fixing
them (well) requires breaking backwards compatibility.

Any chance this will happen for D2?

(This is intended as more of a reminder and simple curiosity than a
discussion.)


I wish very much that a transferring control flow statement (break, 
return, goto etc.) is required at the end of each case. Then, the rare 
case when you want to break through is easy to implement as goto case 
xxx; and all is good.


Walter's answer to that has put me to silence for good. "But I use 
fall-through all the time!" I then knew the feature will never make it.



Andrei


For what its worth, in a (very domain specific) scripting language I've been working on, I 
used 'continue' to implement fall-through, and haven't felt too bad about it.  That and 
being able to do (case A, B, C:) helps for the most common (IME) sort of use.


//
.__receive system ( cmd: STR, @params )
switch ( cmd .lowercase .tosym )
case 'lo', 'login':
user.tell( "(LOgin has been deprecated; please start using COnnect 
instead.)")
continue;

case 'co', 'connect':
uname, pwd <- params;
who = #Database::User.lookup( uname )
if ( who.valid && who.accept_password( pwd ) )
return .accept( user, who );
end

    // ... and so on ...
end
end
//

-- Chris Nicholson-Sauls


Re: About switch case statements...

2009-11-16 Thread Chris Nicholson-Sauls

grauzone wrote:

Walter Bright wrote:
Reminds me a bit of D a few years back, when people would say D didn't 
have lambda's. But D did have them! The problem was the syntax was a 
bit verbose. Simplified the syntax, and suddenly the lambda's got 
noticed and got used.


D has no tuples.


I see what you did there.


[OT] Re: D: at Borders soon?

2009-11-18 Thread Chris Nicholson-Sauls

Tim Matthews wrote:

Nick Sabalausky wrote:
"AJ"  wrote in message 
news:hdr79b$1cm...@digitalmars.com...

Tim Matthews wrote:

AJ wrote:

Is D about to go commercial?

D is not intended as a scam for someones profit
Oh? Is it the current direction. Oh, yeah, bill gates is stupid (I 
think so).




That came straight out of left-field.


I hate being smart.


Great, sounds like you don't have much to worry about.




A fool thinks himself to be wise, but a wise man knows himself to be a 
fool. -- William Shakespeare.


I know that I know nothing. -- Socrates, c. 399 BCE

Shakespeare was such a plagiarist.


Re: Should the comma operator be removed in D2?

2009-11-18 Thread Chris Nicholson-Sauls

yigal chripun wrote:

You're remark of function chaining reminded me of a nice feture that a few OOP 
languages provide:

// pseudo syntax
auto obj = new Object();
obj foo() ; bar() ; goo() 


foo, bar and goo above are three mesages (methods) that are sent to the same 
object. i.e. it's the same as doing:
obj.foo();
obj.bar();
obj.goo();

this means the functions can return void instead of returning this like you'd 
do in C++/D. I think it provides a cleaner conceptual separation between 
multiple messages sent to one object and real chaining when foo returns obj2 
which then receives message bar and so on.


with (auto obj = new Object) { foo; bar; goo; }

Behold. ;)


Re: Chaining exceptions

2009-11-20 Thread Chris Nicholson-Sauls

BCS wrote:

Hello Jesse,


On Wed, 18 Nov 2009 18:27:47 -0800, Andrei Alexandrescu wrote:


Thanks! Question - is there a way to fetch the current Throwable from
within a finally clause?

Andrei


I'm pretty sure you can't since finally isn't passed an exception. I
also don't see anything in my quick search.



That stands to reason because in some cases (when things go correctly) 
there isn't one.





One hopes.  Just the same: (hypothetical syntax incoming)

try {
// ...
}
catch ( ExceptionA exa ) {
// ...
}
catch ( ExceptionB exb ) {
// ...
}
finally ( x ) {
// ...
if ( x ) throw new ExceptionC( x );
}

And obviously if finally has no () it doesn't bother with the feature.

-- Chris Nicholson-Sauls


Re: Chaining exceptions

2009-11-21 Thread Chris Nicholson-Sauls

Andrei Alexandrescu wrote:

Chris Nicholson-Sauls wrote:

BCS wrote:

Hello Jesse,


On Wed, 18 Nov 2009 18:27:47 -0800, Andrei Alexandrescu wrote:


Thanks! Question - is there a way to fetch the current Throwable from
within a finally clause?

Andrei


I'm pretty sure you can't since finally isn't passed an exception. I
also don't see anything in my quick search.



That stands to reason because in some cases (when things go 
correctly) there isn't one.





One hopes.  Just the same: (hypothetical syntax incoming)

try {
// ...
}
catch ( ExceptionA exa ) {
// ...
}
catch ( ExceptionB exb ) {
// ...
}
finally ( x ) {
// ...
if ( x ) throw new ExceptionC( x );
}

And obviously if finally has no () it doesn't bother with the feature.

-- Chris Nicholson-Sauls


I'm not that fancy. An API call getCurrentError returning an Error 
object or null is all that's needed. And more general too.


Andrei


At which point one could argue that the constructor of Throwable or Exception could/should 
call that same API function itself.  I'm not strictly opposed to it, mind you, it just 
bodes ill not to thoroughly examine such auto-magic.


-- Chris Nicholson-Sauls


Re: dynamic classes and duck typing

2009-11-27 Thread Chris Nicholson-Sauls

Walter Bright wrote:
One thing Java and Python, Ruby, etc., still hold over D is dynamic 
classes, i.e. classes that are only known at runtime, not compile time. 
In D, this:


   s.foo(3);

could be emulated with:

   s.dynamicMethod("foo", 3);

Unfortunately, that makes it impossible to use s with generic code 
(besides looking unappealing). But with a small feature, we can make 
this work:


   struct S
   {
...
T opDynamic(s : string)(args...);
   }

and then s.foo(3), if foo is not a compile time member of s, is 
rewritten as:


   s.opDynamic!("foo")(3);

and opDynamic defers all the nuts-and-bolts of making this work out of 
the language and into the library.


In particular, opDynamic's parameter and return types should all be 
instances of std.variant.


(This has come up in various forms in this n.g. before, but I don't have 
any references handy.)


Seems fine, but how will this interact with "alias...this" and opDot?  The former seems 
simple enough: if the "alias...this" field provides the member, use that, otherwise fall 
back on opDynamic.  The latter seems iffy, though.  Maybe something like this:


// if the return type of opDot provides the member...
(auto tmp = s.opDot, tmp ? tmp.foo(3) : s.opDynamic!"foo"(3))

Hmm... ew... but I can't think of anything better off-hand.  The "simple" design would 
probably be for opDynamic's implementation to make the call on whether to forward to 
opDot's result; aka, push the decision to the programmer.  Stick a mixin somewhere for the 
most basic case (what I showed above) and its no big deal.


-- Chris Nicholson-Sauls


Re: Semantics of ^^

2009-12-09 Thread Chris Nicholson-Sauls

Bill Baxter wrote:

On Tue, Dec 8, 2009 at 7:24 PM, Don  wrote:

* If y == 0,  x ^^ y is 1.

Need to mention what happens when x is also 0.

No.  0^^0 is 1, as well.


Is it?  That's rather embarrassing for Wolfram Alpha, then (and
presumably Mathematica, too) since they have it as "indeterminate":
   http://www.wolframalpha.com/input/?i=0^0



Confirmed with Mathematica.

In[2]:= 0^0
During evaluation of In[2]:= Power::indet: Indeterminate expression 0^0 encountered. 
>>
Out[2]= Indeterminate

-- Chris NS


Re: isRef, isLazy, isOut

2009-12-20 Thread Chris Nicholson-Sauls

Walter Bright wrote:

Andrei Alexandrescu wrote:

I asked in vain for is(var == ref), is(var == out) etc.


That's because 'is' works with types, not symbols. It didn't fit.


is(typeof(var) == ref) ?

-- Chris Nicholson-Sauls


opDispatch or equivalent at static context

2010-01-21 Thread Chris Nicholson-Sauls

(Apologies ahead of time if I've overlooked something.)

How possible could it be to have opDispatch or an equivalent feature (opStaticDispatch?) 
available for static forwarding?  Use-case: I'm envisioning an ORM library, where one 
could do things like:

Player.findFirstByName( "Bob" )

With a static forwarding template parsing the "findFirstByName" to rewrite the 
call:
Player.find( FindFlags.First, `name == "Bob"` )

I can't help but think there could be other useful scenarios.  The current (untested) 
work-around would be a proxy object for the API:

auto finder = new Finder!Player;
finder.findFirstByName( "Bob" );

// or...
auto finder = new Finder;
finder.findFirstPlayerByName( "Bob" );

The obvious problem with an opStaticDispatch, of course, would be preserving propagation 
of static lookups along the inheritance chain.  I'm guessing this could be surmountable 
when using conditions though.


class Foo : Base {
static Foo opStaticDispatch ( string s, T t ) ( t param )
if ( s.length > 3 && s[ 0 .. 4 ] == "find" ) {
// do stuff
// if the condition failed, check for 
Base.opStaticDispatch's
}
}

If there were a means for static member functions to be aware that they are being called 
through a sub-class, that might also be an avenue to the abilities I'm wanting.  I can't 
think of any sane means for that, however.


-- Chris Nicholson-Sauls


Re: opDispatch or equivalent at static context

2010-01-21 Thread Chris Nicholson-Sauls

Lars T. Kyllingstad wrote:

Chris Nicholson-Sauls wrote:

(Apologies ahead of time if I've overlooked something.)

How possible could it be to have opDispatch or an equivalent feature 
(opStaticDispatch?) available for static forwarding?  Use-case: I'm 
envisioning an ORM library, where one could do things like:

Player.findFirstByName( "Bob" )

With a static forwarding template parsing the "findFirstByName" to 
rewrite the call:

Player.find( FindFlags.First, `name == "Bob"` )



Isn't that what opDispatch does now?

-Lars


Not as a static member, to my knowledge.  At the very least, I see no mention of static 
forwarding in the docs: http://www.digitalmars.com/d/2.0/operatoroverloading.html#Dispatch


-- Chris Nicholson-Sauls


Re: OT: Minecraft death by GC

2014-10-23 Thread Chris Nicholson-Sauls via Digitalmars-d
Eh.  All I know is, this version that allegedly has framerates in 
the territory of 10ish, runs at 200+ for me on seven year old 
hardware, and I know others with the same experience.  Something 
else is a contributor.


Re: D in my trashbin

2014-10-23 Thread Chris Nicholson-Sauls via Digitalmars-d

I first encountered D in 2001.  Back then it was basically:
1. download zip
2. unpack
3. go

Today it's... the same.  (In fairness I use dvm these days, just 
to automate it.)  So if you are having difficulty compiling 
something as simple as a "hello world," as you say, there is 
something else afoot.


Re: Constant relationships between non-constant objects

2014-06-19 Thread Chris Nicholson-Sauls via Digitalmars-d

Ok, I must be missing something...

Just to make sure I'm understanding the OP: he wants to create 
two classes, A and B, such that each instance of A must be given 
a B to cling to, and which cannot be reassigned?  In what way is 
the following insufficient?



class B {/*...*/}

class A
{
this(B someB)
{
_b = someB;
}

invariant
{
assert(someB !is null);
}

private B _b;

@property B b() const
{
return _b;
}
}


Or is it that he wants to prevent even the code in method bodies 
or same-module functions from reassigning it?  In that case, I 
see two basic things to do:


 1) Isolate A (and B if it makes sense) into a module all by its 
lonesome

 2) Don't write `_b = ...`

#1 is optional.

Am I missing something, or is it really that simple?  (Not that a 
guaranteed non-rebindable type wouldn't be a nice thing to have, 
mind you.)


Re: Constant relationships between non-constant objects

2014-06-19 Thread Chris Nicholson-Sauls via Digitalmars-d

On Thursday, 19 June 2014 at 08:50:55 UTC, Chris Nicholson-Sauls
wrote:


invariant
{
assert(someB !is null);
}



Obviously that should be assert(_b !is null).. I need more
caffeine before posting.


Re: Time to rename "D" to "@D" !?

2014-06-23 Thread Chris Nicholson-Sauls via Digitalmars-d
Funny enough two of the attributes you mentioned (pure and 
nothrow) don't have an @ on them.  Maybe I'm strange, but I don't 
see any problem with the @, and would actually like to see some 
of the other attributes (including pure and nothrow) adopt them, 
for consistancy and to free up names.  Surely you don't think 
"safe" should be a keyword?  Or "trusted" or "system"?