Re: File IO: C# streams VS iterators?

2013-11-07 Thread Lionello Lunesu

On 11/8/13, 8:57, DDD wrote:

I was watching a dconf talk about porting C# code to D. One thing that
came up was there isn't anything like C# streams for D. Walter said he
thinks iterators (unless I remember wrong) is superior. The speaker
agreed but said it isn't a drop in replacement so that is an issue if
you want to port.

I haven't access file in D and i'm completely confused. What are
iterators in regards to file IO?


There are several ranges that can be used for file IO, for example 
http://dlang.org/phobos/std_stdio.html#.File.byChunk and 
http://dlang.org/phobos/std_stdio.html#.File.byLine . C# Stream has no 
such capability, which is why you have TextReader and TextWriter on top 
of streams, etc..


However, sometimes it's useful to have polymorphism for accessing 
streams, especially when porting C#/java code to D. In that case it 
would be pretty trivial to port the base classes to D and implement them 
using the D ranges.


L.



Re: Static arrays passed by value..?

2010-08-07 Thread Lionello Lunesu

On 2010-08-07 9:26, simendsjo wrote:

The spec for array says:
Static arrays are value types. Unlike in C and D version 1, static
arrays are passed to functions by value. Static arrays can also be
returned by functions.

I don't get the "static arrays are passed to functions by value" part.

Here I am passing in a static and dynamic array. Both are passed by
value, and the function can modify the array of both

{
void func(int[] arr, void* ptr) {
arr[0] = 9;
assert(&arr != ptr);
}

int[3] a = [1,2,3];
func(a, &a);
assert(a == [9,2,3]); // changed..

int[] b = [1,2,3];
func(b, &b);
assert(b == [9,2,3]);
}


When you use "int[]" as the parameter type, the array is passed by 
reference as a slice of the original array. If you write the function 
like this:


fund(int[3] arr, void* ptr) {...}

Now the array is passed by value and a copy is made.


Human stupidity or is this a regression?

2013-12-25 Thread Lionello Lunesu
Perhaps should have written "and/or" in the subject line since the two 
are not mutually exclusive.


I was showing off D to friends the other day:

import std.stdio;
void main()
{
  foreach (d; "你好")
writeln(d);
}


IIRC, this used to work fine, with the variable "d" getting deduced as 
"dchar" and correctly reassembling the UTF-8 bytes into Unicode codepoints.


But when I run this code in OSX, dmd v2.064, I get this:

$ dmd -run uni.d
�
�
�
�
�
�

It's clearly printing the bytes. When I print the typeof(d) I get 
"immutable(char)", so that confirms the type is not deduced as "dchar".


I could have sworn this used to work. Is my memory failing me, or was 
this a deliberate change at some point? Perhaps a regression?


L.


Re: get address of object if opCast is overridden

2013-12-25 Thread Lionello Lunesu

On 12/2/12, 21:25, js.mdnq wrote:

I'm not just comparing them but using them as a unique ID for the
objects in an algorithm to prevent computing over the same object more
than once.


o.toHash() ??

(Which incidentally just casts the reference to a hash_t, exactly what 
you want to do.)


Re: Human stupidity or is this a regression?

2013-12-25 Thread Lionello Lunesu

On 12/26/13, 11:58, bearophile wrote:

Lionello Lunesu:


I could have sworn this used to work. Is my memory failing me, or was
this a deliberate change at some point? Perhaps a regression?


It's not a regression, it's a locked-in design mistake. Write it like
this and try again:

foreach (dchar d; "你好")

Bye,
bearophile


Yeah, that's what I ended up doing. But D being D, the default should be 
safe and correct.


I feel we could take this breaking change since it would not silently 
change the code to do something else. You'll get prompted and we could 
special case the error message to give a meaningful hint.


L


Re: dmd simple loop disassembly - redundant instruction?

2013-12-26 Thread Lionello Lunesu

On 12/25/13, 20:03, Ivan Kazmenko wrote:

-
L2C:mov-03D0900h[EDX*4][EBP],EDX
 movECX,EDX
 incEDX
 cmpEDX,0F4240h
 jbL2C
-


You should have said that all instructions are redundant :) Looks like 
the array got optimized out, but then the optimizer stopped. The ECX 
likely refers to the 'i' loop variable. When the array write code got 
optimized out, the compile could have figured out that 'i' was in turn 
unused as well and remove it too. And then, the foreach, etc...


You can file backend bugs on the same site.



Re: enum to string

2009-03-12 Thread Lionello Lunesu

Nick Sabalausky wrote:
Is there any way to do this (preferably in D1) with reflection? (ie, without 
having to manually create a conversion func/lookup for every value of every 
enum.)


--
enum Shape
{
Square, Circle
}
char[] foo(Shape s)
{
// ?
}

// Either one of these, I don't really care which
assert(foo(Shape.Square) == "Shape.Square");
assert(foo(Shape.Square) == "Square");
--



You got to give it to Walter: the code is pretty clean (for C++ code anyway)

Add the attached code to src\dmd\mtype.c, line 5025 (in 
TypeEnum::dotExp, after the #endif). This now works:


import std.stdio;
enum ABC { A, B, C };

void main(string[] args)
{
  foreach(a; ABC.tupleof)
  {
writefln(a);
  }
}

prints:
A
B
C

Of course, I'm way over my head here. I've just copied the code from 
struct.tupleof to make enum.tupleof and creating a tuple of StringExps 
insteadof DotVarExps, whatever they are


L.


Re: enum to string

2009-03-12 Thread Lionello Lunesu
Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a 
patch to the DMD source was not really what you expected. I just got so 
anxious!


L.


Re: enum to string

2009-03-12 Thread Lionello Lunesu

Your attachment is zero-byte.
 


Oops... Try this one..
/* Create a TupleExp out of the fields of the struct e:
 * (e.field0, e.field1, e.field2, ...)
 */
e = e->semantic(sc);// do this before turning on 
noaccesscheck
Expressions *exps = new Expressions;
exps->reserve(sym->members->dim);
for (size_t i = 0; i < sym->members->dim; i++)
{   
EnumMember *em = ((Dsymbol 
*)sym->members->data[i])->isEnumMember();
char* s = em->ident->toChars();
Expression *fe = new StringExp(e->loc, s, strlen(s), 
'c');
exps->push(fe);
}
e = new TupleExp(e->loc, exps);
Scope sss;
e = e->semantic(&sss);

Re: enum to string

2009-03-12 Thread Lionello Lunesu

Nick Sabalausky wrote:
"Lionello Lunesu"  wrote in message 
news:gpc4j3$30a...@digitalmars.com...
Oops, sorry, I didn't notice this was the .learn newsgroup. I guess a 
patch to the DMD source was not really what you expected. I just got so 
anxious!


L.


Hey, solutions are solutions :)  In fact I may very well try that out. I'm 
not particularly keen on using an ugly mixin to declare all my enums just so 
that I can use a simple reflection feature like that (which I'd mostly just 
be using for debugging info anyway).




I'm really glad it's so easy to hack stuff into the compiler. Although 
I'm still strugling to get these new "string expression" to evaluate at 
compile time. The enum.tupleof is done at compile time, the foreach as 
well, but I cannot pragma(msg) the values, nor can they be mixin-ed.. 
Must be some constness flag somewhere?


L.


Re: enum to string

2009-03-12 Thread Lionello Lunesu

cr*p, I've pasted too little. Try this one instead..

I'll use a proper diff tool next time..
/* If e.tupleof
 */
if (ident == Id::tupleof)
{
/* Create a TupleExp out of the fields of the struct e:
 * (e.field0, e.field1, e.field2, ...)
 */
e = e->semantic(sc);// do this before turning on 
noaccesscheck
Expressions *exps = new Expressions;
exps->reserve(sym->members->dim);
for (size_t i = 0; i < sym->members->dim; i++)
{   
EnumMember *em = ((Dsymbol 
*)sym->members->data[i])->isEnumMember();
char* s = em->ident->toChars();
Expression *fe = new StringExp(e->loc, s, strlen(s), 
'c');
exps->push(fe);
}
e = new TupleExp(e->loc, exps);
Scope sss;
e = e->semantic(&sss);
return e;
}

Re: enum to string

2009-03-12 Thread Lionello Lunesu

//src\dmd\mtype.c, line 5025 (in TypeEnum::dotExp, after the #endif):

/* If e.tupleof
 */
if (ident == Id::tupleof)
{
/* Create a TupleExp out of the fields of the struct e:
 * (e.field0, e.field1, e.field2, ...)
 */
e = e->semantic(sc); // do this before turning on noaccesscheck
Expressions *exps = new Expressions;
exps->reserve(sym->members->dim);
for (size_t i = 0; i < sym->members->dim; i++)
{
EnumMember *em = ((Dsymbol 
*)sym->members->data[i])->isEnumMember();
char* s = em->ident->toChars();
Expression *fe = new StringExp(e->loc, s, strlen(s), 'c');
exps->push(fe);
}
e = new TupleExp(e->loc, exps);
Scope sss;
e = e->semantic(&sss);
return e;
}


Re: enum to string

2009-03-12 Thread Lionello Lunesu


"Brad Roberts"  wrote in message 
news:alpine.deb.2.00.0903121755240.4...@bellevue.puremagic.com...

That said, I don't think this really helps the desired usecase much.  It's
useful, don't get me wrong, but still requires code to build up the
bi-directional translations.  Or am I missing something?  Seems to be
happening to me a lot lately, so I'm very prepared to be wrong here too.
:)



You're not wrong :)
The problem is that the foreach variable is not evaluatable to a 
compile-time string. I don't know why, but I'll figure it out tonight.


I've also managed to convert an enum to an AssocArrayLiteralExp* (with the 
name/string as the key and the value/int as the value) but it seems that it 
cannot be foreached at compile time, even if it's a literal expression. But 
hell, I've spent about 1 hour browsing through dmd's code, so I'm pretty 
sure it's possible with a little more research.


I want to get either one to work at compile-time. In the case of TupleExp, 
one could then use a string mixin to convert the string to a value.


L.

* I don't have the AA patch handy (I'm at work) but it's a good exercise: 
start with my original tupleof patch but create an AssocArrayLiteralExp 
instead of the TupleExp. You'll need two Expressions arrays, one for keys 
and one for values. EnumMember::ident is the name, EnumMember::value is the 
value expression. Pretty straightforward.





[static] [shared] [const|immutable]

2009-05-14 Thread Lionello Lunesu
I like shared/const/immutable as much as the next guy, but there are now 
2x2x3=12 ways to decorate a variable. Furthermore, by either declaring the 
variable globally or locally (stack), we end up with 24 possible 
declaration. See the code at the end of this post.


Surely, some combinations should/can be disallowed?
* What's the point of "shared immutable"?
* What about a locally declared "shared" variable? (The stack is implicit 
TLS anyway.)
* Come to think of it, what's the difference between a "const int" and a 
"immutable int"? (Is "const" only meant to be used in a function's argument 
list?)


L.

(From the results it's apparent that "static" on the global level does not 
actually do anything (probably kept for C/C++ compatibility where it's used 
to mean "private") and that "static" used locally declares the variable as 
if it were global. This makes sense.)


//The code:

int f = 0xDEAD0001; //0678
const int cf = 0xDEAD0002;//068d
immutable int _if = 0xDEAD0003;//068d

shared int sf = 0xDEAD0011;//068d
shared const int scf = 0xDEAD0012;   //068d
shared immutable int sif = 0xDEAD0013;   //068d

static int Sf = 0xDEAD0101;//0678
static const int Scf = 0xDEAD0102;   //068d
static immutable int Sif = 0xDEAD0103;   //068d

static shared int Ssf = 0xDEAD0111;   //068d
static shared const int Sscf = 0xDEAD0112;  //068d
static shared immutable int Ssif = 0xDEAD0113;  //068d

int main()
{
 int f_ = 0xDEAD1001; //073c**
 const int cf_ = 0xDEAD1002;//073c*
 immutable int if_ = 0xDEAD1003;   //073c*

 shared int sf_ = 0xDEAD1011;//073c**
 shared const int scf_ = 0xDEAD1012;   //073c*
 shared immutable int sif_ = 0xDEAD1013;  //073c*

 static int Sf_ = 0xDEAD1101;//0678
 static const int Scf_ = 0xDEAD1102;   //068d
 static immutable int Sif_ = 0xDEAD1103;  //068d

 static shared int Ssf_ = 0xDEAD;   //068d
 static shared const int Sscf_ = 0xDEAD1112;  //068d
 static shared immutable int Ssif_ = 0xDEAD1113; //068d

 // prevent optimization
 return f+cf+_if+sf+scf+sif+Sf+Scf+Sif+Ssf+Sscf+Ssif+
   f_+cf_+if_+sf_+scf_+sif_+Sf_+Scf_+Sif_+Ssf_+Sscf_+Ssif_;
}

// The numbers in comments represent the sections as printed by dumpbin:
//0678  LED386 (TLS?)
//068d  LED386 (global)
//073c  CMD386 (code)
//* only appears in obj when compiled with -g
//** does not appear in obj when compiled with -O



Re: [static] [shared] [const|immutable]

2009-05-14 Thread Lionello Lunesu


"Christopher Wright"  wrote in message 
news:gugs7b$70...@digitalmars.com...

Lionello Lunesu wrote:
I like shared/const/immutable as much as the next guy, but there are now 
2x2x3=12 ways to decorate a variable. Furthermore, by either declaring 
the variable globally or locally (stack), we end up with 24 possible 
declaration. See the code at the end of this post.


The decision to make a variable a static class or module member is 
independent of whether to make it shared or not.


You're right, of course. I realize now that "static" is a storage class 
(when used locally) not a type modifier.



Shared and const-level have to do with controlling access to the variable.

An immutable variable does not need to be declared shared.


So, immutable implies shared.


Shared const is for publish-subscribe sort of deals.


You mean one thread can change the value, but for another thread it's 
constant? I can see how it would be useful using reference types, but I 
don't understand how it would work with value types..



Shared mutable is for cooperative writing to the variable.


This one I understood :)

The point of a shared local variable is to pass it to another thread or 
set of threads, which will then be able to mutate it without trouble.


As before, how can an int (value type) on the stack ever be shared with 
another thread? It would always have to be copied... Can you give me an 
example please?


Thanks,

L. 



Re: [static] [shared] [const|immutable]

2009-05-18 Thread Lionello Lunesu

Christopher Wright wrote:

Lionello Lunesu wrote:


"Christopher Wright"  wrote in message 
news:gugs7b$70...@digitalmars.com...

Lionello Lunesu wrote:
I like shared/const/immutable as much as the next guy, but there are 
now 2x2x3=12 ways to decorate a variable. Furthermore, by either 
declaring the variable globally or locally (stack), we end up with 
24 possible declaration. See the code at the end of this post.


The decision to make a variable a static class or module member is 
independent of whether to make it shared or not.


You're right, of course. I realize now that "static" is a storage 
class (when used locally) not a type modifier.


Shared and const-level have to do with controlling access to the 
variable.


An immutable variable does not need to be declared shared.


So, immutable implies shared.


Immutable is threadsafe. Shared implies automatic locking, I believe; 
immutable variables do not need any locking.


So one has to wonder what code will be generated for "shared 
immutable".. an immutable with (useless) locking?



Shared const is for publish-subscribe sort of deals.


You mean one thread can change the value, but for another thread it's 
constant? I can see how it would be useful using reference types, but 
I don't understand how it would work with value types..


Shared const doesn't really work for value types; it ends up being the 
same as immutable. Unless you have a mutable pointer to the value, in 
which case you can write to the value through that pointer. That is not 
safe -- the compiler is free to see that this variable is const and a 
value type, which means you can't ever write to it, and then put it in 
read-only memory.


Const that doesn't boil down to immutable works a fair bit better with 
object-oriented code. You wrap your value in a class, create a mutable 
instance, and send it to a bunch of other functions or objects or 
threads expecting a const object. They can't use the mutators, but they 
can use the accessors.


Got it. Thanks..

L.


Re: [static] [shared] [const|immutable]

2009-05-18 Thread Lionello Lunesu

BCS wrote:

Hello Lionello,


"Christopher Wright"  wrote in message


The point of a shared local variable is to pass it to another thread
or set of threads, which will then be able to mutate it without
trouble.


As before, how can an int (value type) on the stack ever be shared
with another thread? It would always have to be copied... Can you give
me an example please?



// without lookin up the details of threading

void main()
{
   int i;
   with(new Thread({i++;}))
   {
  Start();
  Wait();
   }
}


:O Indeed, that works! Which is scary, since the compiler did not detect 
the access to 'i' from another thread. In this case the code is safe, 
but only because of the Wait/join at the end..


This looks like a hole in the shared/tls system and there's nothing the 
compiler can do about it. :(


L.