Re: __traits for checking if a type is dynamic array (slice)

2018-11-26 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 11/26/18 4:04 AM, Per Nordlöw wrote:

Why is there no

- __traits(isArray, T)

alongside

- __traits(isStaticArray, T) and
- __traits(isAssociativeArray, T)



Thanks for bringing this to my attention, Per.

The core idea is to have __traits "primitive and ugly" and std.traits 
"convenient and nice". From that viewpoint, if isArray can be 
implemented as a library feature using primitives provided by traits, 
there is no need for making it.



when dmd already has `ENUMTY.Tarray` alongside

- ENUMTY.Tsarray and
- ENUMTY.Taarray


Justifying the feature by means of a detail in the compiler 
implementation is definitely undesirable.



and std.traits already has a wrapper for this at

https://dlang.org/phobos/std_traits.html#isDynamicArray

?


If the wrapper works well, use it and move on.


Thanks,

Andrei


Re: Forwarding arguments through a std.algorithm.map

2018-03-16 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 03/16/2018 03:52 PM, Nordlöw wrote:

On Saturday, 10 March 2018 at 21:31:41 UTC, ag0aep6g wrote:

auto forwardMap(alias fun, Ts ...)(Ts things)
{
    import std.meta: aliasSeqOf, staticMap;
    import std.range: iota;
    import std.typecons: Tuple;
    alias NewType(size_t i) = typeof(fun(things[i]));
    alias NewTypes = staticMap!(NewType,
    aliasSeqOf!(iota(things.length)));
    Tuple!NewTypes results;
    static foreach (i, thing; things) results[i] = fun(thing);
    return results;
}


Found a slightly compacter way without `iota` and `aliasSeqOf` and with 
(deprecated) string-lambda support and single-pass initialization using 
`= void` and `emplace`:


/** Returns: `xs` forwarded through calls to `fun`.
  *
  * See also: 
https://forum.dlang.org/post/zjxmreegqkxgdzvih...@forum.dlang.org

  */
auto forwardMap(alias fun, Ts...)(Ts xs)
{
     import std.meta : staticMap;
     alias MappedTypeOf(T) = typeof(fun(T.init));
     alias NewTypes = staticMap!(MappedTypeOf, Ts);

     import std.typecons : Tuple;
     Tuple!NewTypes ys = void;
     import std.conv : emplace;

     import std.functional : unaryFun;
     alias fun_ = unaryFun!(fun);

     static foreach (immutable i, x; xs)
     {
     emplace([i], fun_(x));
     }
     return ys;
}

I believe this should go into Phobos somewhere. Into std.typecons, 
std.meta or std.algorithm?


My knee-jerk reaction is that's a rather peculiar primitive to add to 
the standard library. -- Andrei


Re: Range over a container r-value with disabled postblit

2018-01-14 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 1/14/18 4:59 PM, Nordlöw wrote:

On Sunday, 14 January 2018 at 21:57:37 UTC, Nordlöw wrote:
Note that __trait(isLvalue, this) cannot be used to detect whether 
`this` is an l-value or an r-value, which I find strange.


Shall be

__traits(isRef, this)


That would be difficult because lval/rval is known on he callee side. -- 
Andrei


Re: std.range.interfaces : InputRange moveFront

2017-12-08 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 12/03/2017 12:42 AM, Johan Engelen wrote:

On Friday, 1 December 2017 at 18:33:09 UTC, Ali Çehreli wrote:

On 12/01/2017 07:21 AM, Steven Schveighoffer wrote:
> On 12/1/17 4:29 AM, Johan Engelen wrote:

>> (Also, I would expect "popFront" to return the element
popped, but it
>> doesn't, OK...
>
> pop removes the front element, but if getting the front
element is
> expensive (say if it's a map with a complex lambda function),
you don't
> want to execute that just so you can return it to someone who
doesn't
> care. This is why front and popFront are separate.

Yet, we're told that compilers are pretty good at eliminating that 
unused copy especially for function templates where all code is visible.


I assume that Steven means "copying the front element" when he wrote 
"getting the front element"? There is no need for a copy, because the 
element will be removed from the range, so we can move (whose cost only 
depends on the size of the element, internal pointers being disallowed 
by the language).
If it is expensive to actually get _to_ the front/back element (i.e. 
find its memory location), then having to do the operation twice is a 
disadvantage.


Ali: the compiler can only elide copying/moving of an unused return 
value when inlining the function. (the duty of making the return value 
move/copy is on the callee, not the caller)


Note that because front/back() and popFront/Back() are separate, a copy 
*is* needed when one wants to "pop an element off". Thus 
moveFront/Back() and popFront/Back() should be used. OK.
The fact that "pop" does something different from other programming 
languages is something important to remember when teaching people about 
D. And I think should be made clear in the documentation; let's add an 
example of how one is supposed to use all this in an efficient manner?


Back on topic: let's change the documentation of moveFront such that it 
is clear that it does _not_ reduce the number of elements in the range?


So, even though exception safety is not a common topic of D community, 
the real reason for why popFront() does not return the element is for 
strong exception safety guarantee.


Interesting point. Argh why do we allow the user to throw in move?

Regardless, separating front() from popFront() is preferable due to 
cohesion: fewer responsibilities per function, especially such low 
level ones.


This doesn't make much sense ;-)
popFrontN has more responsibility, and one gains better performance than 
simply calling popFront N times. It's similar here.


Thanks Ali for asking me to comment in this thread. The matter of fact 
is moveFront was needed for different purposes.


First off, moving in D cannot throw; all objects are moveable by means 
of bitwise move.


The main reason for moveFront's existence is supporting ranges that have 
front() return an rvalue. For those, there would otherwise be no 
efficient means to move data out of the range to its user.


Now, why does popFront return void instead of the popped element? We 
need front() anyway as a non-destructive way to look at the current 
element of the range, so having popFront return that element is 
redundant. Plus, it's difficult to optimize away particularly in 
separately compiled code.



Andrei


Re: How to avoid throwing an exceptions for a built-in function?

2017-05-10 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 5/10/17 3:40 PM, k-five wrote:
I have a line of code that uses "to" function in std.conv for a purpose 
like:


int index = to!int( user_apply[ 4 ] ); // string to int

When the user_apply[ 4 ] has value, there is no problem; but when it is 
empty: ""

it throws an ConvException exception and I want to avoid this exception.

currently I have to use a dummy catch:
try{
 index = to!int( user_apply[ 4 ] );
} catch( ConvException conv_error ){
 // nothing
}

I no need to handle that, so is there any way to prevent this exception?


Use the "parse" family: https://dlang.org/phobos/std_conv.html#parse -- 
Andrei




Re: [Semi-OT] I don't want to leave this language!

2016-12-06 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 12/5/16 3:49 PM, e-y-e wrote:

If you don't mind me saying, I think Mir could be one of the best things
for the future of D (along with LDC) and I'd be glad to help it on its way.


Yes, Mir is awesome! I keep on thinking of ways to make it better 
supported by the language and infra. -- Andrei


Re: [Semi-OT] I don't want to leave this language!

2016-12-06 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 12/6/16 3:28 AM, Ilya Yaroshenko wrote:

On Tuesday, 6 December 2016 at 08:14:17 UTC, Andrea Fontana wrote:

On Monday, 5 December 2016 at 20:25:00 UTC, Ilya Yaroshenko
Phobos/Druntime are pretty good for a lot of projects.


In theory


And what seem to be the issues in practice with code that is not highly 
specialized? -- Andrei


Re: Set Operations on Set-like Containers

2016-11-02 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 11/02/2016 11:07 AM, Nordlöw wrote:

On Wednesday, 2 November 2016 at 13:45:41 UTC, Nordlöw wrote:

Typically set- and map-like containers with O(1) key membership checking.


A typical use case is intersection of the two sets `x` and `y`.

When `x` and `y` both support O(1)-`contains(e)` the preferred algorithm
is to interate over all elements in the shorter (smallest .length) of
`x` and `y` (called `s`), and return only those elements of type E in
`s` than can be looked up in `l` via `l.contains(E)`.


Currently we don't have a good framework for associative ranges yet. We 
should define what the associative operations are, and then we can 
proceed to see where they'd make sense. -- Andrei


Re: Rust-like collect in D

2016-10-12 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 10/06/2016 10:32 AM, Nordlöw wrote:

Is there a concept in D similar to Rust's `collect`:

https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.collect


That's "make" in std.container. Is that what you're looking for? As an 
aside, "collect" is an awful abbreviation of "collection". -- Andrei


Re: Allocating Heap/GC Storage upon Default Construction of RC Containers

2016-09-22 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 9/21/16 8:49 AM, Nordlöw wrote:

Is there any way to make a default constructor of a struct container
allocate/initialize an internal pointer?

I need this in a container with RC behaviour similar to

struct Container
{
this()// this is currently forbidden:
{
_rcStore = emplace(cast(RCStore*)malloc(RCStore.size), null, 0);
}

private:
static struct RCStore
{
T* store;
size_t refCount;
}
RCStore* _rcStore;
}

If I can't modify default construction in containers such as `Container`
it is gonna behave in the same confusing way as empty AA's do for
(novel) D developers. Namely that the assignment of uninitialized AA's
has copy semantics and non-empty AA's have reference semantics.

I believe Andralex has spoken about this being a problem that should be
fixed if possible.


Sadly, not currently. I realize this makes certain designs more 
difficult. -- Andrei




Re: Dual conditions in D and Python

2015-05-23 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 5/21/15 2:35 PM, Ali Çehreli wrote:

On 05/21/2015 12:44 PM, Meta wrote:


All we need is user-defined opIs and then we're really cooking with gas.

if (5 is between(4, 6))
{
 //...
}



We're almost there. :)

bool is_between(T0, T1, T2)(T0 what, T1 min, T2 max)
{
 return (what = min)  (what = max);
}

void main()
{
 if (5.is_between(4, 6)) {
 // ...
 }
}


In fact we'll be there with 2.068:

http://dlang.org/phobos-prerelease/std_algorithm_sorting.html#.ordered

if (ordered(4, 5, 6)) { ... }
if (strictlyOrdered(4, 5, 6)) { ... }


Andrei



Re: druntime build failing because of masm386 problems

2015-01-21 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 1/18/15 10:19 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Sunday, January 18, 2015 23:21:43 jollie via Digitalmars-d-learn wrote:

Jonathan M Davis via Digitalmars-d-learn digita
lmars-d-le...@puremagic.com Wrote in message:

It's been a while since I did anything in Windows with D, and unfortunately,
I need to again, and now I can't get druntime to build. I'm getting this
lovely error:

dmc -c  src\rt\minit.asm
masm386 -DM_I386=1 -D_WIN32 -Mx src\rt\minit.asm;

Can't run 'masm386', check PATH
Error: 'dmc' not found


I know that I've seen this before, but I can't remember how to fix the
problem. dmc is definitely on my PATH (I successfully built dmd prior to
trying to build druntime), so the error seems to be wrong, for whatever good
that does me. I don't see a masm386 with dmc, so I don't know where that
comes from. Maybe that's part of the problem.

Has anyone seen this problem and figured out how to get around it or fix it?

- Jonathan M Davis




It's been some months since I had this problem pop up, but I just
  ran touch on the minit.obj file so make thought it was up to date
  and used it.


That did the trick. Thanks. It looks like that has to be done after every
time I run clean. That definitely sucks.

- Jonathan M Davis


Can't we just change win32.mak to consider minit.obj part of the 
distribution? -- Andrei




Re: druntime build failing because of masm386 problems

2015-01-21 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 1/18/15 11:22 PM, Jonathan M Davis via Digitalmars-d-learn wrote:

It suggests creating an empty masm386.bat file in a directory which is in
your path (e.g. C:\dm\bin), and then it'll just work, since masm386 will do
nothing. Still, I'm inclined to think that the makefile should be fixed so
that it just uses the provided object file if can't be rebuilt on the system
anyway.


Yah, that's a pretty poor suggestion. -- Andrei


Re: For those ready to take the challenge

2015-01-09 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 1/9/15 6:10 PM, Jesse Phillips wrote:

On Friday, 9 January 2015 at 13:50:29 UTC, eles wrote:

https://codegolf.stackexchange.com/questions/44278/debunking-stroustrups-debunking-of-the-myth-c-is-for-large-complicated-pro



Link to answer in D:
http://codegolf.stackexchange.com/a/44417/13362


Nailed it. -- Andrei


Re: Getting libcurl for 64 bit Windows

2014-06-26 Thread Andrei Alexandrescu via Digitalmars-d-learn

On 6/26/14, 11:11 AM, Mark Isaacson wrote:

Managed to build it successfully I think, but have actually
returned to the problem that initially caused me to want to try
and build the library in the first place:

If I try to build a simple program:

import std.stdio;
import std.net.curl;

void main() {
writeln(Hello world);
}

The program compiles, but does not print Hello World at
runtime... it just stops, and seemingly does nothing.

Trying to determine the root cause of that now.


Mark is my intern, and we're currently blocked by this in creating an 
important demo for tomorrow.


Does anyone have good instructions for building libcurl on Win64, or 
prebuild .lib and .dll files?



Thanks very much,

Andrei


Re: CMake for D

2014-03-24 Thread Andrei Alexandrescu

On 3/24/14, 4:55 PM, Dragos Carp wrote:


Any alternatives??


I moved cmaked2 to github [1], updated and simplified the usage a
little (system cmake patch not necessary anymore). You can give
it a try. Dub registry support is also on the way.

Regards
Dragos


[1] - https://github.com/dcarp/cmake-d


Fantastic, thanks Dragos!! A fellow Romanian it seems :o) -- Andrei



Re: User defined attributes use

2013-09-16 Thread Andrei Alexandrescu

On 9/16/13 11:56 AM, Namespace wrote:

I hate this NotNull struct hack. It is the same crap as the current
scope solution.


Scoped variables in the language were a lot worse.


BTW: I'm curious which built-in feature will be removed
next, maybe AA?


If we're diligent and lucky, hopefully.


An annotation like Foo! f would be much nicer than NotNull!Foo or
@NotNull Foo, but it would be an agreement.


Is annotation the only or main problem?


And I agree absolute, to disable default CTor's by struct's was a huge
mistake. But D is full of those. ;)


They are not disabled. It seems many people are having trouble with 
getting default constructors to evaluate code, so I assume you mean 
that. One possibility (or first step) would be to relax the language to 
allow CTFE-executable code in default constructors.



Andrei



Re: What's about virtual?

2013-09-09 Thread Andrei Alexandrescu

On 9/9/13 12:47 PM, H. S. Teoh wrote:

On Mon, Sep 09, 2013 at 09:37:07PM +0200, Namespace wrote:

It's been a while since Manu convinced Walter and Andrei to
introduce a virtual Keyword and to change the default from virtual
methods to final methods.
Anything new? Anybody working on that? I would love to see that
soon.


This is going to break a lot of code. We'd need some kind of deprecation
path. And even then, it may anger a lot of existing users.


T


After I've seen a pretty cool demo of clang-modernize 
(http://clang.llvm.org/extra/ModernizerUsage.html), I think the best way 
to attack this and similar problems is to add a class hierarchy 
analyzer: a command-line utility that is fed an entire project and adds 
as many 'final' as possible without changing semantics.


Time has come to migrate such functionality to tools. We keep on telling 
that nobody uses the tools but it seems experience contradicts that 
belief.



Andrei



help a potential binding author?

2013-06-21 Thread Andrei Alexandrescu

http://stackoverflow.com/questions/17235375/how-to-create-bindings-qml-to-d

Andrei


Re: Regarding partition_copy

2013-05-05 Thread Andrei Alexandrescu

On 5/5/13 7:22 AM, bearophile wrote:

Splitting a range in two according to a predicate is a common
enough need. How do you translate this C++/STL idiom to D/Phobos?


vectorint source_data;
...
vectorint good_stuff, bad_stuff;
partition_copy(begin(source_data), end(source_data),
inserter(good_stuff, end(good_stuff)),
inserter(bad_stuff, end(bad_stuff)),
is_good);


If this is not handy to implement with the current Phobos, is it
worth adding a similar function to Phobos?

Thank you,
bye,
bearophile


Yah, I've been thinking of adding a new category of functions that 
generate multiple ranges and conversely merge multiple ranges into one.


A possibility here is to define segregate!pred(range) that takes a 
predicate and a range and returns a tuple of two ranges (for true and 
false values of the predicate). The two ranges can be consumed at 
different rates etc.


That won't work with input ranges though.


Andrei


Re: D is totally useless

2013-05-02 Thread Andrei Alexandrescu

On 5/1/13 6:20 PM, Jesse Phillips wrote:

On Wednesday, 1 May 2013 at 22:33:40 UTC, John Colvin wrote:

On Wednesday, 1 May 2013 at 21:26:32 UTC, Temtaime wrote:

Because it's full of a drawing and many other functions. OpenGL is
part of WinAPI.


Is that strictly speaking true? I didn't think opengl was part of the
windows api (WinAPI) itself.


It is not. DirectX isn't even part of the WinAPI and that is what
Microsoft backs.


Probably would make for a good deimos addition.

Andrei


Re: Quadratic time to sort in a simple case?

2013-04-23 Thread Andrei Alexandrescu

On 4/22/13 5:52 PM, bearophile wrote:

Andrei Alexandrescu:


c) add introspection to the algorithm, i.e. if an attempt to partition
hits the worst case or near worst case, just try another pivot instead
of moving forward with the sorting stage.


Or switch to a sort that is guaranteed to have a pseudo-linear complexity.
I am not sure, but I think the C++ STL sort does this.


There's not the C++ STL sort. Any implementation is fine as long as it 
has O(n log n) expected run time.



TimSort is slower on average.


Here it's not easy to define what average is. Python devs think that a
common case is an array with mostly sorted data with unsorted data at
the end.


Note that in this case it's sorted data followed by its smallest 
element. (Changing the value does improve sped.) This is hitting a 
corner case: median of 3 will pick the smallest element, which will lead 
to an inefficient partition. I haven't looked at the code, but it seems 
the smallest element again makes it to the beginning and the end of the 
array so it's again picked etc.


One simple solution to this (which I forgot to mention) is picking a 
pivot at random.



Andrei


Re: Quadratic time to sort in a simple case?

2013-04-22 Thread Andrei Alexandrescu

On 4/19/13 6:37 PM, Ivan Kazmenko wrote:

That [SwapStrategystable] uses the TimSort that contains
the optimization you look for.

alias mySort = sort!(a  b, SwapStrategy.stable);


Thank you, these are good for now.

A seemingly easy way to provide the choice globally would be to have an
assignable SwapStrategy.default in std.algorithm... or would that be a
bad design decision to have such a global state?


Yah, that would mean one can't reason what a piece of code does without 
knowing what the context was.



Consider a sorted array. Append an element that is less than all the
previous elements. Then sort the array again by the sort function
from std.algorithm.


If you know that, then don't do a sort. Make some free space in
the array, shift the items, sort just the first part with a slice.


That behavior isn't always easy to predict.

Still, I think this is a problem in Phobos which should be fixed. In
most implementations of quicksort (even middle-element, the easiest to
come up with), one expects it to perform in O(n log n) with probability
close to one, except on some artificially constructed cases.

On a side note, I'm surprised that median-of-three (getPivot in
std.algorithm) fails at such a simple test, so I had something new to
learn there, too. If I just comment out the switch in getPivot and
return mid directly, it becomes fast enough in this case.


I could have sworn I made getPivot choose at random at some point. I 
agree this should be fixed; there are a number of possibilities:


a) choose median of five

b) if the array is large, sort a stride of it first (e.g. 1%) then 
choose the pivot as the median point of that stride


c) add introspection to the algorithm, i.e. if an attempt to partition 
hits the worst case or near worst case, just try another pivot instead 
of moving forward with the sorting stage.



Another view at this is the following. As far as I know by now, one of
the points beyond D (and Phobos) design is to have everything safe by
default, but faster if you want it explicitly and you know what you are
doing.


That view of safety is different (memory safety).


In this particular case, that would mean having a worst-case O(n
log n) sort, and/or a stable sort, by default - but with the opportunity
to switch to the (time-wise and stability-wise) unsafe quicksort if you
really need the extra speedup and know what you are doing. So, why isn't
TimSort the default?


TimSort is slower on average.


Andrei


Re: Is this range behaviour correct?

2013-03-14 Thread Andrei Alexandrescu

On 3/14/13 6:45 AM, Andrea Fontana wrote:

On Thursday, 14 March 2013 at 10:08:53 UTC, Andrea Fontana wrote:

I'm trying to implement a db cursor as simple InputRange. I can't
implement as forward range because using c-api I can't clone/save cursor.

I wrote popFront() front() and empty() method and my range works fine.

Using on a foreach() it browses all elements inside range until range
is exausthed.

If i do another foreach() it doesn't restart (empty() is called and it
returns true, of course).

Is it the correct behaviour of a inputrange or have i missed something?


Maybe I got it. I implemented this range as class, so it is passed as
reference to foreach, usually ranges are struct and passed by value. I
guess this is the problem.

Is there a way to make a class based range like a struct one?


Add .save() to it.

Andrei


Re: how to get top N distinct elements from range?

2013-03-09 Thread Andrei Alexandrescu

On 3/8/13 1:34 PM, Chris Cain wrote:

On Friday, 8 March 2013 at 18:17:22 UTC, bearophile wrote:

auto firstDistinct(Range)(Range r, in size_t n) {
bool[ForeachType!Range] mySet;

return r.filter!((k) {
if (k in mySet)
return false;
mySet[k] = true;
return true;
}).take(n);
}



I have to say, that's a great example of beautiful simplicity in
programming. Bravo.


Yah, impressive. Nice work bearophile.

Andrei




Re: structs are now lvalues - what is with auto ref?

2012-12-24 Thread Andrei Alexandrescu

On 12/24/12 12:57 PM, Jonathan M Davis wrote:

On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:

An important smoking gun is C++'s min(), which is allows writing unsafe
code without casts.

const int  haveANiceDay = min(4, 5);


But what does that have to do with const  for function parameters?


min takes its parameters by const ref.

Andrei


Re: structs are now lvalues - what is with auto ref?

2012-12-24 Thread Andrei Alexandrescu

On 12/24/12 1:05 PM, monarch_dodra wrote:

On Monday, 24 December 2012 at 17:37:54 UTC, Andrei Alexandrescu wrote:

On 12/24/12 12:11 PM, Jonathan M Davis wrote:

On Monday, December 24, 2012 17:55:23 Minas Mina wrote:

On Sunday, 23 December 2012 at 23:59:55 UTC, Jonathan M Davis

wrote:

On Monday, December 24, 2012 00:48:01 Namespace wrote:
but Andrei is dead set against

- Jonathan M Davis


Why?


He's convinced that it's caused problems for C++ and was a major
mistake. You
can search the newsgroup for discussions on it. The most recent one
which
involved Andrei was in the beta group:

http://forum.dlang.org/post/4f84d6dd.5090...@digitalmars.com

- Jonathan M Davis


An important smoking gun is C++'s min(), which is allows writing
unsafe code without casts.

const int haveANiceDay = min(4, 5);


Andrei


But that example actually works correctly.


No.

Andrei


Re: structs are now lvalues - what is with auto ref?

2012-12-24 Thread Andrei Alexandrescu

On 12/24/12 1:20 PM, Jonathan M Davis wrote:

On Monday, December 24, 2012 22:11:58 Dmitry Olshansky wrote:

12/24/2012 9:57 PM, Jonathan M Davis пишет:

On Monday, December 24, 2012 12:37:54 Andrei Alexandrescu wrote:

An important smoking gun is C++'s min(), which is allows writing unsafe
code without casts.

const int  haveANiceDay = min(4, 5);


But what does that have to do with const  for function parameters?


It relates directly as one may then pass the result of min to fun(const
ref T);


But the temporary has to be kept in existence for the duration of the
statement, so I don't see how that's a problem.


The problem occurs of course once haveANiceDay is actually used.


The temporary will last as
long as the function call does. Worst case, the function returns a const ref
to its parameter, but either that ref is used as part of the same statement,
and so the temporary continues to exist and there are no problems, or it's
copied when it's assigned to a variable, and there are no problems. It's the
fact that you can have a const  local variable that breaks things, and D
doesn't allow that.


The very binding of rvalues to const ref would allow that breakage. We 
can't allow that to happen.



Andrei



Re: structs are now lvalues - what is with auto ref?

2012-12-24 Thread Andrei Alexandrescu

On 12/24/12 1:49 PM, Jonathan M Davis wrote:

On Monday, December 24, 2012 13:45:10 Andrei Alexandrescu wrote:

The very binding of rvalues to const ref would allow that breakage. We
can't allow that to happen.


But it's only bound for the length of the statement. After that, the binding
can no longer exist (as the binding was a function parameter). And as I
understand it, temporaries only go out of scope once the statement has
completed. So,

foo(bar(min(5, 7)));

wouldn't be a problem no matter what bar or foo did, because no reference to
5, 7, or the return values of any of the functions could be kept.


Actually D's rules are different from C++'s in that regard; Walter 
mentioned D is more sanguine about destroying data. I'll check with him.



It's being
able to do

const int  i = foo(bar(min(5, 7)));

which would allow a reference to be kept around, which D disallows.


I now see what you mean, thanks. We need to disallow taking the address 
of that ref, but that's already planned.



Andrei


Re: structs are now lvalues - what is with auto ref?

2012-12-24 Thread Andrei Alexandrescu

On 12/24/12 2:46 PM, anonymous wrote:

On Monday, 24 December 2012 at 18:50:12 UTC, Jonathan M Davis wrote:

const int i = foo(bar(min(5, 7)));

which would allow a reference to be kept around, which D disallows.


Does it?

const(int)* i = foo(bar(min(5, 7)));


We plan to forbid that.

Andrei


Re: finding composed structs

2012-10-30 Thread Andrei Alexandrescu

On 10/30/12 4:17 PM, Tobias Pankrath wrote:

On Tuesday, 30 October 2012 at 20:16:12 UTC, Tobias Pankrath
wrote:



In the meantime you can use this function template to compare structs
field by field.

bool oneStepEqual(T,F)(ref T lhs, ref F rhs)
if(is(Unqual!T == Unqual!F)  is(T == struct))
{
bool result = true;
foreach(mem; __traits(allMembers, T))
{
static if(!is(typeof(__traits(getMember, T, mem)) == function))
{
result = result  (__traits(getMember, lhs, mem) ==
__traits(getMember, rhs, mem));
}
}
return result;
}


Beautiful version: http://dpaste.dzfl.pl/2340d73f


Y u no short circuit?

Andrei


Re: Narrow string is not a random access range

2012-10-23 Thread Andrei Alexandrescu

On 10/23/12 11:36 AM, mist wrote:

Was thinking on this topic after seeing this:
http://stackoverflow.com/questions/13014999/cannot-slice-taker-from-std-range-in-d

Still can't understand rationale here. Why native slicing / random
access is allowed for narrow strings, but trait explicitly negates this?


Historical mistake.

Andrei


Re: Narrow string is not a random access range

2012-10-23 Thread Andrei Alexandrescu

On 10/23/12 12:35 PM, Andrei Alexandrescu wrote:

On 10/23/12 11:58 AM, mist wrote:

On Tuesday, 23 October 2012 at 15:55:23 UTC, Andrei Alexandrescu wrote:

On 10/23/12 11:36 AM, mist wrote:

Was thinking on this topic after seeing this:
http://stackoverflow.com/questions/13014999/cannot-slice-taker-from-std-range-in-d



Still can't understand rationale here. Why native slicing / random
access is allowed for narrow strings, but trait explicitly negates
this?


Historical mistake.

Andrei


Is string random access gonna be deprecated some day then or this is
considered a mistake we need to get used to? :)


Walter is unconvinced it's a mistake, which doesn't make it any easier.
If I had my way, I'd require people to write str.rep[6] to access the
sixth byte in the representation of a UTF-8 or UTF-16 string. It would
make D's strings from great to indistinguishable from perfect.

Andrei


s/byte/code unit/


Re: Narrow string is not a random access range

2012-10-23 Thread Andrei Alexandrescu

On 10/23/12 11:58 AM, mist wrote:

On Tuesday, 23 October 2012 at 15:55:23 UTC, Andrei Alexandrescu wrote:

On 10/23/12 11:36 AM, mist wrote:

Was thinking on this topic after seeing this:
http://stackoverflow.com/questions/13014999/cannot-slice-taker-from-std-range-in-d


Still can't understand rationale here. Why native slicing / random
access is allowed for narrow strings, but trait explicitly negates this?


Historical mistake.

Andrei


Is string random access gonna be deprecated some day then or this is
considered a mistake we need to get used to? :)


Walter is unconvinced it's a mistake, which doesn't make it any easier. 
If I had my way, I'd require people to write str.rep[6] to access the 
sixth byte in the representation of a UTF-8 or UTF-16 string. It would 
make D's strings from great to indistinguishable from perfect.


Andrei


Re: Sorting algorithms

2012-10-17 Thread Andrei Alexandrescu

On 10/17/12 3:07 PM, Philippe Sigaud wrote:

On Mon, Oct 15, 2012 at 5:52 PM, Andrei Alexandrescu
seewebsiteforem...@erdani.org  wrote:


I wanted to investigate small sorts using sorting networks for ages, but
never got around to it. That's important for quicksort because it produces
many small arrays that need sorting.

Could you also test for very small sizes (2 to 4) and essentially test for
1-increment speed up to, say, 30 elements? I assume that's where the major
wins come. I think we could use CT-generated sorting networks for arrays
below a specific size. The converse risk is growth of generated code.


Here:

http://dpaste.dzfl.pl/42fac981

I don't know if the benchmarking code is OK. I substract a reference
because randomly shuffling an array takes some time.

Results for my computer (smaller ratio means faster network sort
compared to std.algorithm.sort)

Size 1, network: 2.10, std.algorithm.sort: 15.86, ratio network/std.algo: 0.13
Size 2, network: 2.23, std.algorithm.sort: 14.26, ratio network/std.algo: 0.16
Size 3, network: 6.22, std.algorithm.sort: 20.75, ratio network/std.algo: 0.30
Size 4, network: 8.25, std.algorithm.sort: 28.36, ratio network/std.algo: 0.29
Size 5, network: 18.54, std.algorithm.sort: 39.02, ratio network/std.algo: 0.48
Size 6, network: 20.12, std.algorithm.sort: 45.58, ratio network/std.algo: 0.44
Size 7, network: 27.49, std.algorithm.sort: 55.53, ratio network/std.algo: 0.50
Size 8, network: 33.91, std.algorithm.sort: 66.02, ratio network/std.algo: 0.51

[snip]

Looking great, thanks. I'm on the road with little time and 
connectivity, but I want to encourage you with integrating this with 
std.sort. There seems to be a big gain drop off at size 9, so we could 
use sorting networks for size = 8. (I'm also worried about generated 
code size.) So next step would be to integrate the sorting network 
within std.sort and see how it works there.


Please don't let this good work go to waste!


Andrei



Re: Sorting algorithms

2012-10-15 Thread Andrei Alexandrescu

On 10/15/12 8:11 AM, Philippe Sigaud wrote:

On Mon, Oct 15, 2012 at 1:04 PM, Era Scarecrowrtcv...@yahoo.com  wrote:

On Monday, 15 October 2012 at 09:18:12 UTC, Era Scarecrow wrote:


So an example area to be sorted with 16 elements would take on average
about 100 compares while theoretically you can do it in half that number.



  Correction. 16 numbers would be solved in about 49 compares while an
optimal sorting takes about 45. And for 21 numbers about 74 compares while
optimally about 63.

  These numbers don't seem that large, but at the same time they do.


Somewhat related: I once played with sorting networks and how to
generate them at compile time in D. It's in template tutorial on
Github. Here are some results:

https://github.com/PhilippeSigaud/D-templates-tutorial/blob/master/templates_around.tex#L560

Discarding LaTeX markup:


nSortingStandardratio
  networksort
5324532 1.642
10   55510961.975
15   80316792.091
20   1154   23142.005
25   1538   32442.109
30   2173   35081.614
35   4075   41201.011
40   5918   52690.890
45   7479   59590.797
50   9179   64350.701

Were n is the (predetermined) number of elements in an array and a
ratio of 2.0 means sorting networks are twice faster than
std.algo.sort in this particular case.


I wanted to investigate small sorts using sorting networks for ages, but 
never got around to it. That's important for quicksort because it 
produces many small arrays that need sorting.


Could you also test for very small sizes (2 to 4) and essentially test 
for 1-increment speed up to, say, 30 elements? I assume that's where the 
major wins come. I think we could use CT-generated sorting networks for 
arrays below a specific size. The converse risk is growth of generated code.



Andrei


Re: Best way to store postgresql's numeric type in D?

2012-10-10 Thread Andrei Alexandrescu

On 10/10/12 5:35 AM, denizzzka wrote:

It is up to 131072 digits before the decimal point; up to 16383 digits
after the decimal point.


For now, I guess string would be it.

Andrei


Re: Unexpected OPTLINK termination

2012-10-09 Thread Andrei Alexandrescu

On 10/9/12 12:30 PM, Faux Amis wrote:

On a side-note, why is rdmd picky about argument order?

 dmd test.d -I..\include


Because anything after the program is considered an argument to the program.

Andrei


Re: Unexpected OPTLINK termination

2012-10-09 Thread Andrei Alexandrescu

On 10/9/12 4:38 PM, Andrej Mitrovic wrote:

On 10/9/12, Andrei Alexandrescuseewebsiteforem...@erdani.org  wrote:

On 10/9/12 12:30 PM, Faux Amis wrote:

On a side-note, why is rdmd picky about argument order?

  dmd test.d -I..\include


Because anything after the program is considered an argument to the
program.

Andrei



I think this is a fairly common user error. Perhaps we could consider
introducing --args which would treat all args as compiler args except
the ones set with --args which are for the app itself?


I'd be bummed because that's quite a logical decision, and how other 
interpreters do it.


Andrei


Re: Remove element from DList

2012-10-07 Thread Andrei Alexandrescu

On 10/7/12 5:15 AM, Jonathan M Davis wrote:

On Sunday, October 07, 2012 10:09:06 Russel Winder wrote:

Removal from a singly-linked list can be O(1) as well, it depends
whether you are deleting using an iterator in progress.


IIRC that dcollections' singly-linked list is like this, but
std.container.SList definitely isn't. I'm not a big fan of singly-linked lists
in the first place and tend to think that they're useless, but std.container's
is particularly bad in that regard.


Singly-linked lists are limited in functionality as containers, but very 
fast for a few applications. It's quite likely someone would choose a 
singly-linked list primarily for performance.


Some more functionality could be implemented for SList if it used for 
its range a pointer pointing one before the first element. But that 
would have meant an extra indirection for each and every access, undoing 
a large fraction of performance benefits. That's why I chose the 
primitives the way I did.



Andrei



Re: next power of 2

2012-10-06 Thread Andrei Alexandrescu

On 10/6/12 4:48 PM, ref2401 wrote:

is there any Phobos function to calculate the next power of 2 of the
specified number?


Use 1U  bsr(x).

http://dlang.org/phobos/core_bitop.html#bsr


Andrei


Re: next power of 2

2012-10-06 Thread Andrei Alexandrescu

On 10/6/12 4:57 PM, Dmitry Olshansky wrote:

On 07-Oct-12 00:54, Dmitry Olshansky wrote:

On 07-Oct-12 00:48, ref2401 wrote:

is there any Phobos function to calculate the next power of 2 of the
specified number?


No though it's reinvented in a couple of places I think.

Anyway this should work for unsigned numbers:

import core.bitop;
T nextPow2(T)(T x){
return x == 0 ? 1 : 1^^(bsr(x)+1);
}


Yikes, 1(bsr(x)+1) or 2 ^^ (bsr(x)+1) ...
still haven't got used to 2^^x notation compared to shifts.


That's right, apologies for my buggy suggestion and my suggestion of a 
buggy suggestion :o).


Andrei



Re: next power of 2

2012-10-06 Thread Andrei Alexandrescu

On 10/6/12 4:54 PM, Dmitry Olshansky wrote:

On 07-Oct-12 00:48, ref2401 wrote:

is there any Phobos function to calculate the next power of 2 of the
specified number?


No though it's reinvented in a couple of places I think.

Anyway this should work for unsigned numbers:

import core.bitop;
T nextPow2(T)(T x){
return x == 0 ? 1 : 1^^(bsr(x)+1);
}


That's right, apologies for my buggy suggestion.

Andrei



Re: Testing for template argument being result of takeExactly

2012-09-26 Thread Andrei Alexandrescu

On 9/26/12 9:50 AM, monarch_dodra wrote:

struct S{};

is(typeof(takeExactly(S, 1)) == S) //false
is(S == typeof(takeExactly(S, 1))) //Error: template
std.range.takeExactly does not match any function template declaration


Neither should work. The expression should be takeExactly(S.init, 1).

Andrei


Re: Testing for template argument being result of takeExactly

2012-09-23 Thread Andrei Alexandrescu

On 9/23/12 8:47 AM, Timon Gehr wrote:

import std.range, std.traits;
import std.stdio;
template Hello(R) if(is(typeof(R._input.takeExactly(2)) == R)){
alias R Hello;
}


That's the nicest. Regarding availability of _input, I meant to make 
it available systematically as input for ranges where the notion makes 
sense.


Andrei


Re: Variant opArithmetic

2012-09-18 Thread Andrei Alexandrescu

On 9/18/12 1:36 PM, cal wrote:

Variant tries to mimic D's built-in rules for arithmetic conversions but:

import std.variant, std.stdio;
void main()
{
auto v1 = Variant(4.5f);
auto v2 = Variant(3.5f);
writeln((v1+v2).type()); // double
}

The reason is Variant doesn't try to convert to float in opArithmetic
(it's is easily fixed). But is it intentional?


I wrote this:

writeln(typeof(4.5f + 3.5f).stringof);

To my surprise, the reported type was float, not double. Well that means 
it's a bug in Variant, could you please make a bug report (and hopefully 
a pull request fixing it)?



Thanks,

Andrei


Re: rdmd exception def multiple files

2012-08-29 Thread Andrei Alexandrescu

On 8/29/12 3:47 PM, Charles Hixson wrote:

Where should I look to better understand
rdmd? I expected to need to list all the local files that were needed,
but clearly that's the wrong approach.


http://dlang.org/rdmd.html

To my surprise, it's not in the top Google search results. However, 
Dmitry's shadow page is: http://blackwhale.github.com/rdmd.html


Andrei


Re: rdmd exception def multiple files

2012-08-29 Thread Andrei Alexandrescu

On 8/29/12 4:52 PM, Charles Hixson wrote:

On 08/29/2012 04:15 PM, Andrei Alexandrescu wrote:

On 8/29/12 3:47 PM, Charles Hixson wrote:

Where should I look to better understand
rdmd? I expected to need to list all the local files that were needed,
but clearly that's the wrong approach.


http://dlang.org/rdmd.html

To my surprise, it's not in the top Google search results. However,
Dmitry's shadow page is: http://blackwhale.github.com/rdmd.html

Andrei

Thank you. Unfortunately, that page doesn't address the symptoms that
I've been experiencing, which while they don't halt development
certainly confuse it.

It's starting to look as if while I use rdmd I'll need to keep
everything in one file, as otherwise I can't share exceptions between
classes. (And I'm only guessing that the problem is limited to
exceptions, as I haven't tested with other functions.)

Since the small test programs DO call successfully between different
files (including for exceptions) I don't really have a clue as to what's
going on, except that it appears to happen during linking. And combining
the routines into one file appears to fix the problem. And that dmd
doesn't seem to have the same problem. (I.e., if I add a dummy main
routine to the avl.d file, then
dmd -unittest avl.d utils.d
compiles and executes without problems, even though it doesn't do anything.


You should be able to use rdmd for that dependency pattern, and if not 
there's a bug in it. However, nobody can work on that without a test case.


Andrei



Re: Why must bitfields sum to a multiple of a byte?

2012-08-02 Thread Andrei Alexandrescu

On 8/2/12 5:14 AM, Era Scarecrow wrote:

On Thursday, 2 August 2012 at 09:03:54 UTC, monarch_dodra wrote:

I had an (implementation) question for you: Does the implementation
actually require knowing what the size of the padding is?

eg:
struct A
{
int a;
mixin(bitfields!(
uint, x, 2,
int, y, 3,
ulong, , 3 // - This line right there
));
}

It that highlighted line really mandatory?
I'm fine with having it optional, in case I'd want to have, say, a 59
bit padding, but can't the implementation figure it out on it's own?


The original code has it set that way, why? Perhaps so you are aware and
actually have in place where all the bits are assigned (even if you
aren't using them); Be horrible if you used accidently 33 bits and it
extended to 64 without telling you (Wouldn't it?).


Yes, that's the intent. The user must define exactly how an entire 
ubyte/ushort/uint/ulong is filled, otherwise ambiguities and bugs are 
soon to arrive.



However, having it fill the size in and ignore the last x bits wouldn't
be too hard to do, I've been wondering if I should remove it.


Please don't. The effort on the programmer side is virtually nil, and 
keeps things in check. In no case would the use of bitfields() be so 
intensive that the bloat of one line gets any significance.



Andrei


Re: Why must bitfields sum to a multiple of a byte?

2012-08-02 Thread Andrei Alexandrescu

On 8/2/12 5:26 AM, monarch_dodra wrote:

One of the *big* reasons I'm against having a hand chosen padding, is
that the implementation *should* be able to find out what the most
efficient padding is on the current machine (could be 32 on some, could
be 64 on some)


In my neck of the woods they call that non-portability.

If your code is dependent on the machine's characteristics you use 
version() and whatnot.



Andrei


Re: Why must bitfields sum to a multiple of a byte?

2012-08-02 Thread Andrei Alexandrescu

On 8/2/12 9:48 AM, monarch_dodra wrote:

On Thursday, 2 August 2012 at 12:38:10 UTC, Andrei Alexandrescu wrote:

On 8/2/12 5:26 AM, monarch_dodra wrote:

One of the *big* reasons I'm against having a hand chosen padding, is
that the implementation *should* be able to find out what the most
efficient padding is on the current machine (could be 32 on some, could
be 64 on some)


In my neck of the woods they call that non-portability.

If your code is dependent on the machine's characteristics you use
version() and whatnot.


Well, isn't that the entire point: Making your code NOT dependent on the
machine's characteristics?

By forcing the developer to chose the bitfield size (32 or 64), you ARE
forcing him to make a choice dependent on the machine's characteristics.


I think that's backwards.

Andrei