Re: Adapting foreign iterators to D ranges

2024-04-24 Thread cc via Digitalmars-d-learn

On Wednesday, 24 April 2024 at 05:08:25 UTC, Salih Dincer wrote:
Yes, `opApply()` works! You just need to use `do while()` 
instead of `while()` because it skips the first item.


It depends on the type of structure being consumed, if it 
provides "next" as a direct pointer then yeah you would need to 
consume the item first before iterating to the next in line.  
However some APIs provide an opaque iterator type where you call 
a "next" method to get the first element, IIRC Lua does something 
like this.


Re: Adapting foreign iterators to D ranges

2024-04-23 Thread Salih Dincer via Digitalmars-d-learn

On Tuesday, 23 April 2024 at 06:02:18 UTC, cc wrote:
Just to offer an alternative solution (since it sometimes gets 
overlooked), there is also the `opApply` approach.  You don't 
get full forward range status, and checking whether it's empty 
essentially requires doing something like std.algorithm 
`walkLength`, but if all you need is basic iteration, it can be 
a simpler solution:




Yes, `opApply()` works! You just need to use `do while()` instead 
of `while()` because it skips the first item.


```d
struct Node
{
  int item;
  Node* next;
}

class List
{
  Node* root, iter;

  this(int item = 0)
  {
iter = new Node(item, null);
root = iter;
  }

  List dup()
  {
auto backup = new List();
backup.root = root;
backup.iter = iter;

return backup;
  }

  void insertFront(T)(T item)
  {
(*iter).next = new Node(item, null);
this.Next;
  }

  bool empty() const => iter is null;
  auto front() inout => iter;
  auto popFront()=> iter = this.Next;
  auto getItem() => iter.item;
  auto rewind()  => iter = root;
}

auto Next(List list) => list.iter = list.iter.next;
auto gaussian(T)(T n)=> (n * n + n) / 2;

void main()
{
  import std.stdio;
  enum LIMIT = 10;

  auto list = new List(1);
  foreach(t; 2 .. LIMIT + 1)
  {
list.insertFront(t);
  }

  auto tmp = list.dup;
  list.rewind();

  size_t sum;
  do sum += list.getItem; while(list.Next);
  assert(gaussian(LIMIT) == sum);

  sum.writeln; // 55

  auto next = LIMIT + 1;
  tmp.insertFront(next);
  tmp.rewind();
  sum = 0;

  foreach(t; tmp) sum += t.item;
  assert(gaussian(LIMIT) + next == sum);

  sum.writeln; // 66
  tmp.rewind();

  auto range = Range(tmp);

  foreach(r; range) r.item.write(" ");
  writeln; //  2 3 4 5 6 7 8 9 10 11
  // ? (1) --^
}

struct Range
{
  private List iter;

  int opApply(scope int delegate(Node* t) dg)
  {
while(auto current = iter.Next)
{
  if (auto r = dg(current))
return r;
}
return 0;
  }
}
```

SDB@79




Re: Adapting foreign iterators to D ranges

2024-04-23 Thread cc via Digitalmars-d-learn

On Monday, 22 April 2024 at 11:36:43 UTC, Chloé wrote:
I wish to adapt this interface to a forward range for use with 
foreach and Phobos' range utilities. This amounts to 
implementing empty, front, and popFront, in terms of next and 
some state. But there is a choice to be made regarding the 
first call to next.


Just to offer an alternative solution (since it sometimes gets 
overlooked), there is also the `opApply` approach.  You don't get 
full forward range status, and checking whether it's empty 
essentially requires doing something like std.algorithm 
`walkLength`, but if all you need is basic iteration, it can be a 
simpler solution:


```d
struct Range {
private I iter;
this(I iter) { this.iter = iter; }
int opApply(scope int delegate(T* t) dg) {
while (auto current = next(iter)) {
if (auto r = dg(current))
return r;
}
return 0;
}
}
void main() {
I someIter; // = ...
auto range = Range(someIter);
foreach (const t; range) {
writeln(*t);
}
}
```


Re: Adapting foreign iterators to D ranges

2024-04-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On Monday, 22 April 2024 at 11:36:43 UTC, Chloé wrote:

The first implementation has the advantage is being simpler and 
empty being const, but has the downside that next is called 
even if the range ends up not being used. Is either approach 
used consistently across the D ecosystem?


I always go for the simplest approach. So that means, pre-fill in 
the constructor.


Yes, the downside is, if you don't use it, then the iterator has 
moved, but the range hasn't. But returning to the iterator after 
using the range is always a dicey proposition anyway.


The huge benefit is that all the functions become simple and 
straightforward.


But there is no "right" approach. And using composition, you may 
be able to achieve all approaches with wrappers. Phobos does 
various things depending on what people thought was good at the 
time. It sometimes causes some very unexpected behavior.


I recommend always using the same approach for the same library, 
that way your users know what to expect!


-Steve


Re: Adapting foreign iterators to D ranges

2024-04-22 Thread Alexandru Ermicioi via Digitalmars-d-learn

On Monday, 22 April 2024 at 11:36:43 UTC, Chloé wrote:
The first implementation has the advantage is being simpler and 
empty being const, but has the downside that next is called 
even if the range ends up not being used. Is either approach 
used consistently across the D ecosystem?


You can also place initialization logic inside front, then empty 
could become const.


I don't think there is a preffered way of initializing such 
ranges, so imho consider what's best for your use case.




Adapting foreign iterators to D ranges

2024-04-22 Thread Chloé via Digitalmars-d-learn

Assume a third-party API of the following signature:

T* next(I iter);

which advances an iterator of sorts and returns the next element, or 
null when iteration is done. No other information about the state of the 
iterator is available.


I wish to adapt this interface to a forward range for use with foreach 
and Phobos' range utilities. This amounts to implementing empty, front, 
and popFront, in terms of next and some state. But there is a choice to 
be made regarding the first call to next.


One could call next during range construction:

struct Range
{
private I iter;
private T* current;
this(I iter) { this.iter = iter; current = next(iter); }
bool empty() const => current is null;
inout(T)* front() inout => current;
void popFront() { current = next(iter); }
}

Or do not call it until the first call to empty:

struct Range
{
private bool initialized;
private I iter;
private T* current;
this(I iter) { this.iter = iter; }
bool empty()
{
if (!initialized) {
current = next(iter);
initialized = true;
}
return current is null;
}
inout(T)* front() inout => current;
void popFront() { current = next(iter); }
}

The first implementation has the advantage is being simpler and empty 
being const, but has the downside that next is called even if the range 
ends up not being used. Is either approach used consistently across the 
D ecosystem?


Need help how to get started with D ranges

2014-03-24 Thread Uranuz
I see that ranges is primitive to organzie universal approach to 
write some algorithms. But I'm using algorithms from the library 
but I still can't start with writing my own algorithms based on 
ranges. For example I have the following function written without 
ranges. I want to improve it and make it working with different 
types of strings (char[], string, wchar[], etc...). So could 
someone give me an example how to rewrite this function in 
`range`-style?


//Parses HTML form data
dstring[dstring] parseFormData2(dstring queryStr)
{   size_t LexStart = 0;
dstring curKey;
dstring curValue;
for( size_t i = 0; i  queryStr.length; ++i )
{   if( queryStr[i] == '=' )
{   curKey = queryStr[LexStart..i].idup;
curValue = null;
LexStart = i+1;
}
if( (queryStr[i] == '') || (i+1 == queryStr.length) )
		{	curValue = queryStr[ LexStart .. (i+1 == queryStr.length) ? 
++i : i ].idup;

if( curKey.length  0)
{   result[curKey] = curValue;
//result[curKey] ~= curValue;
}
curKey = null;
LexStart = i+1;
}
}
return result;
}


Re: Need help how to get started with D ranges

2014-03-24 Thread John Colvin

On Monday, 24 March 2014 at 12:13:43 UTC, Uranuz wrote:
I see that ranges is primitive to organzie universal approach 
to write some algorithms. But I'm using algorithms from the 
library but I still can't start with writing my own algorithms 
based on ranges. For example I have the following function 
written without ranges. I want to improve it and make it 
working with different types of strings (char[], string, 
wchar[], etc...). So could someone give me an example how to 
rewrite this function in `range`-style?


//Parses HTML form data
dstring[dstring] parseFormData2(dstring queryStr)
{   size_t LexStart = 0;
dstring curKey;
dstring curValue;
for( size_t i = 0; i  queryStr.length; ++i )
{   if( queryStr[i] == '=' )
{   curKey = queryStr[LexStart..i].idup;
curValue = null;
LexStart = i+1;
}
if( (queryStr[i] == '') || (i+1 == queryStr.length) )
		{	curValue = queryStr[ LexStart .. (i+1 == queryStr.length) ? 
++i : i ].idup;

if( curKey.length  0)
{   result[curKey] = curValue;
//result[curKey] ~= curValue;
}
curKey = null;
LexStart = i+1;
}
}
return result;
}


Have you read this: http://ddili.org/ders/d.en/ranges.html ?


Re: Need help how to get started with D ranges

2014-03-24 Thread Uranuz

Have you read this: http://ddili.org/ders/d.en/ranges.html ?


Yes I have read it. It's difficult to formulate the question in 
English bu I'l try. In this example I searching for special 
symbols '' and '='. So when symbol found I use *save* method of 
range to remember start of *name* or *value* string of URL 
encoded param. Then I trying to find next special symbol. And 
when I found it I need to take a slice and insert in result AA. 
Should input range be RandomAccess for it? And if it's not random 
access range should should I append this substring by symbol to 
some temp variable and then (when delimiter found) insert into 
Associative Array. So result is that I will implement two 
different behaviours for InputRange and for RandomAccessRange. Am 
I right or not?




Re: Need help how to get started with D ranges

2014-03-24 Thread Uranuz
I have another question. For example I have some range with input 
data (for example some array). I using method popFront() to 
iterate to next element. Then with property front I check element 
if it has some value. Then I *save* it. But how could I get 
position of this derived range in original range without 
overhead. As I see it is only possible via additional variable 
that will keep this position. In this case I can't understand 
what is the benefit of range over iterators or simply iterating 
using some integral index. I should admit that I haven't used 
iterators a lot in C++ so I don't know all of it's possibilities/ 
advantages. It's why I asking.


In my algorithms for parsing some strings I often save positions 
of beginings of some tokens in order to take a slice and put it 
into some buffer. But for opearting with them in terms of ranges 
I need to have RandomAccessRange, because (as far as I 
understand) only it have ability to take a slice. But with input 
I will need to operate (save parsed data) element-wise. And this 
will realocate and slow execution. What is preferable startegy 
opearating with ranges that will be flexible and productive?


Re: Need help how to get started with D ranges

2014-03-24 Thread monarch_dodra

On Monday, 24 March 2014 at 14:12:58 UTC, Uranuz wrote:

Have you read this: http://ddili.org/ders/d.en/ranges.html ?


Yes I have read it. It's difficult to formulate the question in 
English bu I'l try. In this example I searching for special 
symbols '' and '='. So when symbol found I use *save* method 
of range to remember start of *name* or *value* string of URL 
encoded param. Then I trying to find next special symbol. And 
when I found it I need to take a slice and insert in result AA. 
Should input range be RandomAccess for it? And if it's not 
random access range should should I append this substring by 
symbol to some temp variable and then (when delimiter found) 
insert into Associative Array. So result is that I will 
implement two different behaviours for InputRange and for 
RandomAccessRange. Am I right or not?


If you want to be able to *slice*, then you need an 
`RandomAccessRange` with `hasSlicing`.


a RandomAccessRange is a special kind of ForwardRange, which 
itself is an Input Range.


Re: D Ranges

2013-09-16 Thread Chris

On Monday, 16 September 2013 at 13:05:56 UTC, Chris wrote:
On Saturday, 14 September 2013 at 02:10:13 UTC, Jesse Phillips 
wrote:


There isn't a guide in the manner you desire.

In my experience I generally don't hold any more data than the 
value returned by front (to prevent recalculation). Right now 
I don't recall what situations I've needed to store the 
intermediary data,


but I know how you feel about having a input rang which is 
like an output range simply returning a range to provide the 
chaining ability.




Yes, this occurs sometimes. But I think it's due to my lack of 
experience with ranges, that's why I was asking, if there was a 
rough guide. I don't think I really need to store intermediate 
data in my components.


I'm not sure, however, if I should slowly migrate from OOP to 
structs. A of now I use them in two scenarios:


1. input / output ranges (flexible and interchangeable 
workhorses)
2. storage of user defined data types, e.g. you could have a 
struct like this for an entry in a dictionary:


struct LexEntry {
  string lemma = digital;
  string transcription = Some IPA symbols;
  string[] definition = [1. bla bla, 2. bla bla];
}

At the moment, I use a lot of singletons in my program, because 
a lot of the data and data processing is handled by designated 
classes that do not to be reinstantiated. They just sit there 
waiting for input. In fact, without even noticing it, I 
designed parts of my program in an OO fashion that, in a way, 
makes OOP superfluous. So I'm beginning to wonder whether 
classes are really necessary. If I need features like 
sublcassing, I could just right another input range and add it 
to the chain. I'm still hesitant because a. if it's not broke, 
don't fix it and b. there might be some usage scenario when 
I'll need OO design and that I cannot yet foresee. But I agree 
that OO design is hard to unittest, it's not easy to single out 
a component and test it, because it's like a neurological 
network.


that do not _have_ to be reinstantiated
 I could just right = write (sorry, it's the Monday bug in my 
head!)


Re: D Ranges

2013-09-16 Thread Chris
On Saturday, 14 September 2013 at 02:10:13 UTC, Jesse Phillips 
wrote:


There isn't a guide in the manner you desire.

In my experience I generally don't hold any more data than the 
value returned by front (to prevent recalculation). Right now I 
don't recall what situations I've needed to store the 
intermediary data,


but I know how you feel about having a input rang which is like 
an output range simply returning a range to provide the 
chaining ability.




Yes, this occurs sometimes. But I think it's due to my lack of 
experience with ranges, that's why I was asking, if there was a 
rough guide. I don't think I really need to store intermediate 
data in my components.


I'm not sure, however, if I should slowly migrate from OOP to 
structs. A of now I use them in two scenarios:


1. input / output ranges (flexible and interchangeable 
workhorses)
2. storage of user defined data types, e.g. you could have a 
struct like this for an entry in a dictionary:


struct LexEntry {
  string lemma = digital;
  string transcription = Some IPA symbols;
  string[] definition = [1. bla bla, 2. bla bla];
}

At the moment, I use a lot of singletons in my program, because a 
lot of the data and data processing is handled by designated 
classes that do not to be reinstantiated. They just sit there 
waiting for input. In fact, without even noticing it, I designed 
parts of my program in an OO fashion that, in a way, makes OOP 
superfluous. So I'm beginning to wonder whether classes are 
really necessary. If I need features like sublcassing, I could 
just right another input range and add it to the chain. I'm still 
hesitant because a. if it's not broke, don't fix it and b. there 
might be some usage scenario when I'll need OO design and that I 
cannot yet foresee. But I agree that OO design is hard to 
unittest, it's not easy to single out a component and test it, 
because it's like a neurological network.


Re: D Ranges

2013-09-15 Thread monarch_dodra
On Saturday, 14 September 2013 at 06:18:02 UTC, Jonathan M Davis 
wrote:

On Friday, September 13, 2013 23:07:03 H. S. Teoh wrote:
OTOH, I find myself switching to classes just to get the 
reference
semantics in other cases, even if I never actually do any 
inheritance.
Trying to do reference semantics with structs, while certainly 
possible,
is just too error-prone IME. Just a few days ago, I 
encountered what
looked like a nasty functionality bug in my program, only to 
eventually
discover that it was caused by a missing 'ref' in a function's 
struct
parameter, so updates to the struct didn't persist as the code 
assumed
it would. I found myself seriously considering using classes 
instead,

just for the default ref semantics.


In general, if you want to have structs with reference 
semantics, it's
probably better to just give them reference semantics by making 
it so that any
of their members which are value types are on the heap or by 
putting all of
the struct's guts on the heap. At some point, it becomes 
debatable as to
whether that's better than using a class, but it does have less 
overhead.
There's also RefCounted, which does incur the bookkeeping 
overhead of the
refcounting, but it does make it so that the memory is freed as 
soon as you

don't need the object anymore.

- Jonathan M Davis


I have a few issues with ref counted.

First, if you *ever* place one in an array or an AA, then you 
will leak. It is NOT designed for simply incorporating reference, 
but for deterministic finalization.


Second, it has an elaborate postblit and opAssign. This is not a 
big issue in itself, but their sole existence does cause dmd to 
generate code that is sub-optimal. It also means it can't take 
the optimal route in a lot of algorithms (array has to emplace 
each element individually, for example).


Finally, a RefCounted will implicitly cast to its payload. I 
think this is *horrible*. Before you know it, the Payload will 
have jettisoned its wrapper, and you'll be operating on your 
value-type payload raw. For example:

void foo(T t);
RefCounted!T myRecCounted;
foo(myRefCounted); //Passes. Oops!

The workaround would be to either require explicit get to go 
from ref counted to payload (breaking existing code), or to 
entirelly wrap the RefCounted as a member inside the struct 
(requires boilerplate code).




Overall, if I need a reference semantic struct, I find it much 
simpler for it to just hold a GC pointer to a payload.


Though to be honest, as H.S. Teoh, I seriously wonder why I even 
bother, when I could just use a final class. With proper private 
constructors + non-member make function, you can make your 
choice outright transparent to the final user too, meaning you 
can fast prototype with classes, and later change to structs if 
you think it is worth it.


Re: D Ranges

2013-09-15 Thread Jonathan M Davis
On Sunday, September 15, 2013 10:39:40 monarch_dodra wrote:
 I have a few issues with ref counted.
 
 First, if you *ever* place one in an array or an AA, then you
 will leak. It is NOT designed for simply incorporating reference,
 but for deterministic finalization.
 
 Second, it has an elaborate postblit and opAssign. This is not a
 big issue in itself, but their sole existence does cause dmd to
 generate code that is sub-optimal. It also means it can't take
 the optimal route in a lot of algorithms (array has to emplace
 each element individually, for example).
 
 Finally, a RefCounted will implicitly cast to its payload. I
 think this is *horrible*. Before you know it, the Payload will
 have jettisoned its wrapper, and you'll be operating on your
 value-type payload raw. For example:
 void foo(T t);
 RefCounted!T myRecCounted;
 foo(myRefCounted); //Passes. Oops!
 
 The workaround would be to either require explicit get to go
 from ref counted to payload (breaking existing code), or to
 entirelly wrap the RefCounted as a member inside the struct
 (requires boilerplate code).

Yeah. RefCounted could/should definitely be improved, but the concept is 
essentially the same as smart_ptr in C++11. In many ways, smart pointers are 
far superior to using the GC, and I really think that we should do a better 
job of supporting them and promoting them. There are obviously plenty of cases 
where the GC is better or even necessary, but in many cases - particularly 
with objects - smart pointers are arguably a much better way to go.

- Jonathan M Davis


Re: D Ranges

2013-09-15 Thread Dmitry Olshansky

15-Sep-2013 12:39, monarch_dodra пишет:

On Saturday, 14 September 2013 at 06:18:02 UTC, Jonathan M Davis wrote:
I have a few issues with ref counted.

First, if you *ever* place one in an array or an AA, then you will leak.
It is NOT designed for simply incorporating reference, but for
deterministic finalization.


Another problem with built-in AAs...



Second, it has an elaborate postblit and opAssign. This is not a big
issue in itself, but their sole existence does cause dmd to generate
code that is sub-optimal. It also means it can't take the optimal
route in a lot of algorithms (array has to emplace each element
individually, for example).


Seriously we could do a better job then that.. For instance blit the 
whole data, then call postblits on that range. Exception safety would be 
trickier to achieve. Even better one day I now expect compiler to be 
able to know that e.g. RefCounted is registered as ARC-capable type then 
the compiler should elide call to ref-counting.



Finally, a RefCounted will implicitly cast to its payload. I think this
is *horrible*. Before you know it, the Payload will have jettisoned
its wrapper, and you'll be operating on your value-type payload raw.
For example:
void foo(T t);
RefCounted!T myRecCounted;
foo(myRefCounted); //Passes. Oops!


Well it does a copy. Which is IMO perfectly fine.
If you want to prevent that (at least in theory) you should simply mark 
postblit of T as disabled.




The workaround would be to either require explicit get to go from ref
counted to payload (breaking existing code), or to entirelly wrap the
RefCounted as a member inside the struct (requires boilerplate code).


There is no need to prevent that in general case. Only RAII kind of 
things implemented with RefCounted would have problem copying-out the 
payload but these should have post-blit disabled for their value and 
consequently would not compile.





Overall, if I need a reference semantic struct, I find it much simpler
for it to just hold a GC pointer to a payload.


Ehm.. Isn't finalized class is just that? Plus bit of overhead for monitor.


Though to be honest, as H.S. Teoh, I seriously wonder why I even bother,
when I could just use a final class. With proper private constructors +
non-member make function, you can make your choice outright
transparent to the final user too, meaning you can fast prototype with
classes, and later change to structs if you think it is worth it.


This is true. And in fact I would encourage every D programmer to never 
expose constructors and always provide factory functions. These days 
constructors are constrained by a set of arcane limitations thusly suck 
beyond measure in every way possible. But you need them to say 
initialize immutable members, hence _use_ - but don't _expose_ them.


--
Dmitry Olshansky


Re: D Ranges

2013-09-15 Thread monarch_dodra
On Sunday, 15 September 2013 at 12:17:34 UTC, Dmitry Olshansky 
wrote:

15-Sep-2013 12:39, monarch_dodra пишет:
On Saturday, 14 September 2013 at 06:18:02 UTC, Jonathan M 
Davis wrote:

I have a few issues with ref counted.

First, if you *ever* place one in an array or an AA, then you 
will leak.

It is NOT designed for simply incorporating reference, but for
deterministic finalization.


Another problem with built-in AAs...



Second, it has an elaborate postblit and opAssign. This is not 
a big
issue in itself, but their sole existence does cause dmd to 
generate
code that is sub-optimal. It also means it can't take the 
optimal

route in a lot of algorithms (array has to emplace each element
individually, for example).


Seriously we could do a better job then that.. For instance 
blit the whole data, then call postblits on that range. 
Exception safety would be trickier to achieve. Even better one 
day I now expect compiler to be able to know that e.g. 
RefCounted is registered as ARC-capable type then the compiler 
should elide call to ref-counting.


Well, if a struct has no elaborate opAssign, then = *is* 
blit+postblit. And it doesn't get much more efficient than that.


If not, you have to pull out the memcpy, and things just go 
downhill from there.


Finally, a RefCounted will implicitly cast to its payload. I 
think this
is *horrible*. Before you know it, the Payload will have 
jettisoned
its wrapper, and you'll be operating on your value-type 
payload raw.

For example:
void foo(T t);
RefCounted!T myRecCounted;
foo(myRefCounted); //Passes. Oops!


Well it does a copy. Which is IMO perfectly fine.
If you want to prevent that (at least in theory) you should 
simply mark postblit of T as disabled.


It depends how you look at it. If the original intent was to have 
a type with reference semantics, because your value type was so 
damn big (eg, PRNG), then that would *not* be OK (and the 
original point I was making that RefCounted is a bad contender 
for just reference semantics).


If you are *trully* using it for deterministic finalization, then 
yeah, it's OK.


Re: D Ranges

2013-09-15 Thread Dmitry Olshansky

15-Sep-2013 17:02, monarch_dodra пишет:

It depends how you look at it. If the original intent was to have a type
with reference semantics, because your value type was so damn big (eg,
PRNG), then that would *not* be OK (and the original point I was making
that RefCounted is a bad contender for just reference semantics).



If user don't have the access to the wrapped internal type there should 
be no problem. E.g. the wrapped type is private and only usable inside 
the PRNG's module. Then having public alias for RefCounted!PRNG touted 
as THE PRNG should suffice. (Truly wicked folks can crack open it with a 
carefully applied piece of template deduction but each to their own goals).



If you are afraid of these dark mages of templates you can do something 
like:


struct RefPRNG{
RefCounted!PRNG payload;
mixin ForwardCallsTo!payload;
}

And let them suck it down. IMHO there is no reason to go that far.


If you are *trully* using it for deterministic finalization, then yeah,
it's OK.


See above I don't see the problem.

--
Dmitry Olshansky


Re: D Ranges

2013-09-15 Thread Paulo Pinto

Am 15.09.2013 10:52, schrieb Jonathan M Davis:

...

Yeah. RefCounted could/should definitely be improved, but the concept is
essentially the same as smart_ptr in C++11. In many ways, smart pointers are
far superior to using the GC, and I really think that we should do a better
job of supporting them and promoting them. There are obviously plenty of cases
where the GC is better or even necessary, but in many cases - particularly
with objects - smart pointers are arguably a much better way to go.

- Jonathan M Davis




Actually, it is much easier to write exception safe code in languages 
with GC. Or in case of ref-counting if the compiler is aware of them.


The problems with exception safe code in C++ with memory leaks are 
related to its C compatibility rules and having to cope to optional 
exceptions.


After watching the Going Native 2013 videos, I really wonder how much of 
a push C++ will win back from younger developers, outside the game 
industry and device drivers.



Now back to C++ coding. :)

--
Paulo


Re: D Ranges

2013-09-14 Thread H. S. Teoh
On Fri, Sep 13, 2013 at 10:49:23PM -0400, Jonathan M Davis wrote:
 On Saturday, September 14, 2013 04:10:09 Jesse Phillips wrote:
  Anyway, my recommendation isn't to build up a class structure
  just because that is what you would do in another language.
  Figure out if the usability provided by inheritance is what you
  want, if not struct with helper functions seems to be simplest in
  development and maintenance. Destroy.
 
 I find that I use classes very rarely in D. Once in a while, I need
 polymorphism, and in that situation, I use classes, but at least in
 the types of programs that I've usually been writing, polymorphism has
 rarely made much sense. Structs deal with most everything just fine.
 
 Classes definitely have their uses, but IMHO, they should not be the
 first tool to pull out of your toolbox when writing a D program. Just
 use them when you actually need them.
[...]

I've found myself hovering between structs and classes when writing D
code. I almost always use structs for ranges, just because value types
incur less overhead, which does add up when you use a lot of UFCS
chaining.

OTOH, I find myself switching to classes just to get the reference
semantics in other cases, even if I never actually do any inheritance.
Trying to do reference semantics with structs, while certainly possible,
is just too error-prone IME. Just a few days ago, I encountered what
looked like a nasty functionality bug in my program, only to eventually
discover that it was caused by a missing 'ref' in a function's struct
parameter, so updates to the struct didn't persist as the code assumed
it would. I found myself seriously considering using classes instead,
just for the default ref semantics.

While D's decision to make structs value-only and classes ref-only is
certainly clever, it also introduces some tricky gotchas for the unwary.


T

-- 
May you live all the days of your life. -- Jonathan Swift


Re: D Ranges

2013-09-14 Thread Jonathan M Davis
On Friday, September 13, 2013 23:07:03 H. S. Teoh wrote:
 OTOH, I find myself switching to classes just to get the reference
 semantics in other cases, even if I never actually do any inheritance.
 Trying to do reference semantics with structs, while certainly possible,
 is just too error-prone IME. Just a few days ago, I encountered what
 looked like a nasty functionality bug in my program, only to eventually
 discover that it was caused by a missing 'ref' in a function's struct
 parameter, so updates to the struct didn't persist as the code assumed
 it would. I found myself seriously considering using classes instead,
 just for the default ref semantics.

In general, if you want to have structs with reference semantics, it's 
probably better to just give them reference semantics by making it so that any 
of their members which are value types are on the heap or by putting all of 
the struct's guts on the heap. At some point, it becomes debatable as to 
whether that's better than using a class, but it does have less overhead. 
There's also RefCounted, which does incur the bookkeeping overhead of the 
refcounting, but it does make it so that the memory is freed as soon as you 
don't need the object anymore.

- Jonathan M Davis


Re: D Ranges

2013-09-14 Thread Jacob Carlborg

On 2013-09-14 08:07, H. S. Teoh wrote:


OTOH, I find myself switching to classes just to get the reference
semantics in other cases, even if I never actually do any inheritance.


I agree, it seems I most times want a reference type (not talking ranges 
here but in general).


--
/Jacob Carlborg


D Ranges

2013-09-13 Thread Chris

A short report on component programming and ranges.

A lot of my code deals with transforming and reformatting input, 
e.g. text is split into sentences and words for grammatical 
parsing (part of speech) and phonetic transcriptions. I'm using D 
ranges and component programming and I'm quite happy with 
one-liners like


foreach 
(bySentence().byWord().byWhateverFormat().byReformatAgain()) {

   // Whatever
}

The code is much easier to maintain, neater and more efficient 
within each component.


Sometimes, however, I wonder how I should design my ranges. It is 
hard to decide whether to use them as pure pipes or semi-output 
ranges. Semi because they're not sinks as defined by put() but 
still they can hold data (an array of reformatted strings for 
example) that could be accessed by using Range.data. I'm not sure 
as regards best practice and whether or not I'm wasting 
resources by storing data internally. On the other hand, it might 
be handy to have access to the data stored internally. Does 
anyone have a rough guide to D ranges? Like Case 1: Use XYZ, Case 
2: Use ZYX etc.
(I've read this tutorial http://ddili.org/ders/d.en/ranges.html, 
and I'd like to thank Ali for that! It helped me a lot.)


Another issue I've come across is how to integrate CP and ranges 
into an OO framework. I figure that ranges are good work horses, 
but it makes sense to keep the overall logic in an OO fashion. Or 
could it be that D's structs and ranges will replace OOP as we no 
it (a class-free system).


Re: D Ranges

2013-09-13 Thread bearophile

Chris:


A short report on component programming and ranges.

A lot of my code deals with transforming and reformatting 
input, e.g. text is split into sentences and words for 
grammatical parsing (part of speech) and phonetic 
transcriptions. I'm using D ranges and component programming 
and I'm quite happy with one-liners like


foreach 
(bySentence().byWord().byWhateverFormat().byReformatAgain()) {

   // Whatever
}


In most cases today you are free to omit those ():

foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {

Bye,
bearophile


Re: D Ranges

2013-09-13 Thread Dicebot

On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:

In most cases today you are free to omit those ():

foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {

Bye,
bearophile


...but you shouldn't if you care about readability (leave at 
least the last pair in the line) :P


Re: D Ranges

2013-09-13 Thread Chris

On Friday, 13 September 2013 at 13:42:07 UTC, Dicebot wrote:

On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:

In most cases today you are free to omit those ():

foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {

Bye,
bearophile


...but you shouldn't if you care about readability (leave at 
least the last pair in the line) :P


It also helps other people (and me) to realize that it actually 
_does_ something and doesn't just return a value. Often (not 
always of course), if you omit the brackets it returns a value 
without doing anything. But that's just a personal convention I 
might abandon further down the road.


Re: D Ranges

2013-09-13 Thread deadalnix

On Friday, 13 September 2013 at 13:42:07 UTC, Dicebot wrote:

On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:

In most cases today you are free to omit those ():

foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {

Bye,
bearophile


...but you shouldn't if you care about readability (leave at 
least the last pair in the line) :P


That is my gideline as well. Keep at least the last one.


Re: D Ranges

2013-09-13 Thread Brad Anderson

On Friday, 13 September 2013 at 14:39:29 UTC, Chris wrote:

On Friday, 13 September 2013 at 13:42:07 UTC, Dicebot wrote:

On Friday, 13 September 2013 at 13:31:18 UTC, bearophile wrote:

In most cases today you are free to omit those ():

foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) {

Bye,
bearophile


...but you shouldn't if you care about readability (leave at 
least the last pair in the line) :P


It also helps other people (and me) to realize that it actually 
_does_ something and doesn't just return a value. Often (not 
always of course), if you omit the brackets it returns a value 
without doing anything. But that's just a personal convention I 
might abandon further down the road.


Since most ranges in std.algorithm are lazy they are usually not 
doing anything but setting a few members and returning a new 
range, often without having even touched the input range.  
Thinking about it I think I may start using () to denote eager 
versus lazy ranges in my UFCS chains.


Re: D Ranges

2013-09-13 Thread Chris

On Friday, 13 September 2013 at 17:35:21 UTC, Brad Anderson wrote:

On Friday, 13 September 2013 at 14:39:29 UTC, Chris wrote:

On Friday, 13 September 2013 at 13:42:07 UTC, Dicebot wrote:
On Friday, 13 September 2013 at 13:31:18 UTC, bearophile 
wrote:

In most cases today you are free to omit those ():

foreach (bySentence.byWord.byWhateverFormat.byReformatAgain) 
{


Bye,
bearophile


...but you shouldn't if you care about readability (leave at 
least the last pair in the line) :P


It also helps other people (and me) to realize that it 
actually _does_ something and doesn't just return a value. 
Often (not always of course), if you omit the brackets it 
returns a value without doing anything. But that's just a 
personal convention I might abandon further down the road.


Since most ranges in std.algorithm are lazy they are usually 
not doing anything but setting a few members and returning a 
new range, often without having even touched the input range.  
Thinking about it I think I may start using () to denote eager 
versus lazy ranges in my UFCS chains.


This reminds me, I have to check whether my ranges are lazy 
enough (like myself).


Re: D Ranges

2013-09-13 Thread Jesse Phillips

On Friday, 13 September 2013 at 11:31:24 UTC, Chris wrote:
Sometimes, however, I wonder how I should design my ranges. It 
is hard to decide whether to use them as pure pipes or 
semi-output ranges. Semi because they're not sinks as defined 
by put() but still they can hold data (an array of reformatted 
strings for example) that could be accessed by using 
Range.data. I'm not sure as regards best practice and whether 
or not I'm wasting resources by storing data internally. On the 
other hand, it might be handy to have access to the data stored 
internally. Does anyone have a rough guide to D ranges? Like 
Case 1: Use XYZ, Case 2: Use ZYX etc.
(I've read this tutorial 
http://ddili.org/ders/d.en/ranges.html, and I'd like to thank 
Ali for that! It helped me a lot.)


There isn't a guide in the manner you desire.

In my experience I generally don't hold any more data than the 
value returned by front (to prevent recalculation). Right now I 
don't recall what situations I've needed to store the 
intermediary data, but I know how you feel about having a input 
rang which is like an output range simply returning a range to 
provide the chaining ability.


I also generally don't find a need to specify output ranges. 
Output ranges are the end of the line so they kill component 
programming


Another issue I've come across is how to integrate CP and 
ranges into an OO framework. I figure that ranges are good work 
horses, but it makes sense to keep the overall logic in an OO 
fashion. Or could it be that D's structs and ranges will 
replace OOP as we no it (a class-free system).


I spent much of my initial time programming in Java, so I have a 
good grasp of the constructs behind OOP (and a little bit of the 
prototyping style known to be in Javascript). I also think I have 
a pretty good grasp on designing for OOP, though I do have a lot 
I could learn.


I hate OOP. I believe it has a place in software design, I just 
haven't found it yet. Templates cause a lot of problem, though I 
need to look into using the trick using /final/. Trying to do 
inheritance when your interface defines that it takes a range or 
returns a range. Though generics in C# work quite nicely.


The other issue I have is that OOP is very resistant to change 
and testing. It is hard enough to get all the data needed for 
your test cases, then throw in designing mock objects and blah 
blah, it quickly becomes a mess. And even if you skip all the 
testing aspects, if you want to make changes there is a giant 
structure you're making changes for. Yes had I done a better job 
designing my structure up front to allow for such change I 
wouldn't be in this mess...


Anyway, my recommendation isn't to build up a class structure 
just because that is what you would do in another language. 
Figure out if the usability provided by inheritance is what you 
want, if not struct with helper functions seems to be simplest in 
development and maintenance. Destroy.


Re: D Ranges

2013-09-13 Thread Jonathan M Davis
On Saturday, September 14, 2013 04:10:09 Jesse Phillips wrote:
 Anyway, my recommendation isn't to build up a class structure
 just because that is what you would do in another language.
 Figure out if the usability provided by inheritance is what you
 want, if not struct with helper functions seems to be simplest in
 development and maintenance. Destroy.

I find that I use classes very rarely in D. Once in a while, I need 
polymorphism, and in that situation, I use classes, but at least in the types 
of programs that I've usually been writing, polymorphism has rarely made much 
sense. Structs deal with most everything just fine.

Classes definitely have their uses, but IMHO, they should not be the first tool 
to pull out of your toolbox when writing a D program. Just use them when you 
actually need them.

- Jonathan M Davis


Re: D Ranges in C#

2013-06-08 Thread Ali Çehreli

On 05/31/2013 11:17 PM, David Piepgrass wrote:

I'm adding D-style ranges to my new C# collections library. In case
anyone would like to comment, please see here:

http://loyc-etc.blogspot.ca/2013/06/d-style-ranges-in-c-net.html


(I wrote the following comment on the blog page but it is not visible at 
this time.)


Thank you for writing this.

I think the range article that you mentioned is Andrei Alexandrescu's 
On Iteration:


  http://www.informit.com/articles/article.aspx?p=1407357

Ali



Re: D Ranges in C#

2013-06-03 Thread Steven Schveighoffer
On Sat, 01 Jun 2013 04:11:59 -0400, bearophile bearophileh...@lycos.com  
wrote:



David Piepgrass:


In fact, most STL algorithms require exactly two iterators--a  
range--and none require only a single iterator


I think there are some C++ data structures that store many single  
iterators. If you instead store ranges you double the data amount.


This is true.  In dcollections, I have the concept of cursors.  These are  
1 or 0 element ranges (they are 0 after the first popFront).  For almost  
all cases, they require an extra boolean to designate the empty state.


So while not consuming 2x, it's more like 1.5x-ish.  Because of alignment,  
it pretty much requires 2x.  There have been suggestions on utilizing  
perhaps unused bits in the pointer to designate the empty flag, but I'm a  
bit aprehensive on that, especially if the node is GC-managed.


But besides the space requirements the *concept* of a single-element  
pointer is very much needed.  And cursors fill that role.


As an example, std.algorithm.find consumes a range until it finds the  
specific value.  It then returns a range of the remaining data.  But what  
if you wanted the range of the data UNTIL the first value?


In std.container, we have three functions to deal with this, upperBound,  
lowerBound, and equalRange.  But even with these, it can be difficult to  
construct intersections of these two ranges.


In dcollections, we have one function, find, which returns a cursor.  Then  
using the cursor, you can construct the range you need:


auto r = mymap[mymap.find(5)..$]; // opDollar not supported yet, but will  
be.


auto rbefore = mymap[mymap.begin()..mymap.find(5)];

All of this is safe and correct, and I think it reads rather well.

There are other good places where single-element ranges are useful.  It is  
important to note that a cursor is NOT equivalent to a range of one  
element.  Such a range in a node-based container has two node pointers.  A  
cursor MUST only point at exactly one element.  This is important when  
considering cursor invalidation -- removing an element unreferenced by a  
cursor should not invalidate that cursor (depending on how the container  
is structured).  For example, adding a new value to a hash set, or  
removing an unrelated value from a hash set may invalidate all ranges, but  
not cursors.


-Steve


D Ranges in C#

2013-06-01 Thread David Piepgrass
I'm adding D-style ranges to my new C# collections library. In 
case anyone would like to comment, please see here:


http://loyc-etc.blogspot.ca/2013/06/d-style-ranges-in-c-net.html


Re: D Ranges in C#

2013-06-01 Thread bearophile

David Piepgrass:


http://loyc-etc.blogspot.ca/2013/06/d-style-ranges-in-c-net.html


From the article:

Ranges are an improvement on the C++ concept of iterators. I 
don't exactly know how ranges were invented in D, but perhaps 
someone noticed that most of the C++ STL algorithms require 
pairs of iterators:


Ranges are an improvement over iterators about as much as oxygen 
molecules are an improvement over oxygen atoms. You breath 
mostly O2, and it allows you to live, but they are made of atomic 
oxygen. Atomic oxygen is more fundamental, it is here to stay (as 
Alexander Stepanov says), and it has capabilities that 
molecules don't have. In your normal life you can think to use 
only molecular oxygen, but sometimes you can even desire some 
ozone :-) And in chemistry reactions that happen inside you all 
the time, like oxidation, the oxygen molecules usually break 
apart to react.



In fact, most STL algorithms require exactly two iterators--a 
range--and none require only a single iterator


I think there are some C++ data structures that store many single 
iterators. If you instead store ranges you double the data amount.


Bye,
bearophile


Re: D Ranges in C#

2013-06-01 Thread Peter Alexander

On Saturday, 1 June 2013 at 08:12:00 UTC, bearophile wrote:

David Piepgrass:
In fact, most STL algorithms require exactly two iterators--a 
range--and none require only a single iterator


I think there are some C++ data structures that store many 
single iterators. If you instead store ranges you double the 
data amount.


Hashmaps would be the most common example. Usually implemented as 
a linked list of key-value pairs along with a vector of list 
iterators.


Iterators are also useful for constructing sub-ranges, which 
proves useful in the implementation of some algorithms. Writing 
std::next_permutation in D with ranges is quiet frustrating 
compared to C++.


https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L10901
http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01045_source.html#l03619

Notice that in D you need to maintain a count of the elements 
popped off the back and then use takeExactly to retrieve that 
portion again. In C++ you just move the iterators around and 
create ranges from pairs of iterators as you need them.


When I implemented nextPermutation in D, I constantly felt as if 
I was fighting with ranges instead of working with them - I knew 
exactly what I wanted to do, but ranges only provide a roundabout 
way of doing it.


Re: D Ranges in C#

2013-06-01 Thread Andrei Alexandrescu

On 6/1/13 2:17 AM, David Piepgrass wrote:

I'm adding D-style ranges to my new C# collections library. In case
anyone would like to comment, please see here:

http://loyc-etc.blogspot.ca/2013/06/d-style-ranges-in-c-net.html


http://www.reddit.com/r/programming/comments/1fgnyl/dstyle_ranges_in_c_net/

Andrei


Re: D Ranges in C#

2013-06-01 Thread Szymon Gatner

On Saturday, 1 June 2013 at 06:17:30 UTC, David Piepgrass wrote:
I'm adding D-style ranges to my new C# collections library. In 
case anyone would like to comment, please see here:


http://loyc-etc.blogspot.ca/2013/06/d-style-ranges-in-c-net.html


Lol I am just preparing a blog post on D ranges in C++, a piece 
of code I did after Andrei's Iterators must Go presentation. It 
was not super usable before C++11 and auto but now is pretty cool 
thing to have.


Re: D Ranges in C#

2013-06-01 Thread David Piepgrass

David Piepgrass:
In fact, most STL algorithms require exactly two iterators--a 
range--and none require only a single iterator


I think there are some C++ data structures that store many 
single iterators. If you instead store ranges you double the 
data amount.


Hashmaps would be the most common example. Usually implemented 
as a linked list of key-value pairs along with a vector of list 
iterators.


In theory. But the .NET hashtables are implemented with an 
*array* of key-value pairs and an array of *indexes*. The former 
forms a virtual linked list that is more efficient than a 
traditional linked list, and the latter is more efficient than a 
vector of iterators (especially on x64, as the indexes can be 
32-bit.)


Iterators are also useful for constructing sub-ranges, which 
proves useful in the implementation of some algorithms. Writing 
std::next_permutation in D with ranges is quiet frustrating 
compared to C++.


https://github.com/D-Programming-Language/phobos/blob/master/std/algorithm.d#L10901
http://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01045_source.html#l03619

Notice that in D you need to maintain a count of the elements 
popped off the back and then use takeExactly to retrieve that 
portion again. In C++ you just move the iterators around and 
create ranges from pairs of iterators as you need them.


When I implemented nextPermutation in D, I constantly felt as 
if I was fighting with ranges instead of working with them - I 
knew exactly what I wanted to do, but ranges only provide a 
roundabout way of doing it.


Hmm, very interesting. I suppose the problem with C++ iterators 
is that they are useless without external context: you can't 
increment or decrement one without also comparing it to begin() 
or end() in its container, which implies that the caller must 
manually keep track of which container it came from. Thus, an 
iterator is hardly an improvement over a plain-old integer index, 
the only advantages being


1. You can dereference it (*if* you can be sure it doesn't point 
to end())
2. Unlike an index, it's compatible with non-random-access data 
structures


But perhaps the iterator concept could be improved by being made 
self-aware: if the iterator knew and could tell you when it was 
at the beginning or end of its container. This would increase the 
storage requirement in some circumstances but not others. For 
example, an iterator to a doubly-linked list node can tell when 
it is at the beginning or end, but an iterator to a singly-linked 
list node can only tell when it is at the end. A pointer inside 
an array may or may not be able to tell if it is at the end 
depending on how arrays work, e.g. perhaps the way D heap arrays 
work would allow an array iterator, implemented as a simple 
pointer, to still know when it is safe to increment and decrement.


The simplest possible .NET array iterator is an array reference 
plus an index, and again the iterator can know when it is at the 
beginning or end of the array--except that if the iterator came 
from inside a range, it would be unaware of the range's 
boundaries, which may be smaller than the array's boundaries.


Re: D Ranges in C#

2013-06-01 Thread Mehrdad

On Saturday, 1 June 2013 at 16:30:05 UTC, David Piepgrass wrote:

David Piepgrass:
In fact, most STL algorithms require exactly two iterators--a 
range--and none require only a single iterator


I think there are some C++ data structures that store many 
single iterators. If you instead store ranges you double the 
data amount.


Hashmaps would be the most common example. Usually implemented 
as a linked list of key-value pairs along with a vector of 
list iterators.


In theory. But the .NET hashtables are implemented with an 
*array* of key-value pairs and an array of *indexes*. The 
former forms a virtual linked list that is more efficient than 
a traditional linked list, and the latter is more efficient 
than a vector of iterators (especially on x64, as the indexes 
can be 32-bit.)




Iterators are usually (but not always) faster, as they don't have 
an extra level of indirection involved -- the iterators tell you 
directly where to look in memory, whereas indices are useless 
without containers (or iterators) backing them.



You shouldn't be using 32-bit indices on x64, that defeats the 
whole point of x64.



Hmm, very interesting. I suppose the problem with C++ iterators 
is that they are useless without external context: you can't 
increment or decrement one without also comparing it to begin() 
or end() in its container, which implies that the caller must 
manually keep track of which container it came from.



No, that's exactly the opposite of what happens.

The caller just accepts two iterators (like std::unique), so that 
it has the end iterator as well as the begin iterator.


Re: D Ranges in C#

2013-06-01 Thread Paulo Pinto

Am 01.06.2013 20:23, schrieb Mehrdad:

On Saturday, 1 June 2013 at 16:30:05 UTC, David Piepgrass wrote:

David Piepgrass:

In fact, most STL algorithms require exactly two iterators--a
range--and none require only a single iterator


I think there are some C++ data structures that store many single
iterators. If you instead store ranges you double the data amount.


Hashmaps would be the most common example. Usually implemented as a
linked list of key-value pairs along with a vector of list iterators.


In theory. But the .NET hashtables are implemented with an *array* of
key-value pairs and an array of *indexes*. The former forms a virtual
linked list that is more efficient than a traditional linked list, and
the latter is more efficient than a vector of iterators (especially on
x64, as the indexes can be 32-bit.)




Iterators are usually (but not always) faster, as they don't have an
extra level of indirection involved -- the iterators tell you directly
where to look in memory, whereas indices are useless without containers
(or iterators) backing them.


You shouldn't be using 32-bit indices on x64, that defeats the whole
point of x64.


As of .NET 4.5, 64bit array indexes are supported as well.

http://msdn.microsoft.com/en-us/library/hh285054.aspx





Re: D Ranges in C#

2013-06-01 Thread David Piepgrass
You shouldn't be using 32-bit indices on x64, that defeats the 
whole

point of x64.


As of .NET 4.5, 64bit array indexes are supported as well.

http://msdn.microsoft.com/en-us/library/hh285054.aspx


Don't forget that we're talking about a *hashtable* here. If a 
.NET hashtable used 64-bit indexes (or pointers) it would require 
8-12 bytes more memory per entry, specifically 32 bytes total, 
including overhead, if the key and value are 4 bytes each.


An in-memory hashtable that requires 64-bit indexes rather than 
32 bits would have to contain over 4 billion entries which would 
take at least 128 GB of RAM, assuming 8 bytes for each key-value 
pair!!! In fact it's worse than that, as the dictionary grows by 
size-doubling and contains a certain amount of unused entries at 
the end.


No thanks, I'd rather save those 8 bytes and accept the 4 billion 
limit, if you don't mind.


Re: D Ranges in C#

2013-06-01 Thread renoX

On Saturday, 1 June 2013 at 18:23:31 UTC, Mehrdad wrote:
[cut]


You shouldn't be using 32-bit indices on x64, that defeats the 
whole point of x64.


Some would disagree: have a look at x32: 
http://en.wikipedia.org/wiki/X32_ABI
Being able to use efficiently 64 bit doesn't mean that you *have* 
to use 64bit when 32bit is enough..

renoX


Re: D Ranges in C#

2013-06-01 Thread Marco Leise
Am Sat, 01 Jun 2013 23:20:19 +0200
schrieb renoX reno...@gmail.com:

 On Saturday, 1 June 2013 at 18:23:31 UTC, Mehrdad wrote:
 [cut]
 
  You shouldn't be using 32-bit indices on x64, that defeats the 
  whole point of x64.
 
 Some would disagree: have a look at x32: 
 http://en.wikipedia.org/wiki/X32_ABI
 Being able to use efficiently 64 bit doesn't mean that you *have* 
 to use 64bit when 32bit is enough..
 renoX

No wait, the whole 'efficiency' point was that on x64 you
don't have to waste memory with the native word size for
indexes, but can go with 32-bits. So it saves memory.

But Mehrdad argued that we have x64 to be able to address
beyond 2^32 (bytes, items, objects). And 32-bit indexes in
generic code are thus asking for overflow bugs on x64 one day.

x32 adds nothing to the discussion as you'd always use 32-bit
indexes there. There is no point in storing more than 2^32
items when the address space is 32-bit. (Exceptions: bit
arrays, file offsets, etc.)

-- 
Marco



Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Walter Bright
Elements of containers (and pseudo-containers) are accessed by the range 
abstraction of D. D's InputRange, ForwardRange, BidirectionalRange, 
RandomAccessRange, and OutputRange are sufficient to connect many types of 
containers and many types of algorithms.


Most modules of Phobos, including std.range, provide algorithms and ranges that 
make programs consistent, fast, and easy to maintain.


-- http://astoriaseminar.com/sessions.html


Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Ali Çehreli

On 05/27/2012 01:12 PM, Walter Bright wrote:

Elements of containers (and pseudo-containers) are accessed by the range
abstraction of D. D's InputRange, ForwardRange, BidirectionalRange,
RandomAccessRange, and OutputRange are sufficient to connect many types
of containers and many types of algorithms.

Most modules of Phobos, including std.range, provide algorithms and
ranges that make programs consistent, fast, and easy to maintain.

-- http://astoriaseminar.com/sessions.html


Great! :) Walter, there is a typo in my last name and it's not the first 
letter. ;)


Ali

--
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html


Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Walter Bright

On 5/27/2012 1:38 PM, Ali Çehreli wrote:

Great! :) Walter, there is a typo in my last name and it's not the first 
letter. ;)


OOPS! Fixed.

What's the Unicode number for the first letter, so I can fix that, too? Is there 
an entity name for it?


Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Jonathan M Davis
On Sunday, May 27, 2012 13:53:24 Walter Bright wrote:
 On 5/27/2012 1:38 PM, Ali Çehreli wrote:
  Great! :) Walter, there is a typo in my last name and it's not the first
  letter. ;)
 OOPS! Fixed.
 
 What's the Unicode number for the first letter, so I can fix that, too? Is
 there an entity name for it?

According to this

import std.stdio;

void main()
{
writefln(%x, 'Ç');
}


it's \u00c7.

- Jonathan M Davis


Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Jonathan M Davis
On Sunday, May 27, 2012 14:01:09 Jonathan M Davis wrote:
 On Sunday, May 27, 2012 13:53:24 Walter Bright wrote:
  On 5/27/2012 1:38 PM, Ali Çehreli wrote:
   Great! :) Walter, there is a typo in my last name and it's not the first
   letter. ;)
  
  OOPS! Fixed.
  
  What's the Unicode number for the first letter, so I can fix that, too? Is
  there an entity name for it?
 
 According to this
 
 import std.stdio;
 
 void main()
 {
 writefln(%x, 'Ç');
 }
 
 
 it's \u00c7.

Having .d files be able to be UTF-8 combined with unicode support built into 
the language itself can be _very_ handy.

- Jonathan M Davis


Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Walter Bright

On 5/27/2012 2:01 PM, Jonathan M Davis wrote:

On Sunday, May 27, 2012 13:53:24 Walter Bright wrote:

On 5/27/2012 1:38 PM, Ali Çehreli wrote:

Great! :) Walter, there is a typo in my last name and it's not the first
letter. ;)

OOPS! Fixed.

What's the Unicode number for the first letter, so I can fix that, too? Is
there an entity name for it?


According to this

import std.stdio;

void main()
{
 writefln(%x, 'Ç');
}


it's \u00c7.

- Jonathan M Davis


Thanks! Checking it out, there's an entity for it:

   Ccedil;

Fixed the web pages.


Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Walter Bright

On 5/27/2012 2:03 PM, Jonathan M Davis wrote:

Having .d files be able to be UTF-8 combined with unicode support built into
the language itself can be _very_ handy.



I also love D's support for entities: http://dlang.org/entity.html

I'm amazed this is not adopted by other languages. It is so damned convenient.


Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Ali Çehreli

On 05/27/2012 01:53 PM, Walter Bright wrote:

On 5/27/2012 1:38 PM, Ali Çehreli wrote:

Great! :) Walter, there is a typo in my last name and it's not the
first letter. ;)


OOPS! Fixed.

What's the Unicode number for the first letter, so I can fix that, too?
Is there an entity name for it?


Thanks but the misspelling has overpowered the correct one: Now both the 
Speakers and the Sessions page has the wrong name! :D


Also, there is a rogue Ddoc at the end of the speaker bio.

About the letter, if you are using ddoc as I suspect, just copy paste 
the Ç into the ddoc source file. Both D and ddoc support Unicode. ;)


Ali

--
D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html


Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Walter Bright

On 5/27/2012 2:15 PM, Ali Çehreli wrote:

Thanks but the misspelling has overpowered the correct one: Now both the
Speakers and the Sessions page has the wrong name! :D

Also, there is a rogue Ddoc at the end of the speaker bio.


Alas! Someday, I might get this right. Fixed.


About the letter, if you are using ddoc as I suspect, just copy paste the Ç into
the ddoc source file. Both D and ddoc support Unicode. ;)


I generally prefer using named entities, as some of my programs cannot deal with 
non-ascii.


I've also had trouble with copy-pasta of these things, because I'll get the hex 
value for some random code page, rather than the Unicode code point.





Re: Ali Cehrili on D Ranges at D Conference 2012

2012-05-27 Thread Andrei Alexandrescu

On 5/27/12 3:38 PM, Ali Çehreli wrote:

On 05/27/2012 01:12 PM, Walter Bright wrote:

Elements of containers (and pseudo-containers) are accessed by the range
abstraction of D. D's InputRange, ForwardRange, BidirectionalRange,
RandomAccessRange, and OutputRange are sufficient to connect many types
of containers and many types of algorithms.

Most modules of Phobos, including std.range, provide algorithms and
ranges that make programs consistent, fast, and easy to maintain.

-- http://astoriaseminar.com/sessions.html


Great! :) Walter, there is a typo in my last name and it's not the first
letter. ;)


Also please make sure the C has a cedilla.

Andrei



Re: Tutorial on D ranges now on reddit

2012-01-28 Thread deadalnix

Le 28/01/2012 04:10, Jonathan M Davis a écrit :

On Saturday, January 28, 2012 04:05:53 deadalnix wrote:

Le 28/01/2012 03:08, Andrei Alexandrescu a écrit :

Just posted it:
http://www.reddit.com/r/programming/comments/ozzgn/tutorial_on_d_ranges/

Andrei


In this tutorial, save is not a property. I see a lot of code where it is.

I do think that save shouldn't be a property, but it would be very
interesting if a clear guideline was written on that point.


No guide needed. It must be a property, or it won't compile with -property.
The fact that properties haven't been being enforced is what's making it so
that people are mistakenly not making save a property. As soon as -property
becomes the normal compiler behavior, anything that has save as a function
rather than a property won't compile.

- Jonathan M Davis


So this tutorial has to be corrected.


Tutorial on D ranges now on reddit

2012-01-27 Thread Andrei Alexandrescu
Just posted it: 
http://www.reddit.com/r/programming/comments/ozzgn/tutorial_on_d_ranges/


Andrei


Re: Tutorial on D ranges now on reddit

2012-01-27 Thread deadalnix

Le 28/01/2012 03:08, Andrei Alexandrescu a écrit :

Just posted it:
http://www.reddit.com/r/programming/comments/ozzgn/tutorial_on_d_ranges/

Andrei


In this tutorial, save is not a property. I see a lot of code where it is.

I do think that save shouldn't be a property, but it would be very 
interesting if a clear guideline was written on that point.


If We put that remark aside, this is a great tutorial ! This is exactly 
the type of docuement we need to promote D and help newcomers. If we 
succed in getting more of this, we probably would be able to conquier 
the world soon.