Re: Real OOP with D
On 17/08/2015 5:57 p.m., Ozan wrote: Hi Working with objectoriented concepts results often in large trees of related classes. Every instance of a class knows his methods and data. An example like following would work: import std.stdio; class Family { } class Dad : Family { void greeting() { writeln("I'm dad"); } } class Boy : Family { void greeting() { writeln("I'm daddy's boy"); } } void main() { writeln("Father and son"); Dad father = new Dad; Family son = new Boy; father.greeting; son.greeting; } The critical point is using a variable of type Family for an instance of Boy. Class Family covers the greeting method of Boy. In real OOP that would not be a problem, because the access point of view starts with the object. In D, it starts with the class definition. Is there any way to get real OOP with D? Regards, Ozan import std.stdio; abstract class Family { void greeting(); } class Dad : Family { void greeting() { writeln("I'm dad"); } } class Boy : Family { void greeting() { writeln("I'm daddy's boy"); } } void main() { Family dad = new Dad; Family boy = new Boy; dad.greeting; boy.greeting; } I'm confused how this isn't real OOP?
Re: Real OOP with D
On 08/16/2015 10:57 PM, Ozan wrote: > Working with objectoriented concepts results often in large trees of > related classes. Every instance of a class knows his methods and data. > An example like following would work: > > import std.stdio; > class Family { } From the way you use it below, a better name for that class would be FamilyMember but I get the point. > class Dad : Family { void greeting() { writeln("I'm dad"); } } > class Boy : Family { void greeting() { writeln("I'm daddy's boy"); } } > void main() { > writeln("Father and son"); > Dad father = new Dad; > Family son = new Boy; > father.greeting; > son.greeting; What you mean is that the call above causes a compilation error: Error: no property 'greeting' for type 'deneme.Family' > } > > The critical point is using a variable of type Family for an instance of > Boy. Class Family covers the greeting method of Boy. In real OOP that > would not be a problem, because the access point of view starts with the > object. My experience with OOP is limited to C++ and D. I think what you are describing is how dynamically typed languages work. It is impossible in compiled languages like C++ and D. When a type is used in an expression, the compiler ensures that the call is bound to a function. > In D, it starts with the class definition. Actually, 'interface' is a better fit in most cases: interface FamilyMember { // ... } class Dad : FamilyMember { // ... } > Is there any way to get real OOP with D? > > Regards, Ozan Ali
Real OOP with D
Hi Working with objectoriented concepts results often in large trees of related classes. Every instance of a class knows his methods and data. An example like following would work: import std.stdio; class Family { } class Dad : Family { void greeting() { writeln("I'm dad"); } } class Boy : Family { void greeting() { writeln("I'm daddy's boy"); } } void main() { writeln("Father and son"); Dad father = new Dad; Family son = new Boy; father.greeting; son.greeting; } The critical point is using a variable of type Family for an instance of Boy. Class Family covers the greeting method of Boy. In real OOP that would not be a problem, because the access point of view starts with the object. In D, it starts with the class definition. Is there any way to get real OOP with D? Regards, Ozan
Re: pragma(mangle, on a template)
On Monday, 17 August 2015 at 02:46:02 UTC, Freddy wrote: I can't get pragma(mangle) to work on templates(or structs). [...] I don't know why but it looks like it only works on functions. Even if a struct is not a template the custom symbol mangle won't be handled: --- import std.stdio; pragma(mangle, "a0") class MyClass{} pragma(mangle, "a1") struct MyStruct{} pragma(mangle, "a2") void body_func(); pragma(mangle, "a3") struct MyStructh { pragma(mangle, "a4") void foo(){}} void main() { writeln(MyClass.mangleof); writeln(MyStruct.mangleof); writeln(body_func.mangleof); writeln(MyStructh.mangleof); writeln(MyStructh.foo.mangleof); } --- which outputs: --- C13temp_019455687MyClass S13temp_019455688MyStruct a2 S13temp_019455689MyStructh a4 --- 'a4' being printed and not 'a3' is interesting BTW ;) I think that the manual is not clear enough about this pragma: http://dlang.org/pragma.html#mangle Unless the spec. are more detailed this could be considered as a bug.
Re: pragma(mangle, on a template)
On Monday, 17 August 2015 at 03:14:16 UTC, Adam D. Ruppe wrote: On Monday, 17 August 2015 at 02:46:02 UTC, Freddy wrote: Mangling is done at a different level in the compiler than aliases, so I don't think this is intended to work. Is there any way I can mangle a template struct then?
Re: pragma(mangle, on a template)
On Monday, 17 August 2015 at 02:46:02 UTC, Freddy wrote: pragma(mangle, "MyAlias") alias MyAlias = MyStruct!("a", "b", "c" /+very long symbol bloating list+/ ); Mangling is done at a different level in the compiler than aliases, so I don't think this is intended to work.
Re: Weird error message.
On Monday, 17 August 2015 at 00:00:11 UTC, Jonathan M Davis wrote: On Sunday, August 16, 2015 21:32:08 Warwick via Digitalmars-d-learn wrote: Dont know what to make of this, I pretty much get it every other time I call rdmd. It'll alternate between running fine and then giving me this error... C:\Program Files (x86)\Notepad++>rdmd J:\Code\statproc.d std.process.ProcessException@std\process.d(550): Failed to spawn new process (The process cannot access the file because it is being used by another process.) [...] Any ideas? Well, Windows has file locks, so tyically, if one program has a [...] Personally, I wish that Windows didn't have file locks... :( It's locked unless it's specified during the call to `CreateFile()` that the file can be shared for reading/writing (FILE_SHARE_READ / FILE_SHARE_WRITE).
Re: Pointers to Dynamic Arrays
On Monday, 17 August 2015 at 02:45:22 UTC, Brandon Ragland wrote: Since Dynamic Arrays / Slices are a D feature, using pointers to these has me a bit confused... Short answer: pointers to slices are usually a mistake, you probably don't actually want it, but rather should be using a regular slice instead. string c2s(int* pos, char[]* file, int l){ char[] s; for(int i = 0; i < l; i++){ s ~= file[(*pos + i)]; Here, for example, you've accidentally escaped slice land and are unto unchecked pointer arithmetic. Since file is declared char[]* instead of char[], indexing it works C style: it at the index as an offset from the base char[]. In other words, it works more as if you wrote `char** file` in C. (still not identically, a D slice is different than a C char*, but same idea). The above will only really work fine for index 0. Anything else would be a wild pointer. If this didn't crash on you, you just got kinda lucky with the index. The append compiles because dereferencing a `char[]*` yields a `char[]`, which D can append normally. Now what is especially confusing about this, is that the above seems to works fine, while this does not: if(file[(*pos + i)] == '}'){ This errors for the same reason the top one succeeded: what's pointed to by a char[]* is char[], not char. So you are trying to compare a string on the left hand side to an individual character on the right hand side. In other words, what your error message told :) I can no longer assume that using the dynamic array pointer works anything like a standard pointer to an array, or a pointer to a dynamic array. char[] in D is like: struct char_array { size_t length; char* ptr; } in C. Since there's already a pointer in there, you typically don't want the address of this struct, you just want to pass it right down by value and let the pointer be copied (it still points to the same actual data). BTW you can access those .length and .ptr values in D: char[] slice; char* a = slice.ptr; // works The only time you'd actually want a char[]* in D is if you need to write back to the original *variable* once you append or shrink it. (The contents are fine, they can be modified through the slice with no special effort.) Bottom line again is char[] in D is like char* in C. So char[]* in D is more like char** in C.
Re: Pointers to Dynamic Arrays
On Monday, 17 August 2015 at 02:45:22 UTC, Brandon Ragland wrote: Howdy, Since Dynamic Arrays / Slices are a D feature, using pointers to these has me a bit confused... Consider: Now what is especially confusing about this, is that the above seems to works fine, while this does not: if(file[(*pos + i)] == '}'){ *pos += i; return; } This fails with this error: Error: incompatible types for ((file[cast(ulong)(*pos + i)]) == ('}')): 'char[]' and 'char' This is wrong. what you want is (*file)[(*pos + i)] == '}' file is a pointer. deref it you get a char array. index that you get a char. Now what I do not understand, is if the above works, by appending come chars gathered from the dynamic array via pointer to me new dynamic array named "s", and the below does not seem to work on comparison of two chars, what is really going on? I can no longer assume that using the dynamic array pointer works anything like a standard pointer to an array, It is. arr.ptr[n] is the same as arr[n] (modulo bounds checking) or a pointer to a dynamic array. Is there something I'm missing? Remember, that de-referencing a dynamic array was deprecated. So what I would normally have done: &dynamic_array_pntr does not work any longer, and there is no new spec on what to do... -Brandon string c2s(int* pos, char[]* file, int l){ char[] s; for(int i = 0; i < l; i++){ s ~= file[(*pos + i)]; } return s.dup; } would more idiomatically be written as string c2s(int* pos, char[]* file, int k) { char* p = *file.ptr+*pos; return p[0 .. k].dup } or changing the signature string c2s(char[] file, size_t offset,size_t length) { return file[offset .. offset + length].dup; }
Re: Pointers to Dynamic Arrays
On Monday, 17 August 2015 at 02:45:22 UTC, Brandon Ragland wrote: if(file[(*pos + i)] == '}'){ *pos += i; return; } That code doesn't do what you want it do. file is a ((char[])*) you are indexing the pointer(accessing invalid memory) and getting a char[].
pragma(mangle, on a template)
I can't get pragma(mangle) to work on templates(or structs). import std.stdio; struct MyStruct(T...) { int var; void func() { writeln(var); } } pragma(mangle, "MyAlias") alias MyAlias = MyStruct!("a", "b", "c" /+very long symbol bloating list+/ ); void main() { auto v = MyAlias(2); v.func(); }
Pointers to Dynamic Arrays
Howdy, Since Dynamic Arrays / Slices are a D feature, using pointers to these has me a bit confused... Consider: string c2s(int* pos, char[]* file, int l){ char[] s; for(int i = 0; i < l; i++){ s ~= file[(*pos + i)]; } return s.dup; } Now what is especially confusing about this, is that the above seems to works fine, while this does not: if(file[(*pos + i)] == '}'){ *pos += i; return; } This fails with this error: Error: incompatible types for ((file[cast(ulong)(*pos + i)]) == ('}')): 'char[]' and 'char' Now what I do not understand, is if the above works, by appending come chars gathered from the dynamic array via pointer to me new dynamic array named "s", and the below does not seem to work on comparison of two chars, what is really going on? I can no longer assume that using the dynamic array pointer works anything like a standard pointer to an array, or a pointer to a dynamic array. Is there something I'm missing? Remember, that de-referencing a dynamic array was deprecated. So what I would normally have done: &dynamic_array_pntr does not work any longer, and there is no new spec on what to do... -Brandon
Re: App Build Error
On Sunday, 16 August 2015 at 17:33:52 UTC, Benjamin wrote: I'm having an issue with building my app - even a simple trivial app (shown below). [...] OS X version? Have you configured your dmd.conf? iirc it requires linker path changes or something. Have you looked in /usr/local/lib for libiconv.* ? Have you any idea why it's targeting i386 and not, say i686 and not passing -m64 by default? (You're getting the arch mismatch because you passed -m64 and dmd for some reason didn't)
Re: D Classes Passed By Reference or Value?
On Sunday, 16 August 2015 at 23:40:41 UTC, Brandon Ragland wrote: On Sunday, 16 August 2015 at 23:31:46 UTC, Ali Çehreli wrote: On 08/16/2015 04:13 PM, Brandon Ragland wrote: > That makes more sense. Though it does make the ref method > signature unclear, as it only applies to literals at this > point? As long as the returned object will be valid after the function leaves, it can be anything: one of the ref parameters, a module-level variable, etc. > Would you still need the ref signature for method parameters > for classes to avoid a copy? Such that I could work on the > class itself, and not a copy. Obviously, you meant "the object itself." > //This is reference? > void doStuff(ref MyClass mc){ > return; > } Yes, that's a reference to a class variable. Since class variables are references anyway, unless intended, there is one too many level of indirection there. (Although, it is valid and it may exactly be what is needed.) > or would this also be a valid reference type: > > //This is a copy? > void doStuff(MyClass mc){ > return; > } That's the normal way of doing it. mc is class reference to an object that was presumably created somewhere else. Ali If I understand you correctly than: void doStuff(MyClass mc){ mc.x = 7; } Would be working with the reference to the object instantiated elsewhere. This would NOT be a copy of the object. That would mean that (ref MyClass mc) is the equivalent to a pointer to a pointer (sorta, though these are references, same idea follows). -Brandon Yes. void doStuff(ref MyClass a, ref MyClass b, ref MyClass c, bool d) { if (d) b = a; else c = a; } void main(string[] args) { auto a = new MyClass(); a.x = 1; auto b = new MyClass(); b.x = 2; auto c = new MyClass(); c.x = 3; assert(a !is b); assert(a.x == 1); assert(a !is c); assert(b.x == 2); assert(c !is b); assert(c.x == 3); doStuff(a,b,c,true); assert(a is b); assert(b.x == 1); b.x = 2; assert( a.x == 2); assert(a !is c); assert(c.x == 3); doStuff(a,b,c,false); assert(a is c); assert(c.x == 2); }
Re: Weird error message.
On Sunday, August 16, 2015 21:32:08 Warwick via Digitalmars-d-learn wrote: > Dont know what to make of this, I pretty much get it every other > time I call rdmd. It'll alternate between running fine and then > giving me this error... > > C:\Program Files (x86)\Notepad++>rdmd J:\Code\statproc.d > std.process.ProcessException@std\process.d(550): Failed to spawn > new process (The process cannot access the file because > it is being used by another process.) > > 0x00434C59 > 0x00426F47 > 0x00403C9C > 0x00403D17 > 0x0042F60B > 0x0042F521 > 0x0042258C > 0x76B533CA in BaseThreadInitThunk > 0x775A9ED2 in RtlInitializeExceptionChain > 0x775A9EA5 in RtlInitializeExceptionChain > > Any ideas? Well, Windows has file locks, so tyically, if one program has a file open, another can't have it open. So, I'd guess that either something has the file open when you're running rdmd, so rdmd can't access it, or rdmd is trying to access it from multiple processes and sometimes one of its processes is accessing it when another one tries to. But I don't know if rdmd creates multiple processes or not. Personally, I wish that Windows didn't have file locks... :( - Jonathan M Davis
Re: D Classes Passed By Reference or Value?
On Sunday, 16 August 2015 at 23:31:46 UTC, Ali Çehreli wrote: On 08/16/2015 04:13 PM, Brandon Ragland wrote: > That makes more sense. Though it does make the ref method > signature unclear, as it only applies to literals at this > point? As long as the returned object will be valid after the function leaves, it can be anything: one of the ref parameters, a module-level variable, etc. > Would you still need the ref signature for method parameters > for classes to avoid a copy? Such that I could work on the > class itself, and not a copy. Obviously, you meant "the object itself." > //This is reference? > void doStuff(ref MyClass mc){ > return; > } Yes, that's a reference to a class variable. Since class variables are references anyway, unless intended, there is one too many level of indirection there. (Although, it is valid and it may exactly be what is needed.) > or would this also be a valid reference type: > > //This is a copy? > void doStuff(MyClass mc){ > return; > } That's the normal way of doing it. mc is class reference to an object that was presumably created somewhere else. Ali If I understand you correctly than: void doStuff(MyClass mc){ mc.x = 7; } Would be working with the reference to the object instantiated elsewhere. This would NOT be a copy of the object. That would mean that (ref MyClass mc) is the equivalent to a pointer to a pointer (sorta, though these are references, same idea follows). -Brandon
Re: D Classes Passed By Reference or Value?
On 08/16/2015 04:13 PM, Brandon Ragland wrote: > That makes more sense. Though it does make the ref method > signature unclear, as it only applies to literals at this > point? As long as the returned object will be valid after the function leaves, it can be anything: one of the ref parameters, a module-level variable, etc. > Would you still need the ref signature for method parameters > for classes to avoid a copy? Such that I could work on the > class itself, and not a copy. Obviously, you meant "the object itself." > //This is reference? > void doStuff(ref MyClass mc){ > return; > } Yes, that's a reference to a class variable. Since class variables are references anyway, unless intended, there is one too many level of indirection there. (Although, it is valid and it may exactly be what is needed.) > or would this also be a valid reference type: > > //This is a copy? > void doStuff(MyClass mc){ > return; > } That's the normal way of doing it. mc is class reference to an object that was presumably created somewhere else. Ali
Re: D Classes Passed By Reference or Value?
On Sunday, 16 August 2015 at 22:35:15 UTC, Alex Parrill wrote: On Sunday, 16 August 2015 at 22:31:02 UTC, Brandon Ragland wrote: Hi All, I'm a bit confused as to how Classes in D are passed in arguments and returns. Take this for example: class MyClass{ int x = 2; } And then in app.d ref MyClass doStuff(){ MyClass mc = new MyClass() // Heap allocation, using new return mc; } The above fails, as "escaping reference to local variable" however, this was created using new Not understanding what the deal is, this should be a valid heap allocated object, and therefore, why can I not pass this by reference? I don't want this to be a local variable... So this begs the question: Are Classes (Objects) passed by reference already? -Brandon Classes are reference types, a la Java/C#. class MyClass { int x = 5; } void main() { auto c1 = new MyClass(); auto c2 = c1; c1.x = 123; assert(c2.x == 123); } Thanks, That makes more sense. Though it does make the ref method signature unclear, as it only applies to literals at this point? Would you still need the ref signature for method parameters for classes to avoid a copy? Such that I could work on the class itself, and not a copy. //This is reference? void doStuff(ref MyClass mc){ return; } or would this also be a valid reference type: //This is a copy? void doStuff(MyClass mc){ return; }
Re: How to provide this arg or functor for algorithm?
On 08/16/2015 03:36 PM, cym13 wrote: On Sunday, 16 August 2015 at 22:22:07 UTC, Ali Çehreli wrote: // HERE: // Error: function deneme.func @nogc function allocates //a closure with the GC @nogc auto func(uint[] arr, DelegateRef d) { return arr.map!(a => d.d(a)); } Aren't you making another delegate in the map by using "=>" that needs to allocate because it uses 'd' which is out of its scope? I did not see that at all. :) I've finally gotten it to work by stepping into template realm where the compiler is a master of attributes: :) import std.stdio; import std.range; import std.algorithm; struct Caller { this(uint context) { _context = context; } // ADDED pure pure uint method(uint value) { return _context * value; } uint _context; } // Now the type of d is a template parameter @nogc auto func(Func)(uint[] arr, Func d) { return arr.map!(d); } void main(string[] args) { uint[] arr = [1,2,3]; uint context = 2; auto c = Caller(context); auto d = &c.method; writeln(func(arr, d)); } Prints: [2, 4, 6] Ali
Re: D Classes Passed By Reference or Value?
On Sunday, 16 August 2015 at 22:31:02 UTC, Brandon Ragland wrote: Hi All, I'm a bit confused as to how Classes in D are passed in arguments and returns. Take this for example: class MyClass{ int x = 2; } And then in app.d ref MyClass doStuff(){ MyClass mc = new MyClass() // Heap allocation, using new return mc; } The above fails, as "escaping reference to local variable" however, this was created using new Not understanding what the deal is, this should be a valid heap allocated object, and therefore, why can I not pass this by reference? I don't want this to be a local variable... So this begs the question: Are Classes (Objects) passed by reference already? -Brandon Classes are reference types, a la Java/C#. class MyClass { int x = 5; } void main() { auto c1 = new MyClass(); auto c2 = c1; c1.x = 123; assert(c2.x == 123); }
Re: D Classes Passed By Reference or Value?
On Sunday, 16 August 2015 at 22:31:02 UTC, Brandon Ragland wrote: ref MyClass doStuff(){ MyClass mc = new MyClass() // Heap allocation, using new return mc; } This attempts to return a reference to the _variable_ `mc`, not a reference to the class. Just remove `ref` from the function signature.
Re: How to provide this arg or functor for algorithm?
On Sunday, 16 August 2015 at 22:22:07 UTC, Ali Çehreli wrote: // HERE: // Error: function deneme.func @nogc function allocates //a closure with the GC @nogc auto func(uint[] arr, DelegateRef d) { return arr.map!(a => d.d(a)); } Aren't you making another delegate in the map by using "=>" that needs to allocate because it uses 'd' which is out of its scope?
D Classes Passed By Reference or Value?
Hi All, I'm a bit confused as to how Classes in D are passed in arguments and returns. Take this for example: class MyClass{ int x = 2; } And then in app.d ref MyClass doStuff(){ MyClass mc = new MyClass() // Heap allocation, using new return mc; } The above fails, as "escaping reference to local variable" however, this was created using new Not understanding what the deal is, this should be a valid heap allocated object, and therefore, why can I not pass this by reference? I don't want this to be a local variable... So this begs the question: Are Classes (Objects) passed by reference already? -Brandon
Re: How to provide this arg or functor for algorithm?
On 08/16/2015 09:26 AM, FreeSlave wrote: >> It still says it needs allocation: >> >> test.d(17): Error: function test.func @nogc function allocates a >> closure with the GC I wrapped it inside a class object but it still thinks it needs to allocate: import std.stdio; import std.range; import std.algorithm; struct Caller { this(uint context) { _context = context; } uint method(uint value) { return _context * value; } uint _context; } class DelegateRef { uint delegate(uint) d; this (uint delegate(uint) d) { this.d = d; } } // HERE: // Error: function deneme.func @nogc function allocates //a closure with the GC @nogc auto func(uint[] arr, DelegateRef d) { return arr.map!(a => d.d(a)); } void main(string[] args) { uint[] arr = [1,2,3]; uint context = 2; auto c = Caller(context); auto d = &c.method; writeln(func(arr, new DelegateRef(d))); } Ali
Weird error message.
Dont know what to make of this, I pretty much get it every other time I call rdmd. It'll alternate between running fine and then giving me this error... C:\Program Files (x86)\Notepad++>rdmd J:\Code\statproc.d std.process.ProcessException@std\process.d(550): Failed to spawn new process (The process cannot access the file because it is being used by another process.) 0x00434C59 0x00426F47 0x00403C9C 0x00403D17 0x0042F60B 0x0042F521 0x0042258C 0x76B533CA in BaseThreadInitThunk 0x775A9ED2 in RtlInitializeExceptionChain 0x775A9EA5 in RtlInitializeExceptionChain Any ideas?
GDB for D debugging on OS X seems to be broken
For reference: OSX 10.10.5 GDB 7.9.1 (non apple; from homebrew) yes, it is code signed Compiling with dub: "dflags": ["-gc", "-gs"] I would also like to preface this post by saying that everything works fine in GDB on linux. When finding that a bug in my program was a null pointer bug, I decided to drop into GDB to try to figure out what was happening. But I quickly realized that trying to set a breakpoint in a file other than the one where the main function is, and stepping into functions in a file other than the one where the main function is, don't work. GDB will return something like: Cannot insert breakpoint 2. Cannot access memory at address 0x9bc06 when trying to insert a breakpoint in another file. GDB also treats the aforementioned step command as a continue because it can't read the file where the function is defined. Nothing changes when running the command as sudo either. Two more pain points: `info locals` doesn't work. It responds with "No symbol table info available." And `info variables` returns the mangled D names for variables and not their real name, despite the language being set to D and doing `demangle [some_name]` returns the correct names.
App Build Error
I'm having an issue with building my app - even a simple trivial app (shown below). I receive the following error message: cc -arch i386 -framework CoreFoundation -lobjc -liconv: No such file or directory --- errorlevel 255 I've removed and reinstalled DMD - same issue. I'm not really sure whats going on. --- BENJAMINs-MacBook-Pro:source benjamin$ ls app.d BENJAMINs-MacBook-Pro:source benjamin$ cat app.d import std.stdio; void main() { writeln("Hello D!"); } BENJAMINs-MacBook-Pro:source benjamin$ dmd --version DMD64 D Compiler v2.068 Copyright (c) 1999-2015 by Digital Mars written by Walter Bright BENJAMINs-MacBook-Pro:source benjamin$ BENJAMINs-MacBook-Pro:source benjamin$ BENJAMINs-MacBook-Pro:source benjamin$ dmd app.d cc -arch i386 -framework CoreFoundation -lobjc -liconv: No such file or directory --- errorlevel 255 BENJAMINs-MacBook-Pro:source benjamin$ BENJAMINs-MacBook-Pro:source benjamin$ cc -arch i386 -framework CoreFoundation -lobjc -liconv app.o -o app -m64 -L/usr/local/Cellar/dmd/2.068.0/lib -lphobos2 -lpthread -lm cc -arch i386 -framework CoreFoundation -lobjc -liconv: No such file or directory --- errorlevel 255 BENJAMINs-MacBook-Pro:source benjamin$ BENJAMINs-MacBook-Pro:source benjamin$ BENJAMINs-MacBook-Pro:source benjamin$ BENJAMINs-MacBook-Pro:source benjamin$ cc -arch i386 -framework CoreFoundation -lobjc -liconv app.o -o app -m64 -L/usr/local/Cellar/dmd/2.068.0/lib -lphobos2 -lpthread -lm ld: warning: ignoring file app.o, file was built for unsupported file format ( 0xCF 0xFA 0xED 0xFE 0x07 0x00 0x00 0x01 0x03 0x00 0x00 0x00 0x01 0x00 0x00 0x00 ) which is not the architecture being linked (i386): app.o ld: warning: ignoring file /usr/local/Cellar/dmd/2.068.0/lib/libphobos2.a, file was built for archive which is not the architecture being linked (i386): /usr/local/Cellar/dmd/2.068.0/lib/libphobos2.a Undefined symbols for architecture i386: "_main", referenced from: implicit entry/start for main executable ld: symbol(s) not found for architecture i386 clang: error: linker command failed with exit code 1 (use -v to see invocation) BENJAMINs-MacBook-Pro:source benjamin$
Re: How to provide this arg or functor for algorithm?
On Sunday, 16 August 2015 at 16:23:05 UTC, FreeSlave wrote: On Sunday, 16 August 2015 at 15:29:10 UTC, Ali Çehreli wrote: On 08/16/2015 04:53 AM, FreeSlave wrote: > The problem is that this allocates delegate, so it can't be used in > @nogc code. Would constructing the delegate by setting its .funcptr and .ptr properties work in this case? You can have a pool of context objects which become the context for the delegate. http://ddili.org/ders/d.en/lambda.html#ix_lambda..funcptr Ali I don't see how this can solve the problem. What I tried: import std.stdio; import std.range; import std.algorithm; struct Caller { this(uint context) { _context = context; } uint method(uint value) { return _context * value; } uint _context; } @nogc auto func(uint[] arr, uint function(uint) f) { return arr.map!(f); } void main(string[] args) { uint[] arr = [1,2,3]; uint context = 2; auto c = Caller(context); auto d = &c.method; writeln(func(arr, d.funcptr)); } It still says it needs allocation: test.d(17): Error: function test.func @nogc function allocates a closure with the GC funcptr does not play any role here, since passing the delegate directly leads to the same error. Forgot about data ptr. @nogc auto func(uint[] arr, uint function(uint) f, void* data) { uint delegate(uint) d; d.funcptr = f; d.ptr = data; return arr.map!(d); } void main(string[] args) { uint[] arr = [1,2,3]; uint context = 2; auto c = Caller(context); auto d = &c.method; writeln(func(arr, d.funcptr, d.ptr)); } Still the same error though.
Re: How to provide this arg or functor for algorithm?
On Sunday, 16 August 2015 at 15:29:10 UTC, Ali Çehreli wrote: On 08/16/2015 04:53 AM, FreeSlave wrote: > The problem is that this allocates delegate, so it can't be used in > @nogc code. Would constructing the delegate by setting its .funcptr and .ptr properties work in this case? You can have a pool of context objects which become the context for the delegate. http://ddili.org/ders/d.en/lambda.html#ix_lambda..funcptr Ali I don't see how this can solve the problem. What I tried: import std.stdio; import std.range; import std.algorithm; struct Caller { this(uint context) { _context = context; } uint method(uint value) { return _context * value; } uint _context; } @nogc auto func(uint[] arr, uint function(uint) f) { return arr.map!(f); } void main(string[] args) { uint[] arr = [1,2,3]; uint context = 2; auto c = Caller(context); auto d = &c.method; writeln(func(arr, d.funcptr)); } It still says it needs allocation: test.d(17): Error: function test.func @nogc function allocates a closure with the GC funcptr does not play any role here, since passing the delegate directly leads to the same error.
Re: How to provide this arg or functor for algorithm?
On 08/16/2015 04:53 AM, FreeSlave wrote: > The problem is that this allocates delegate, so it can't be used in > @nogc code. Would constructing the delegate by setting its .funcptr and .ptr properties work in this case? You can have a pool of context objects which become the context for the delegate. http://ddili.org/ders/d.en/lambda.html#ix_lambda..funcptr Ali
Re: How to provide this arg or functor for algorithm?
On Sunday, 16 August 2015 at 12:30:54 UTC, cym13 wrote: On Sunday, 16 August 2015 at 11:53:42 UTC, FreeSlave wrote: [...] Ok, so as my lambda proposition obviously doesn't work, here is one way that does using a templated function. There may be a way to make it shorter, I don't know. import std.conv; import std.stdio; template fun(uint context) { static uint withContext(uint value) { return value * context; } auto fun(uint[] arr) @nogc { return arr.map!withContext; } } void main(string[] args) { [1, 2, 3].to!(uint[]) .fun!2 .writeln; } It works only because 2 is known constant at compile time.
Re: How to provide this arg or functor for algorithm?
On Sunday, 16 August 2015 at 11:53:42 UTC, FreeSlave wrote: Let's say I want to map some range using some context. The obvious way is to do: uint[3] arr = [1,2,3]; uint context = 2; auto r = arr[].map!(delegate(value) { return value * context; }); The problem is that this allocates delegate, so it can't be used in @nogc code. What I want to do might look like this: static struct Caller { this(uint context) @nogc { _context = context; } auto opCall(uint value) @nogc { return value * _context; } uint _context; } auto caller = Caller(2); auto r = arr[].map!(&caller.opCall); But it will not work of course since function must be a compile-time parameter. So the way to go would be: auto caller = Caller(2); auto r = arr[].map!(Caller.opCall)(&caller); But map and other algorithms don't support this interface. The other way is auto r = arr.map!(Caller(2)); But again, since it's template parameter, it can't use variables unknown at compile time: uint context = ...; auto r = arr.map!(Caller(context)); //will not work So what's the solution? Of course besides rewriting the whole std.algorithm. Ok, so as my lambda proposition obviously doesn't work, here is one way that does using a templated function. There may be a way to make it shorter, I don't know. import std.conv; import std.stdio; template fun(uint context) { static uint withContext(uint value) { return value * context; } auto fun(uint[] arr) @nogc { return arr.map!withContext; } } void main(string[] args) { [1, 2, 3].to!(uint[]) .fun!2 .writeln; }
Re: How to provide this arg or functor for algorithm?
On Sunday, 16 August 2015 at 12:04:51 UTC, cym13 wrote: To me the obvious way is to use a lambda, not a delegate: Lambdas and delegates are the same thing, just different syntax.
Re: 2.068 Regression in EnumMembers?
On Sunday, 16 August 2015 at 11:25:48 UTC, Nordlöw wrote: I tried rebuilding my knowledge graph project at https://github.com/nordlow/justd/tree/master/knet with DMD 2.068 and it seems like we have a regression in std.traits: EnumMembers: [...] It builds without errors nor warnings on 2.067. Help, please. Did it still work in 2.068a ? If so then it's possible that the resolution of issue 14844, which changed the traits allMembers, is the cause. Because if you look at std.traits 'blame' on GH (https://github.com/D-Programming-Language/phobos/blame/master/std/traits.d , around line 3412) that's clear that the template EnumMembers hasn't changed since February 2014. So it must be one of the call inside... Just an idea.
Re: How to provide this arg or functor for algorithm?
On Sunday, 16 August 2015 at 11:53:42 UTC, FreeSlave wrote: Let's say I want to map some range using some context. The obvious way is to do: uint[3] arr = [1,2,3]; uint context = 2; auto r = arr[].map!(delegate(value) { return value * context; }); To me the obvious way is to use a lambda, not a delegate: uint[3] arr = [1,2,3]; uint context = 2; auto r = arr[].map!(value => value * context);
Re: How to convert a ubyte to a byte without losing information?
On Sunday, 16 August 2015 at 11:43:24 UTC, CharmingChocolate wrote: I can cast a ubyte to a byte, but as far as I know I'd only get positive values out of that conversion. ubyte b = 255; byte b2 = cast(byte) b; assert(b2 == -1); No information is lost by that cast, all the bits remain exactly the same.
How to provide this arg or functor for algorithm?
Let's say I want to map some range using some context. The obvious way is to do: uint[3] arr = [1,2,3]; uint context = 2; auto r = arr[].map!(delegate(value) { return value * context; }); The problem is that this allocates delegate, so it can't be used in @nogc code. What I want to do might look like this: static struct Caller { this(uint context) @nogc { _context = context; } auto opCall(uint value) @nogc { return value * _context; } uint _context; } auto caller = Caller(2); auto r = arr[].map!(&caller.opCall); But it will not work of course since function must be a compile-time parameter. So the way to go would be: auto caller = Caller(2); auto r = arr[].map!(Caller.opCall)(&caller); But map and other algorithms don't support this interface. The other way is auto r = arr.map!(Caller(2)); But again, since it's template parameter, it can't use variables unknown at compile time: uint context = ...; auto r = arr.map!(Caller(context)); //will not work So what's the solution? Of course besides rewriting the whole std.algorithm.
How to convert a ubyte to a byte without losing information?
I can cast a ubyte to a byte, but as far as I know I'd only get positive values out of that conversion. If I was instead getting a ubyte out of a function and I want to assign those bits to a byte and have some of those numbers be interpreted as negative values by the new type they're in, how would I cast that in D?
Re: 2.068 Regression in EnumMembers?
On Sunday, 16 August 2015 at 11:25:48 UTC, Nordlöw wrote: Try cloning https://github.com/nordlow/justd/tree Should be: git clone https://github.com/nordlow/justd
Re: 2.068 Regression in EnumMembers?
On Sunday, 16 August 2015 at 11:25:48 UTC, Nordlöw wrote: I tried rebuilding my knowledge graph project at https://github.com/nordlow/justd/tree/master/knet Should be, https://github.com/nordlow/justd.
2.068 Regression in EnumMembers?
I tried rebuilding my knowledge graph project at https://github.com/nordlow/justd/tree/master/knet with DMD 2.068 and it seems like we have a regression in std.traits: EnumMembers: /usr/include/dmd/phobos/std/traits.d(3432,21): Error: template instance std.traits.EnumMembers!(Lang).WithIdentifier!"fortran" recursive expansion scons: *** [knet/traversal.o] Error 1 /usr/include/dmd/phobos/std/traits.d(3432,21): Error: template instance std.traits.EnumMembers!(Lang).WithIdentifier!"firstAcademic" recursive expansion scons: *** [knet/base.o] Error 1 /usr/include/dmd/phobos/std/traits.d(3432,21): Error: template instance std.traits.EnumMembers!(const(Lang)).WithIdentifier!"physics" recursive expansion scons: *** [knet/io.o] Error 1 /usr/include/dmd/phobos/std/traits.d(3432,21): Error: template instance std.traits.EnumMembers!(Lang).WithIdentifier!"modelica" recursive expansion scons: *** [knet/tests.o] Error 1 Sadly the diagnositcs give no help whatsoever on what's wrong. What happened to the instantiation stack trace here? Try cloning https://github.com/nordlow/justd/tree and building for instance scons knet/base.o provided that SCons has been installed (on Ubuntu as `sudo apt-get install scons`) It builds without errors nor warnings on 2.067. Help, please.
Re: Using replaceInPlace, string and char[]
> Must create a ticket for it ? I think so. Unless others object in 10 minutes... :) :-) Done : https://issues.dlang.org/show_bug.cgi?id=14925 Thanks for your help