Re: DConf '24 Schedule & BeerConf News
On Monday, 3 June 2024 at 13:26:54 UTC, Mike Parker wrote: ## The DConf '24 Schedule The DConf '24 schedule is now live: https://dconf.org/2024/index.html#schedule You'll notice that we've departed from the norm in a few places. That's because of the number of submissions we received. Typically, we receive either just enough or many more than we need. This year, we needed 16 and received submissions from 19 people. Yay! Maybe on the template for next year, have an optional rating field for "How important is this talk to you / how time-critical is this talk" so you can sort by "is fine being deferred". My Neat talk was a bit time-critical to me due to the development schedule, and of course close to my heart; conversely, I wouldn't have had a problem with moving the Dustmite talk to '25, for instance.
Re: Limits of implicit conversion of class arrays
On Saturday, 23 March 2024 at 11:04:04 UTC, Dmitry Olshansky wrote: On Saturday, 23 March 2024 at 09:08:45 UTC, Per Nordlöw wrote: Is there a reason why ```d class Base {} class Derived : Base {} @safe pure nothrow unittest { Base b; Derived d; b = d; // pass Base[] bs; Derived[] ds; bs ~= ds; // pass bs = ds; // fail [1], should pass bs = cast(Base[])ds; // fail [2], should pass } ``` fails as [1]: cannot implicitly convert expression `ds` of type `Derived[]` to `Base[]` [2]: cast from `Derived[]` to `Base[]` not allowed in safe code ? The first and second is unsound (infamously allowed in Java). Once you cast the slice you can populate it with Derived2 objects that are not Derived, hence breaking type safety of the ds slice. — Dmitry Olshansky CEO @ Glow labs https://olshansky.me Note that it works if the classes are const: ```d const(Base)[] bs; const(Derived)[] ds; bs ~= ds; // pass bs = ds; // pass bs = cast(const(Base)[])ds; // pass ``` Exactly because you can't replace existing entries.
Re: Get Ready for DConf '24!
On Tuesday, 20 February 2024 at 10:51:27 UTC, FeepingCreature wrote: I'm gonna see if I can put together enough content for a talk about effective dustmiting. Might have to be a lightning talk though. 30 minutes is gonna be a challenge to hit with that. Nevermind, I just went through the content I have on dustmite and I can hit 30 minutes comfortably. Gonna be submitting that then. :)
Re: Get Ready for DConf '24!
On Tuesday, 20 February 2024 at 03:27:31 UTC, Mike Parker wrote: It's time to start thinking more seriously about that DConf talk you've been thinking about submitting: DConf '24 is tentatively scheduled for September 17 - 20. Symmetry Investments is again our host and primary sponsor. We'll be back for a third time at CodeNode, and we're working again with Brightspace Events to put it all together. If you'd like to submit a talk but aren't sure you've got anything to talk about, just take a look at our past [DConf and DConf Online editions](https://dconf.org) for inspiration. If you're using D for anything right now, then you've almost certainly got content for a DConf talk. Hm. For the first time in many years, I don't think I have a topic! :) I'm gonna see if I can put together enough content for a talk about effective dustmiting. Might have to be a lightning talk though. 30 minutes is gonna be a challenge to hit with that.
Re: Setting field of struct object
On Monday, 22 January 2024 at 08:54:54 UTC, zjh wrote: On Monday, 22 January 2024 at 08:27:36 UTC, Joel wrote: ```d import std; struct Person { string name, email; ulong age; auto withName(string name) { this.name=name; return this; } auto withEmail(string email) { this.email=email; return this; } auto withAge(ulong age) { this.age=age; return this; } } void main() { Person p; p.withName("Tom").withEmail("joel...@gmail.com").withAge(44); writeln(p); } ``` VS:`C++` ```d struct Person { string name, email; ulong age; } Person a{"n","email",33}; ``` D: ```d import std.stdio; struct Person { string name, email; ulong age; } void main() { Person p = Person(name: "n", email: "email", age: 33); writefln!"%s"(p); } ```
Re: Delegates and values captured inside loops
On Saturday, 20 January 2024 at 15:59:59 UTC, Anonymouse wrote: I remember reading this was an issue and now I ran into it myself. ```d import std.stdio; void main() { auto names = [ "foo", "bar", "baz" ]; void delegate()[] dgs; foreach (name; names) { dgs ~= () => writeln(name); } foreach (dg; dgs) { dg(); } } ``` Expected output: `foo`, `bar`, `baz` Actual output: `baz`, `baz`, `baz` If I make `names` an `AliasSeq` it works, but I need it to be a runtime array. Is there a workaround? ``` foreach (name; names) { dgs ~= ((name) => () => writeln(name))(name); } ``` lol
Re: Nested delegates and closure allocations
On Tuesday, 16 January 2024 at 15:39:07 UTC, Anonymouse wrote: If I make a `scope` variable of the delegate and pass *it* to `receiveTimeout`, there no longer seems to be any mention of the closure in the error (given 2.092 or later). ```d void foo(Thing thing) @nogc { void sendThing(const string where, int i) { send(thing, where, i); } scope scopeSendThing = receiveTimeout(Duration.zero, scopeSendThing); } ``` Ignoring that it doesn't compile for other reasons; provided `scope scopeSendThing = ` compiles -- as in, `` is eligible for `scope` -- is this a valid workaround? Correct. The problem is that `receiveTimeout` is defined as a template variadic function: it *can* take a scoped function, but it doesn't (can't) declare that its argument is always scoped, so since scoped parameters are opt-in, it defaults to unscoped. And has to also default to unscoped, because you can pass unscoped values to scoped parameters but not the other way around, so it defaults to the most generic type available. With your scoped variable you provide DMD the critical hint that actually you want the closure to be scoped, and once the value is scoped it stays scoped.
Re: Nested delegates and closure allocations
On Tuesday, 16 January 2024 at 10:56:58 UTC, Anonymouse wrote: I'm increasingly using nested delegates to partition code. ```d void foo(Thing thing) { void sendThing(const string where, int i) { send(thing, where, i); } sendThing("bar", 42); } ``` ... 3. Those referenced stack variables that make up the closure are allocated on the GC heap, unless: * The closure is passed to a scope parameter. * The closure is an initializer for a scope variable. * The closure is assigned to a scope variable. I'm generally not storing the delegates or passing them around as values, so I don't think the thing about scope variables and parameters *directly* applies. Am I safe as long as I don't do something like, pass `` as an argument to `std.concurrency.receive`? Yes.
Re: Trying to understand map being a template
On Saturday, 6 January 2024 at 17:57:06 UTC, Paul Backus wrote: On Friday, 5 January 2024 at 20:41:53 UTC, Noé Falzon wrote: In fact, how can the template be instantiated at all in the following example, where no functions can possibly be known at compile time: ``` auto do_random_map(int delegate(int)[] funcs, int[] values) { auto func = funcs.choice; return values.map!func; } ``` Thank you for the insights! It works for the same reason this example works: ```d void printVar(alias var)() { import std.stdio; writeln(__traits(identifier, var), " = ", var); } void main() { int x = 123; int y = 456; printVar!x; // x = 123 printVar!y; // y = 456 x = 789; printVar!x; // x = 789 } ``` To clarify, what this actually compiles to is: ```d void main() { int x = 123; int y = 456; void printVar_x() { import std.stdio; writeln(__traits(identifier, x), " = ", x); } void printVar_y() { import std.stdio; writeln(__traits(identifier, y), " = ", y); } printVar_x; printVar_y; x = 789; printVar_x; } ``` Which lowers to: ```d struct mainStackframe { int x; int y; } void printVar_main_x(mainStackframe* context) { import std.stdio; writeln(__traits(identifier, context.x), " = ", context.x); } void printVar_main_y(mainStackframe* context) { import std.stdio; writeln(__traits(identifier, context.y), " = ", context.y); } void main() { // this is the only "actual" variable in main() mainStackframe frame; frame.x = 123; frame.y = 456; printVar_main_x(); printVar_main_y(); frame.x = 789; printVar_main_x(); } Same with `map`.
Re: Dirty DMD
On Saturday, 18 November 2023 at 18:52:07 UTC, JN wrote: Latest DMD for Windows downloaded from here: https://downloads.dlang.org/releases/2.x/2.105.3/dmd-2.105.3.exe reports version as dirty: DMD64 D Compiler v2.105.3-dirty Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved written by Walter Bright what does it mean by dirty? Oops. It means whoever built it had uncommitted changes in their version of the code. It's probably harmless though - somebody trying to smuggle in changes could just disable that annotation.
Re: DLF September 2023 Monthly Meeting Summary
On Monday, 13 November 2023 at 00:18:35 UTC, Richard (Rikki) Andrew Cattermole wrote: Part of the problem with shared is that it is completely inverse of what it should be. It fundamentally does not annotate memory with anything extra that is useful. At the CPU level there are no guarantees that memory is mapped only to one thread, nor at the language level. Therefore all memory is shared between threads. As long as people have this inverted mindset in place and instead of wanting to prove its thread owned shared is going to be a problem for us. Remove shared, add atomic storage class. Figure out thread owned/shared memory some other day. Just to once again add my own view, since I don't see it represented a lot: Remove shared or don't, at least *stop making `synchronized` imply `shared`.* I don't care about shared, I don't care about atomics, I want to use the mutex style of protecting access, where I manually think about who exclusively owns what memory. But I can't use `synchronized`, because then I have to cast *every access to `this`,* which is clearly insane, and as a result invariant-using class code is *straight up incorrect,* because I have literally no choice but to do this: ``` class Foo { private int[] array; invariant { synchronized (this) { assert(this.array.all!(i => i > 0)); } } void foo(int i) in (i > 0) { synchronized (this) { // Note that the invariant on `array` is not actually guaranteed here! // Some other method in another thread might currently have set up a violation // for it, but switched out before its out invariant could be locked and tested. // So we can have a *wrong invariant in this method,* which has done absolutely // nothing wrong. Very fun!! array ~= i; } } } ``` The only way to prevent this is `synchronized class`, but even if all missing features are implemented, `array` would be `shared`. Which is just wrong, as `array` is *privately owned storage of the class,* a fact I cannot prove to the compiler but is nonetheless true. `synchronized class` brings in the one feature I don't want to use and makes it an unavoidable condition of *literally writing correct code at all*. So yeah `shared`, I didn't *want* to be your enemy but apparently you wanted to be mine. `shared` delenda est.
Re: Request you advise : isValidFilename
On Friday, 22 September 2023 at 17:52:51 UTC, FeepingCreature wrote: "Integer representation" here refers to the ANSI index or Unicode codepoint, ie. the filename must not contain `\x00` to `\x31`. Er oops, make that `\x00` to `\x1f`.
Re: Request you advise : isValidFilename
On Friday, 22 September 2023 at 17:44:50 UTC, Vino wrote: Hi All, Request you help in understanding why the below code is always returning true when it should return false as per the documentation. Documentation ``` filename must not contain any characters whose integer representation is in the range 0-31. ``` "Integer representation" here refers to the ANSI index or Unicode codepoint, ie. the filename must not contain `\x00` to `\x31`.
Re: dlang custom keyword for struct/class
On Sunday, 17 September 2023 at 15:55:37 UTC, Vitaliy Fadeev wrote: Is it possible to write like this in D? ```d struct Message { ulong timestamp; } Message LongMessage { ubyte[255] s; } // // it mean // // struct LongMessage // { // Message _super; // alias _super this; // ubyte[255] s; // } // // or // // struct LongMessage // { // ulong timestamp; // ubyte[255] s; // } ``` Is it possible? No, there's no struct inheritance. But you can just write the `alias this` version manually.
Re: DConf '23 Talk Videos
On Sunday, 17 September 2023 at 15:35:04 UTC, Mike Parker wrote: I've begun editing, rendering, and publishing the standalone videos of the DConf '23 talks. The venue gave us access to all of their footage this year rather than just a subset of it, and I'm happy to make use of it. I've also got the benefit of AI subtitle generation built into the latest version of the editor I'm using. It does an amazing job of it. The first video required only very minor tweaks. The upshot is that if you have English CC enabled, you'll get a more accurate script than the auto-generated one from YouTube. The first video, Saeed's talk, is live: https://youtu.be/cN0zS04wOFU Please let me know if anything is problematic with the video and of any errors you happen to find in the subtitles. I'm not going to announce every video I publish. I'll announce when I'm finished with all of them. If you're not subscribed to the channel, you can periodically check the DConf '23 playlist for updates: https://youtube.com/playlist?list=PLIldXzSkPUXWH97DYBENhAqLk4DUqKUmf=kpEpj3Y_A5zSAoVT I'll try to publish a new one every two or three days, but I've got a lot going on right now and make no promises. If you want to keep up with my progress on the DConf videos and other tasks related to the DLF's YouTube channel, you can follow the project tracker here: https://github.com/orgs/dlang/projects/40 Thank you for your work!
Re: isBinary
On Sunday, 3 September 2023 at 10:11:22 UTC, Vino wrote: Hi All, Any update as to when the function described in the below ticked would be action-ed, I am more interested in isBinary (check a file whether is is binary file or not) http://d.puremagic.com/issues/show_bug.cgi?id=9455 From, Vino Those are totally different ideas. When writing a file, some operating systems support line ending conversion. To do that, you explicitly specify that you are writing to a text file. Then a "binary file" is just any file that is not a text file. However, this is merely a conversion process on writing. You cannot discover whether a file is a binary file in reverse. At most you can check whether *you yourself* opened the file as a binary file.
Re: Warning for anyone who was at DConf.
On Sunday, 3 September 2023 at 07:04:44 UTC, Steven Schveighoffer wrote: On Saturday, 2 September 2023 at 20:41:33 UTC, Dukc wrote: Just a while ago I was hit by some sort of a violent ailment. I first noticed it like an hour ago, and I'm shivering as I stand in a well-heated house, despite having had a sauna just a while ago. Temperature already high. I wouldn't rule out having contracted it at DConf, and could well be the Covid. Please watch your health for a few days if you were at DConf or related events. Fwiw it’s definitely Covid. I tested positive today. Now trapped in London Heathrow for another week. A bizarre incident, I was on the plane going to Boston and they did a 180 after 30 minutes and booked us the next day. But of course, there is now this. Ugh -Steve I also have two tests very loudly indicating positive here. --Mathis
Re: D Language Foundation August 2023 Monthly Meeting Summary
On Saturday, 2 September 2023 at 20:27:04 UTC, Bonarc wrote: On Wednesday, 30 August 2023 at 14:19:03 UTC, FeepingCreature wrote: When you want to react to ~every keypress in a language server impl with updated coloring, it starts to be problematic. Think in terms of "UI feedback" rather than "project compilation". You only need an AST for this though right? Not a full compilation? Depends if you want language server info, ie. types, docs, etc. You can do very clever things here like caching symbols between runs, but the *naive* way is to run the frontend at least all the way through to sema2.
Re: pointer to std.algorithm.iteration : splitter
On Thursday, 31 August 2023 at 05:16:02 UTC, Vino wrote: Hi All, Request your help on the below error Program ``` void main() { import std.stdio:writeln; import std.algorithm.iteration : splitter; auto splitter_ptr = !((a, b) => a.splitter(b).array); string str = "TEST1;TEST2;TEST3"; auto words = splitter_ptr(str, ';'); foreach (word; words) { writeln(word); } } ``` ``` Error: template instance `splitter!((a, b) => a.splitter(b).array)` does not match any template declaration ``` From, Vino Why are you trying to take pointers of lots of different things? You should pretty much never need pointers in normal D code.
Re: D Language Foundation August 2023 Monthly Meeting Summary
On Friday, 25 August 2023 at 02:10:25 UTC, harakim wrote: I'm also curious why a 500ms compile time would be generally recognized as way too long. Is it because it has potential to be faster or does it cause some legitimate problem? That's a question at large, not for Matheus. When you want to react to ~every keypress in a language server impl with updated coloring, it starts to be problematic. Think in terms of "UI feedback" rather than "project compilation".
Re: File size
On Tuesday, 22 August 2023 at 16:22:52 UTC, harakim wrote: On Monday, 21 August 2023 at 11:05:36 UTC, FeepingCreature wrote: Can you print some of the wrong sizes? D's DirEntry iteration code just calls `FindFirstFileW`/`FindNextFileW`, so this *shouldn't* be a D-specific issue, and it should be possible to reproduce this in C. Thanks for the suggestion. I was working on getting the list for you when I decided to first try and reproduce this on Linux. I was not able to do so. Then I opened the Linux File Explorer and went to one of the files. There were two files by that name, with names differing only by case. In windows, I only saw one, because Windows Explorer only supports one file with an identical case-insensitive name per directory. Unsurprisingly, that is also the one that was selected by getSize(filename). The underlying windows functions must ignore case as well and select the same way as Explorer (which makes sense). That explains why Windows Explorer reported the same size as getsize(name) in every case, while DirEntry.size would match for the file with the same case as windows recognized and not for the file with a different case. I was able to get into this state because I copied the files (merged directories) in Linux. It was interesting to look into. It seems everything is working as designed. It shouldn't be an issue for me going forward either as I move more and more towards Linux. That's hilarious! I'm happy you found it.
Re: File size
On Monday, 21 August 2023 at 07:52:28 UTC, harakim wrote: I have been doing some backups and I wrote a utility that determines if files are an exact match. As a shortcut, I check the file size. So far so good on this with millions of files until I found something odd: getSize() and DirEntry's .size are producing different values. ... It seems really odd that getSize(sourceFile.name) is returning a different number than sourceFile.size. This is an external HDD on windows formatted in ntfs that it is reading. I believe I originally wrote the files to the file system in Windows, but then today I cut and paste them (in the same drive) in Linux. However, this is the first time this has happened after millions of comparisons and it only happened for about 6 files. It does happen consistently though. I have verified that the file size is that reported by getSize and not sourceFile.size and that the files open correctly. ... Can you print some of the wrong sizes? D's DirEntry iteration code just calls `FindFirstFileW`/`FindNextFileW`, so this *shouldn't* be a D-specific issue, and it should be possible to reproduce this in C.
Re: Finding duplicate elements
On Tuesday, 15 August 2023 at 17:59:27 UTC, vino wrote: Hi All, Request your help in finding duplicate element without sorting as per the below example ``` Example: string[] args = [" test3", "test2 ", " test1 ", " test1 ", " "]; Output Required: If duplicate element found then print "Duplicate element found: " else print ["test3", "test2", "test1"]; ``` From, Vino.B ``` import std; void main() { string[] args = [" test3", "test2 ", " test1 ", " test1 ", " "]; findDuplicates(args); } void findDuplicates(string[] args) { bool[string] dupes; foreach (arg; args) { if (arg in dupes) { writefln!"Duplicate element found: %s"(arg); return; } dupes[arg] = true; } writefln!"%s"(dupes.keys); } ```
Re: toLower
On Tuesday, 15 August 2023 at 20:09:28 UTC, Joel wrote: On Tuesday, 15 August 2023 at 16:54:49 UTC, FeepingCreature wrote: But does *not* import `std.ascii`! So there's no ambiguity inside the `sort` string expression between the two `toLower` functions.. How do I get it to work? I tried std.ascii.toLower. And using alias toLower=std.ascii.toLower; To elaborate more, `toLower` doesn't work because function-scope aliases are not considered for UFCS. ``` alias toLower = std.ascii.toLower; ... // So this does actually work: .map!toLower // but this does not, because it looks for a UFCS-capable symbol .map!(c => c.toLower) // but this does again .map!(c => toLower(c)) ```
Re: toLower
On Tuesday, 15 August 2023 at 16:47:36 UTC, Joel wrote: How come toLower works in the sort quotes, but not in the map? ```d void main() { import std; "EzraTezla" .to!(char[]) .byCodeUnit .sort!"a.toLower c.toLower) .writeln; } ``` When you pass a string to a lambda, it's evaluated in `std.functional.unaryFun`/`binaryFun`. At that point, these modules are imported for use in string expressions: ``` import std.algorithm, std.conv, std.exception, std.math, std.range, std.string; import std.meta, std.traits, std.typecons; ``` And `std.string` itself publically imports: ``` public import std.uni : icmp, toLower, toLowerInPlace, toUpper, toUpperInPlace; ``` But does *not* import `std.ascii`! So there's no ambiguity inside the `sort` string expression between the two `toLower` functions..
Re: On assigning const to immutable
On Thursday, 13 July 2023 at 11:55:17 UTC, Ki Rill wrote: Why does the first example `class A` work, but the second one with `class B` does not? ```D class A { immutable int a; this(in int a) { this.a = a; } } class B { immutable int[] b; this(in int[] b) { this.b = b; } } void main() { auto a = new A(1); auto b = new B([1, 2]); } ``` It implicitly converts `const` to `immutable`, but fails to do the same with an array. Is it intentional? Why? Yep: `immutable` is data that *cannot ever* change. If you could convert `int[]` to `immutable int[]`, you could do this: ``` int[] a = [2]; immutable(int)[] b = a; auto first = b[0]; a[0] = 3; auto second = b[0]; // Wait, this fails? I thought `b` was immutable. assert(first == second); ``` Use `array.idup` (immutable dup) to turn `int[]` into `immutable int[]`. And you can convert `int` to `immutable int` because it's a "value copy": you cannot mutate the immutable variable through an assignment to the original. Generally speaking, only the constness of referenced data matters for assignment. That's why you can assign `string` to `immutable string`, because `string` is `immutable(char)[]`: the referenced data is immutable in both cases.
Re: Dynamic array of strings and appending a zero length array
On Saturday, 8 July 2023 at 17:15:26 UTC, Cecil Ward wrote: I have a dynamic array of dstrings and I’m spending dstrings to it. At one point I need to append a zero-length string just to increase the length of the array by one but I can’t have a slot containing garbage. I thought about ++arr.length - would that work, while giving me valid contents to the final slot ? What I first did was arr ~= []; This gave no errors but it doesn’t increase the array length, so it seems. Is that a bug ? Or is it supposed to do that? You can append an element to an array. You can also append an array to an array. Because [] can be an array of any type, the compiler guesses that it's an empty `string[]` array and appends it to no effect.
Re: Inheritance and arrays
On Monday, 3 July 2023 at 09:50:20 UTC, Arafel wrote: Hi! I am a D user coming from java, rather than from C/C++ (although obviously also have some exposure to them), and thus apparently one of the few people here who likes OO (within reason, of course). So while I appreciate the fact that D closely follows java's design, I wonder why there is no implicit inheritance for arrays (also the same applies to AAs): ```d interface I {} class C : I {} void main() { I i; C c = null; i = c; // Works I[] ii; C[] cc = null; // ii = cc; // Doesn't work: Error: cannot implicitly convert expression `cc` of type `C[]` to `I[]` ii = cast (I[]) cc; // Works, but why do I need to cast? } ``` The `cast` version "works", but will crash at runtime. In D, as opposed to Java, a reference to an object has a *different pointer value* than a reference to the interface-typed version of that object. This is necessary for efficient compiled virtual method calls on the interface. But for the same reason, you cannot reinterpret an array of objects to an array of interfaces; even if you can implicitly convert each object to that interface, there's a difference between automatically rewriting a value and automatically rewriting every element of an array: one is O(1), the other is O(n) and incurs a GC allocation.
Re: Inheritance and arrays
On Monday, 3 July 2023 at 09:50:20 UTC, Arafel wrote: Hi! I am a D user coming from java, rather than from C/C++ (although obviously also have some exposure to them), and thus apparently one of the few people here who likes OO (within reason, of course). So while I appreciate the fact that D closely follows java's design, I wonder why there is no implicit inheritance for arrays (also the same applies to AAs): ... Is this a conscious design decision (if so, why?), or just a leak of some implementation detail, but that could eventually be made to work? See also this thread on implementation details: https://forum.dlang.org/post/bibtjiiwpiqzzfwgx...@forum.dlang.org
Re: Bug in usage of associative array: dynamic array with string as a key
On Friday, 30 June 2023 at 19:05:23 UTC, Cecil Ward wrote: I have code roughly like the following: dstring str = "name"d; uint ordinal = (( str in Decls.ordinals ) !is null) ? Decls.ordinals[ str ] : -1; struct Decls { uint[ dstring] ordinals; } //and Decls.ordinals[ str ] = ordinal_counter++; The problem is that it always returns ordinal== -1 from the expression. Can you sort me out? Impossible to tell without a complete repro, I'm afraid. The expression, at least, looks correct at first glance. Note that you can do `uint ordinal = Decls.ordinals.get(str, -1);`.
Re: static if - unexpected results
On Friday, 23 June 2023 at 18:43:06 UTC, Steven Schveighoffer wrote: It should be a spec change. Change POD to say "type" instead of "struct". The goal of `isPOD` is to determine how careful generic code needs to be to pass the type around, or copy it. Changing it to false implies that it is not "plain old data". I.e. it has a destructor, it has hidden members, or it cannot be copied via bit copying (all of these do not fit the type in question). The only other option is to error on calling `__traits(isPOD, char)`, but I think that's even worse. -Steve Yeah, I think that's also where I'm standing. The current behavior seems correct and useful, it's just not documented correctly.
Re: static if - unexpected results
On Friday, 23 June 2023 at 14:22:24 UTC, DLearner wrote: Hi Was looking for compile-time detection of a struct variable. However, the following test code gave the two 'FAILS' shown below. Comments? ``` void main() { import std.stdio : writeln; import std.traits; string mxnTst(string VarName) { return `static if (is(typeof(` ~ VarName ~ `) == char)) {` ~ `writeln("` ~ VarName ~ ` ", " is a char");` ~ `} else static if (__traits(isPOD, typeof(` ~ VarName ~ `))) {` ~ `writeln("` ~ VarName ~ ` ", " is a struct");` ~ `} else static if (is(typeof(` ~ VarName ~ `) == int)) {` ~ `writeln("` ~ VarName ~ ` ", " is an int");` ~ `} else {` ~ `static assert(false, "mxnTst Variable '` ~ VarName ~ `' is of unknown type");` ~ `}` ; } char char1; int int1; byte byte1; struct foo { int fooint; char foochar; } foo foovar1; mixin(mxnTst("char1")); // Expected: char1 is a char. Actual: char1 is a char. (ok) mixin(mxnTst("int1"));// Expected: int1 is an int. Actual: int1 is a struct. (FAIL) mixin(mxnTst("foovar1")); // Expected: foovar1 is a struct. Actual: foovar1 is a struct. (ok) mixin(mxnTst("byte1")); // Expected: Run to fail with the static assert message. Actual: byte1 is a struct. (FAIL) } ``` ``` static assert(__traits(isPOD, int)); // ok. static assert(__traits(isPOD, byte)); // ok. ``` It's a bug in either the spec or the compiler.
Re: Strange behaviour of __traits(allMembers)
On Sunday, 18 June 2023 at 10:21:16 UTC, IchorDev wrote: On Sunday, 18 June 2023 at 10:04:14 UTC, FeepingCreature wrote: On Sunday, 18 June 2023 at 09:48:40 UTC, IchorDev wrote: Does anyone understand why this happens? Is there any way to subvert this behaviour, or is it actually a bug? Yes, see also my bug report, https://issues.dlang.org/show_bug.cgi?id=20008 "__traits(allMembers) of packages is complete nonsense". Whaat why has this not been fixed in the last 4 years! I think because nobody *needs* `__traits(allMembers)` of packages. Mostly people just learn to skip them while scanning modules, and instead of iterating imports, they do the standard hack of "generate a list of all files in the project, string import it, and generate import statements for each". Yeah it's ugly. I guess the lesson is, nothing takes as long to fix as a bug with a well-known workaround.
Re: Strange behaviour of __traits(allMembers)
On Sunday, 18 June 2023 at 09:48:40 UTC, IchorDev wrote: Does anyone understand why this happens? Is there any way to subvert this behaviour, or is it actually a bug? Yes, see also my bug report, https://issues.dlang.org/show_bug.cgi?id=20008 "__traits(allMembers) of packages is complete nonsense".
Re: The DConf '23 Schedule is Live!
On Tuesday, 6 June 2023 at 13:33:00 UTC, Mike Parker wrote: Thanks again to everyone who submitted talks for DConf '23, and congratulations to those who were accepted. We've got what looks to be another solid lineup this year. Check it out: https://dconf.org/2023/index.html And remember, early-bird registration ends next week. Get your discounted rate while you still can! https://dconf.org/2023/index.html#register I've also updated the page with information about BeerConf. Unfortunately, pub hire rates in the area are well beyond our budget this year. Much, much higher than last year. So we've fallen back to what we did pre-2019 and tentatively designated a hotel as the BeerConf spot: Travelodge Central City Road I know from staying there last year that they've recently undergone renovations and have an enclosed restaurant/lounge space off of the lobby, where one of the front desk clerks can sell beverages (alcoholic and non-) and snacks after the restaurant closes. It's possible we could pick another spot, or (less likely) our event planner might find something to fit in our budget. I'll announce here and update the website if anything changes. See you in London! I see that you strategically left time after my presentation. :looks at his notes: That is probably wise. (I have some rants I can cut if I *really* need to fit in the 45 minutes. But they're very fun rants.) Anyway, I can't wait to show off my compiler to everyone. It's not "finished", but it has some seriously cool things.
Re: Beta 2.104.0
On Tuesday, 2 May 2023 at 00:34:45 UTC, Iain Buclaw wrote: This release comes with 11 major changes, including: - In the standard library, `std.typecons.Rebindable` now supports all types Tiny note of warning: `Rebindable` supports all types that it did not previously support, including structs. However, the previous `Rebindable` had a special logic where if you passed it an _array_, it would simply alias itself to `Unqual!ElementType[]`. So you cannot rely that if you write `Rebindable!T foo;`, that you can then do `foo.get`. I'm trying to fix that, but it's a bit controversial. My main argument is that ~nobody used to use it anyway, so we may as well fix it now as it's actually becoming useful.
Re: A New Era for the D Community
On Sunday, 7 May 2023 at 02:15:02 UTC, monkyyy wrote: On Wednesday, 3 May 2023 at 11:13:34 UTC, Mike Parker wrote: IVY, their organizational development program Your solution to hearing luas dev saying "I dont manage anything" and whatever feedback from your survey, is you got corporate training and now you gun-ho about management? Was I in an extreme minority here? https://monkyyyscience.substack.com/i/93037044/stop-pretending-d-is-a-corporate-language *Stop pretending D is a corporate language* You have a community of meta-programming-crazed iconoclasts Either you believe this small community has great 1000x programmers or you don't and we are doomed anyway If Adr says "I want to make a color lib", don't stand in his way give him the namespace std.community.color that can be written to his style guide, to his standards, on his github, and when a new version of the compiler ships a script will grab a snapshot Please redesign and relaunch `std.experimental` to have a completely hands-off, anarchic structure. I'm confused how you came to the conclusion that complaints about management mean there should be more management instead of a fundamentally different approach. Don't herd cats, just clean out the litter boxes. To be honest, this has always been my take as well. I don't want to be critical here, because I have no idea what IVY is and what is supposed to come of this, but I have seen people for years saying that D has a management problem, and this has always seemed wrong to me. D has an effort and agreement problem, but that's not something you can manage in a community of volunteers. Management implies an ability to focus effort. Broadly, D doesn't have users who want to improve D, D has users who want to improve doing X *with D.* Now D management can say "we want to reach style X" or "we are working on improvement Y"; they can do this by setting review standards and only merging PRs that go in the direction they want the project to do. But they cannot decide what work gets done - only accept or reject. Isn't the point of the DIP process primarily to be able to forecast whether a feature will be accepted or rejected? So managing the work requires an inherently reactive approach. This is why I never understood why people were saying D "needed better management". What work got done has always been, in this language, a matter of some person saying "I could do this cool thing" and going and doing it. This can be mismanaged, sure, and there's room for improvement, granted, but better management can still not make improvements appear where currently there are none. (Honestly, maybe 80% of the time when I've seen "D needs better management", it has been code for "D management didn't like my proposal.")
Re: undefined reference to "main"
On Wednesday, 5 April 2023 at 09:19:17 UTC, Alexander Zhirov wrote: How to compile the example given in the book correctly? When compiling, an error occurs that the main function is missing. If I replace `shared static this()` with `void main()', then everything starts. What does the compilation string in `dub` and `dmd` look like correctly? ```d import vibe.d; shared static this() { auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["::1", "127.0.0.1"]; listenHTTP(settings, ); logInfo("Please open http://127.0.0.1:8080/ in your browser."); } void hello(HTTPServerRequest req, HTTPServerResponse res) { res.writeBody("Hello, World!"); } ``` This seems to work for me: ```d /+ dub.json: { "name": "test", "dependencies": { "vibe-d": "*" } } +/ import vibe.d; shared static this() { auto settings = new HTTPServerSettings; settings.port = 8080; settings.bindAddresses = ["::1", "127.0.0.1"]; listenHTTP(settings, ); logInfo("Please open http://127.0.0.1:8080/ in your browser."); } void main() { runApplication; } void hello(HTTPServerRequest req, HTTPServerResponse res) { res.writeBody("Hello, World!"); } ``` Run with ``` dub run --single test.d ```
Re: Can nice D code get a bit slow?
On Wednesday, 8 March 2023 at 10:49:32 UTC, Markus wrote: So, having no clue about D (just bought some books), I wanted to ask if nice looking code can become slow, in general. In the mentioned case it's just that I like the packaging of functions into some sort of scope (OOP) versus the flat C and Go stuff. I like OOP for this reason, but now I'm unsure whether I might stay out of creating classes at all. Uh, hope you understand my vague question, sorry about that. I found D to be the right place because it's not missing any essential feature I know of. Kind regards If you write D like Java, it will be slow like Java - actually slower, because D's GC isn't as good. If you remember to use structs for value types (no `class Vector3f`, `class Point` etc.), you should be fine. Though as a general rule, don't worry about it too much. Even slow D is still fast.
Re: How would the equivalent C type be in D?
On Wednesday, 1 March 2023 at 09:37:48 UTC, rempas wrote: Thank you! You are amazing for explaining it! I was so focused on thinking that I'm doing something wrong with the type that I didn't noticed that the pointers, points to nowhere so the function obviously has nowhere to write to. Like... OMG! And I want to make a fully fledged compiler when making stupid mistakes like that. Btw, When I executed the program, I got "Error Program exited with code -11". You said that the code was "11". What about that dash? If it is not a "minus" and it's just the dash symbol, then what's the idea? Yay! (Definitely make a compiler, it's a great way to learn.) Yes, that is a bit weird. First of all, the actual signal is 11 ``` $ grep SIGSEGV /usr/include/bits -R /usr/include/bits/signum-generic.h:#define SIGSEGV 11 /* Invalid access to storage. */ ``` As per the POSIX spec https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_21_18. signal exits must be reported with exit codes above 128. Customarily, shells will simply add 128 to the signal: ``` $ cat test.c; gcc test.c -otestc; ./testc; echo $? int main() { int* ip = 0; *ip = *ip; return 0; } Segmentation fault 139 ``` 139 being 128 + 11, but POSIX does not specify *how* the signal code is converted to an exit code. For instance, Python reports a signal 11 exit as -11. Strictly speaking, -11 is "above 128" in two's complement, corresponding to unsigned 245. But I don't know why Python does this. Presumably your shell does it the same way?
Re: How would the equivalent C type be in D?
On Wednesday, 1 March 2023 at 09:37:48 UTC, rempas wrote: Thank you! You are amazing for explaining it! I was so focused on thinking that I'm doing something wrong with the type that I didn't noticed that the pointers, points to nowhere so the function obviously has nowhere to write to. Like... OMG! And I want to make a fully fledged compiler when making stupid mistakes like that. Btw, When I executed the program, I got "Error Program exited with code -11". You said that the code was "11". What about that dash? If it is not a "minus" and it's just the dash symbol, then what's the idea? Yay! Yes, that is a bit weird. First of all, the actual signal is 11 ``` $ grep SIGSEGV /usr/include/bits -R /usr/include/bits/signum-generic.h:#define SIGSEGV 11 /* Invalid access to storage. */ ``` As per the POSIX spec https://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_21_18. signal exits must be reported with exit codes above 128. Customarily, shells will simply add 128 to the signal: ``` $ cat test.c; gcc test.c -otestc; ./testc; echo $? int main() { int* ip = 0; *ip = *ip; return 0; } Segmentation fault 139 ``` 139 being 128 + 11, but POSIX does not specify *how* the signal code is converted to an exit code. For instance, Python reports a signal 11 exit as -11. Strictly speaking, -11 is "above 128" in two's complement, corresponding to unsigned 245. But I don't know why Python does this. Presumably your shell does it the same way?
Re: How would the equivalent C type be in D?
On Wednesday, 1 March 2023 at 08:26:07 UTC, FeepingCreature wrote: ```d uint32_t[1] value; value[0] = screen.black_pixel; xcb_create_gc(connection, black, win, mask, value.ptr); ``` To expand on this: ```d uint32_t[2] value; uint32_t* value_ptr = value.ptr; // We are allowed to access the pointer at index 0 // because we declared the value it points to, to be size 2. value_ptr[0] = 0; // This is also allowed, because `value_ptr` is // a pointer to two sequential `uint32_t` in memory. value_ptr[1] = 0; // But this access would segfault, because it's trying to write // to the third element of a two-element array: value_ptr[2] = 0; ``` Note: I just lied; `value_ptr[2]` would not segfault, for somewhat technical reasons; but it *would* corrupt your program's memory. At any rate, it's an invalid operation.
Re: How would the equivalent C type be in D?
On Wednesday, 1 March 2023 at 08:12:05 UTC, rempas wrote: I'm looking into [this](https://www.x.org/releases/X11R7.7/doc/libxcb/tutorial/index.html) tutorial to learn XCB and I'm trying to write the code in D with betterC. In the section 9.1 (sorry, I cannot give a section link, the article does not give us this ability), I'm facing a problem and my program exits with the exit code: "-11". I suspect that this happens because I haven't translated the following code the right way: ```d uint32_t value[1]; value[0] = screen.black_pixel; xcb_create_gc(connection, black, win, mask, value); ``` I originally tried to translate this as: ```d uint[1] value; value[0] = screen.black_pixel; xcb_create_gc(connection, black, win, mask, value); ``` But then, when I tried to compile the program, I got the following error: ``` Error: function `headers.xcb_create_gc(xcb_connection_t* c, uint cid, uint drawable, uint value_mask, const(void)* value_list)` is not callable using argument types `(xcb_connection_t*, uint, uint, uint, uint[1])` src/draw.d(18,16):cannot pass argument `value` of type `uint[1]` to parameter `const(void)* value_list` ``` So I thought of doing the following: ```d uint* value; value[0] = screen.black_pixel; xcb_create_gc(connection, black, win, mask, value); ``` Now the program complies but I get the "-11" exit code. Another thing I thought (which is probably the same thing under the hood but done a different way): ```d const(void)* value; (cast(ubyte*)value)[0] = screen.black_pixel; xcb_create_gc(connection, black, win, mask, value); ``` Same results. Any ideas? 11 is SIGSEGV. A segfault, or access violation, happens when you try to access unallocated memory. In this case, let me annotate your code so it's easier to see what's happening: ```d // null is the default value for a pointer uint* value = null; // because `value` is null, the first index also lies at null. assert([0] is null); // So we try to store screen.black_pixel at memory address null, which is unallocated. value[0] = screen.black_pixel; xcb_create_gc(connection, black, win, mask, value); ``` As there is no memory segment allocated at address null, the CPU indicates a segmentation fault, which terminates the program. So yes, `xcb_create_gc` wants a `uint*` parameter, but not just any `uint*` will do: it has to point to valid memory. Going back to the first snippet, what's happening here is that in C, arrays implicitly convert to pointers, because C doesn't have a notion of array types as distinct from pointer types. So you can have a variable declared as `uint[1]`, but pass it to a parameter that expects `uint*`, and the value that is passed will just be the address of the first field of the array. However, even in C, if you try to define `value` as `uint*`, it will segfault in the same way. Instead, in D, you need to tell the compiler to define an array of size 1, and then pass a pointer to the array's first member explicitly: ```d uint32_t[1] value; value[0] = screen.black_pixel; // this is what C does under the hood xcb_create_gc(connection, black, win, mask, [0]); ``` Or shorter, but with the same effect: ```d uint32_t[1] value; value[0] = screen.black_pixel; xcb_create_gc(connection, black, win, mask, value.ptr); ```
Re: Non-ugly ways to implement a 'static' class or namespace?
On Monday, 20 February 2023 at 07:11:49 UTC, Mike Parker wrote: On Monday, 20 February 2023 at 06:26:34 UTC, FeepingCreature wrote: There have now been three pages produced by three people all agreeing with each other. At what point does it start being spam? Yes, it's all just noise now. Let's end it here. Further posts in this thread will be deleted. oy vey, shut it down fucking idiot
Re: Non-ugly ways to implement a 'static' class or namespace?
On Monday, 20 February 2023 at 05:21:44 UTC, forky wrote: On Friday, 10 February 2023 at 07:04:31 UTC, Max Samukha wrote: ... Having class-private doesn't preclude module-private. Dennis even submitted a PR implementing class-private, but it stalled because people couldn't agree on whether class-private should be "private to class" or "private to class instance". It likely the 'disagreement' was intentional .. i.e. to stall ;-) But in any case, it should be class private. There have now been three pages produced by three people all agreeing with each other. At what point does it start being spam?
Re: Non-ugly ways to implement a 'static' class or namespace?
On Thursday, 16 February 2023 at 02:27:23 UTC, Mike Parker wrote: On Thursday, 16 February 2023 at 02:26:44 UTC, Mike Parker wrote: Wrong. I'm arguing things: Geez. "I'm arguing 2 things:" Springboarding off this post: This thread is vastly dominated by some people who care very much about this issue. Comparatively, for instance, I care very little because I think D already does it right. But then the thread will look unbalanced. This is a fundamental design flaw in forum software. So let me just say: I think D does it right. D does not have class encapsulation; it has module encapsulation. This is by design, and the design is good.
Re: Is defining get/set methods for every field overkill?
On Tuesday, 22 November 2022 at 21:45:29 UTC, []() {}() wrote: On Tuesday, 22 November 2022 at 21:00:58 UTC, []() {}() wrote: "Being able to declare a “friend” that is somewhere in some other file runs against notions of encapsulation." (This is the motivation for that article it seems). I completely disagree with the assertion. C++ Friend notion does not, not by any means, run against the notion of encapsulation. Sure, it expands the perimeter (i.e. it puts a door in the wall). But, and this is my point, there is a guard standing at the door. And that guard knows who has been authorised to pass through it. The encapsulation remains. Only its perimeter has been expanded. One could argue that D's approach is just that. It expands the perimeter to the module level. But there's no guard at the door in D. Surely, this 'let anyone pass through' design, decreases encapsulation? How could it possibly increase encapsulation, as claimed, by the author of that article? If there were a means in the language for controlled sharing within a module, *that* would increase encapsulation. The module is the capsule. D is simply not interested in building a capsule around a class. D does not let "anyone" pass through, it lets "anyone in the module" pass through, because the module is the wall. I think this is a stronger concept of encapsulation than C++ friends because the encapsulation is lexical rather than just declarative.
Re: Is defining get/set methods for every field overkill?
On Thursday, 17 November 2022 at 04:39:35 UTC, thebluepandabear wrote: I am creating a TUI library and I have a class with the following constant fields: ``` class Label : Renderable { const string text; const TextAlignment textAlignment; const Color color; this(Dimensions dimensions, string text, TextAlignment textAlignment, Color color) { this.dimensions = dimensions; this(text, textAlignment, color); } this(string text, TextAlignment textAlignment, Color color) { this.text = text; this.textAlignment = textAlignment; this.color = color; } override Cell[] render() const { Cell[] cells; for (int x = 0; x < 0 + text.length; ++x) { cells ~= Cell(Coordinates(x, 0), text[x], color); } return cells; } } ``` I am debating whether or not I should add getter methods to these properties. On one hand, it will inflate the codebase by a lot, on the other hand -- in other languages like Java it is a good practice: ``` class Label : Renderable { private const string text; private const TextAlignment textAlignment; private const Color color; this(Dimensions dimensions, string text, TextAlignment textAlignment, Color color) { this.dimensions = dimensions; this(text, textAlignment, color); } this(string text, TextAlignment textAlignment, Color color) { this.text = text; this.textAlignment = textAlignment; this.color = color; } string getText() const { return text; } TextAlignment getTextAlignment() const { return textAlignment; } Color getColor() const { return color; } override Cell[] render() const { Cell[] cells; for (int x = 0; x < 0 + text.length; ++x) { cells ~= Cell(Coordinates(x, 0), text[x], color); } return cells; } } ``` It's not a lot of code that has been added but if you have a class with say 10 different fields, adding getter methods would definitely increase the code size by a lot, so what are you guys thoughts on this? Obligatory note that boilerplate https://code.dlang.org/packages/boilerplate exists for just this reason: class Label : Renderable { @ConstRead private const string text_; @ConstRead private const TextAlignment textAlignment_; @ConstRead private const Color color_; this(Dimensions dimensions, string text, TextAlignment textAlignment, Color color) { this.dimensions_ = dimensions; this(text, textAlignment, color); } override Cell[] render() const { Cell[] cells; for (int x = 0; x < 0 + text.length; ++x) { cells ~= Cell(Coordinates(x, 0), text[x], color); } return cells; } mixin(GenerateFieldAccessors); mixin(GenerateThis); }
Re: Beerconf October 2022
On Saturday, 29 October 2022 at 10:14:31 UTC, rikki cattermole wrote: And now for some good news! Its almost Halloween, so grab your candy and any spooky brews you may have, and join us for a ghostly chat! https://meet.jit.si/Dlang2022OctoberBeerConf I wish you'd announce the time a bit in advance. :)
Re: "chain" vs "~"
On Sunday, 7 August 2022 at 01:22:18 UTC, pascal111 wrote: Why we use "chain" while we have "~": '''D int[] x=[1,2,3]; int[] y=[4,5,6]; auto z=chain(x,y); auto j=x~y; ''' Chain doesn't allocate any memory. This can be useful occasionally.
Re: Obsecure problem 1
On Sunday, 31 July 2022 at 07:43:06 UTC, Salih Dincer wrote: Why are you using const for strings? After all, they are protected by immutable. Moreover, since you do not use refs, copies are taken in every function and also you have created extra copy for results. Note sure if I'm misunderstanding, but: D does not copy strings on value passing, because they're inherently reference types. You can think of a string (or any array) as a `struct { size_t length; T* ptr; }` combined with a bunch of syntax magic.
Re: D Language Foundation April Quarterly Meeting and Server Meeting Summaries
On Wednesday, 4 May 2022 at 16:21:19 UTC, Mike Parker wrote: Mario also mentioned that Mathis Beer is having "the usual problems" in his work because he is always "in the dark areas of the D compiler", but they have nothing causing them any major issues that need immediate attention. I don't get sensible bugs anymore! It's all cryptic stuff like "if I use random feature one, then random feature two while wrapped in random feature three, plus a syntax error in an unrelated module, the compiler literally catches on fire." My favorite recent one is https://issues.dlang.org/show_bug.cgi?id=22949 If you: - define a module with an enum that has an initializer that doesn't exist - and in another module, you define a struct - that speculatively compiles itself via `__traits(compiles)` - (dmd starts sweating nervously) - and imports from the first module a symbol that doesn't exist - then mixes it in - then import the first module again - and evaluate the enum Then you get an "Error: Unknown." This code has like three different errors! Missing import, mixin of a missing symbol, enum with an invalid initializer. Each of those individually, or in combinations of two, would be reported just fine. But, I think because `__traits(compiles)` strategically blocks *all* of them from being printed, the compiler ends up in a state where it knows that everything is wrong, but can no longer quite work out why or how. They're all like this. Well, that or bugs with `immutable`.
Re: Beta 2.098.0
On Monday, 4 October 2021 at 22:40:19 UTC, Temtaime wrote: What is really discourages me that persons like Walter instead of making D great just do nothing helpful. This is just uncalled for. I'm sure you can express what you mean without pointlessly and wrongly insulting the *reason we have this language,* a person who put more than twenty years of their life into this project.
Re: New library: rebindable, create a type that can stand in for any other type, but mutable (and without destructor)
On Wednesday, 29 September 2021 at 10:22:40 UTC, FeepingCreature wrote: Or: Turducken 2.0 The Reckoning https://code.dlang.org/packages/rebindable https://github.com/FeepingCreature/rebindable Rebindable offers a proxy type, `rebindable.DeepUnqual` (`DeepUnqual!T`) that can "stand in" for `T` in layout, but does not share `T`'s constructor, destructor, copy constructor, invariants or constness. I forgot to mention: It does this by recursively crawling the member types of `T`, replacing all primitives with non-const equivalents. Is this terrible? Yes, it's very terrible. I also don't see how to avoid it.
New library: rebindable, create a type that can stand in for any other type, but mutable (and without destructor)
Or: Turducken 2.0 The Reckoning https://code.dlang.org/packages/rebindable https://github.com/FeepingCreature/rebindable Rebindable offers a proxy type, `rebindable.DeepUnqual` (`DeepUnqual!T`) that can "stand in" for `T` in layout, but does not share `T`'s constructor, destructor, copy constructor, invariants or constness. It's effectively "`std.typecons.Rebindable` for structs (and everything else)". This proxy type is useful when implementing data structures where the lifetime of a contained value is different from the lifetime of the data structure itself. This project sprang from my thread over in general, https://forum.dlang.org/thread/kkefkykirldffkdoq...@forum.dlang.org "Will D always have a way to rebind an arbitrary data type?" To my knowledge, rebindable exploits no compiler bugs and invokes no undefined behavior. All casts are such that pointer fields are matched with pointer fields (or void[]) at the same offset. It is also totally independent of the vagaries of Phobos functions like `moveEmplace`, which Turducken used. Of course, you must still make sure that mutable fields in `DeepUnqual!T` are never exposed as immutable. You can do this by only returning `T` by value. See also: Turducken Type Technique https://forum.dlang.org/thread/ekbxqxhnttihkoszz...@forum.dlang.org
Re: alias this - am I using it wrong?
On Wednesday, 25 August 2021 at 12:11:01 UTC, Johann Lermer wrote: Hi all, I have a little problem understanding alias this. I always thought, that alias this only makes implicit conversions from the aliased object to this. Then, why do lines 18 and 22 compile in the code below? And, btw, line 22 crashes with a segmentation fault. ```d 01 struct Test_Struct {long t;} 02 03 class Alias_Class 04 { 05 Test_Struct ts; 06 alias ts this; 07 } 08 09 class Test_Class 10 { 11 Alias_Class ac; 12 } 13 14 void main () 15 { 16 auto ac = new Alias_Class; 17 Test_Struct ts = ac; // compiles 18 ac = ts; // compiles as well - why? 19 20 auto tc = new Test_Class; 21 ts = tc.ac; // compiles 22 tc.ac = ts; // again this compiles, but seg faults 23 } ``` Johann ts is a field. You can assign to a field. So when the field is aliased to this, you can assign to the field through a class reference. You can disable this behavior by creating a getter in Alias_Class, then aliasing it to this: ``` class Alias_Class { Test_Struct ts; Test_Struct getter() { return ts; } alias getter this; } ```
Re: LDC 1.27.1
On Saturday, 14 August 2021 at 21:19:25 UTC, kinke wrote: A new minor version was just released: * Based on D 2.097.2 (very few fixes over v1.27.0). * Improved `-ftime-trace` implementation for compiler profiling/tracing, now excluding LLVM-internal traces, adding frontend memory tracing, source file location infos etc. * An official prebuilt package for Linux AArch64 is available again. Full release log and downloads: https://github.com/ldc-developers/ldc/releases/tag/v1.27.1 Thanks to all contributors & sponsors! Thank you! 拾
Re: Beta 2.097.2
On Thursday, 12 August 2021 at 15:34:48 UTC, Dennis wrote: On Thursday, 12 August 2021 at 14:14:27 UTC, FeepingCreature wrote: I can just wait for 2.098.1 otherwise though, it's not a big deal. Since Nullable is a template type, maybe you can just apply the patch on your LDC installation's Phobos source? Actually, that's a good idea, thanks.
Re: Beta 2.097.2
On Thursday, 12 August 2021 at 13:57:28 UTC, kinke wrote: On Thursday, 12 August 2021 at 08:43:59 UTC, FeepingCreature wrote: On Wednesday, 11 August 2021 at 17:21:40 UTC, kinke wrote: I don't plan to release any LDC v1.27.1 for the very few minor fixes that made it into v2.097.2 compared to v1.27.0. :( Any chance I can convince you otherwise? The Nullable opAssign regression breaks literally *all* our code, and we use ldc for release builds. Who's 'we'? - It wouldn't be a big deal, but there were 3 betas and a beta period of almost 2 months to check for problems and regressions. And we're literally talking about a single compiler diagnostics improvement, that one Phobos fix you're after, and 5 minor druntime fixes. (Funkwerk.) You're right, but what happened was: I ran into another bug first, and after I filed that, I didn't think to recheck if there were more bugs waiting. I can just wait for 2.098.1 otherwise though, it's not a big deal.
Re: Beta 2.097.2
On Wednesday, 11 August 2021 at 17:21:40 UTC, kinke wrote: On Wednesday, 11 August 2021 at 13:06:24 UTC, FeepingCreature wrote: Seems to work here too :) Just waiting for ldc now. I don't plan to release any LDC v1.27.1 for the very few minor fixes that made it into v2.097.2 compared to v1.27.0. :( Any chance I can convince you otherwise? The Nullable opAssign regression breaks literally *all* our code, and we use ldc for release builds.
Re: Beta 2.097.2
On Saturday, 7 August 2021 at 00:31:34 UTC, kinke wrote: On Wednesday, 4 August 2021 at 17:34:32 UTC, Martin Nowak wrote: Glad to announce the first beta for the 2.097.2 point release, Thanks Martin, much appreciated. Test results at Symmetry are looking good. Seems to work here too :) Just waiting for ldc now.
Re: using "invariant" with structs ... possible to call when a field value is set??
On Sunday, 8 August 2021 at 11:30:41 UTC, james.p.leblanc wrote: Hello, With structs, I understand that "invariant checking" is called (from dlang tour): It's called after the constructor has run and before the destructor is called. It's called before entering a member function invariant() is called after exiting a member function. But, is is possible to have the invariant checking be performed whenever a field is directly set? For example, suppose a struct "S", has a field "x". I would like to have invariance check in cases such as: S.x = 4; Maybe there is a hidden set field function that gets called that might be exploitable?? Thoughts on this? Possible? Better paths that I should consider? Best Regards, James You can make a field set function like so: ``` struct S { private int x_; int x(int value) { return this.x_ = value; } int x() { return this.x_; } } ``` This will then run invariants. (boilerplate can automate that for you. https://code.dlang.org/packages/boilerplate cough self-advertisement cough)
gcsnoop: Monitor D GC runs systemwide on Linux.
Since the GC can sometimes cause delays that can make problems for latency-sensitive programs, it may be useful to notice when it has run. To that end, I've adapted Brendan Gregg's killsnoop ( https://github.com/brendangregg/perf-tools/blob/master/killsnoop ) to `gcsnoop`, a tool to supervise `tgkill` syscalls (used by the GC for `SIGUSR1`/`SIGUSR2`) and log time, PID and GC delay. https://gist.github.com/FeepingCreature/a2efe19f15eb582af274b23002c25706 Since it uses the kernel event tracing API, it needs to run as root. Time is seconds since boot. Sample output: ``` $ sudo ./gcsnoop -t Tracing GC runs. Ctrl-C to end. TIMEsCOMM PIDTGID LENGTH 355487.807757gctest-360995360996 360995 1.364406 355489.930831gctest-360995360996 360995 1.291132 355492.119666gctest-360995360996 360995 1.403598 355494.446310gctest-360995360996 360995 1.543637 ^C Ending tracing... ```
IT'S OVER ZION! THE WAR IS OVER!
On Saturday, 5 June 2021 at 10:19:47 UTC, Martin Nowak wrote: Glad to announce D 2.097.0, ♥ to the 54 contributors. This release comes with a new `std.sumtype` packcage, support for `while (auto n = expression)`, an overhauled formatting package, and many more changes. http://dlang.org/download.html http://dlang.org/changelog/2.097.0.html -Martin ``` Nullable!int ni = 5.nullable; int i = ni; ``` ``` test.d(5): Error: cannot implicitly convert expression `ni` of type `Nullable!int` to `int` ``` F***ing finally.
Re: General rule when not to write ;
On Tuesday, 18 May 2021 at 16:27:13 UTC, Alain De Vos wrote: After each } i write a ; And let the compiler tell me it is an empty instruction. What are the general rules where ; is not needed after a } Is `;` ever needed after a `}`? I guess in `void delegate() dg = { writeln!"Hello World"; };`, but that hardly counts, because it belongs to the variable declaration, not the `{}`.
Re: Silicon Valley D Meetup - April 15, 2021 - "Compile Time Function Execution (CTFE)"
On Monday, 26 April 2021 at 14:01:37 UTC, sighoya wrote: On Monday, 26 April 2021 at 13:17:49 UTC, FeepingCreature wrote: On Sunday, 25 April 2021 at 21:27:55 UTC, sighoya wrote: On Monday, 19 April 2021 at 06:37:03 UTC, FeepingCreature wrote: Native CTFE and macros are a beautiful thing though. What did you mean with native? When cx needs to execute a function at compiletime, it links it into a shared object and loads it back with dlsym/dlopen. So while you get a slower startup speed (until the cache is filled), any further calls to a ctfe function run at native performance. Ah okay, but can't Dlang runtime functions not anyway called at compile time with native performance too? So generally, cx first parses the program, then filters out what is a macro, then compiles all macro/ctfe functions into shared lib and execute these macros from that lib? Sorta: when we hit a macro declaration, "the module at this point" (plus transitive imports) is compiled as a complete unit. This is necessary cause parser macros can change the interpretation of later code. Then the generated macro object is added to the module state going forward, and that way it can be imported by other modules. Isn't it better to use the cx compiler as a service at compile time and compile code in-memory in the executable segment (some kind of jiting I think) in order to execute it then. I think the cling repl does it like that. That would also work, I just went the path of least resistance. I already had an llvm backend, so I just reused it. Adding a JIT backend would be fairly easy, except for the part of writing and debugging a JIT. :P And how does cx pass type objects? By reference. :) Since the compiler is in the search path, you can just import cx.base and get access to the same Type class that the compiler uses internally. In that sense, macros have complete parity with the compiler itself. There's no attempt to provide any sort of special interface for the macro that wouldn't also be used by compiler internal functions. (There's some class gymnastics to prevent module loops, ie. cx.base defines an interface for the compiler as a whole, that is implemented in main, but that is indeed also used by the compiler's internal modules themselves.) The downside of all this is that you need to parse and process the entire compiler to handle a macro import. But DMD gives me hope that this too can be made fast. (RN compiling anything that pulls in a macro takes about a second even with warm object cache.)
Re: Silicon Valley D Meetup - April 15, 2021 - "Compile Time Function Execution (CTFE)"
On Sunday, 25 April 2021 at 21:27:55 UTC, sighoya wrote: On Monday, 19 April 2021 at 06:37:03 UTC, FeepingCreature wrote: Native CTFE and macros are a beautiful thing though. What did you mean with native? When cx needs to execute a function at compiletime, it links it into a shared object and loads it back with dlsym/dlopen. So while you get a slower startup speed (until the cache is filled), any further calls to a ctfe function run at native performance. Plus, it means the macro is ABI compatible with the running compiler, so the compiler can pass objects back and forth without a glue layer.
Re: Silicon Valley D Meetup - April 15, 2021 - "Compile Time Function Execution (CTFE)"
On Monday, 19 April 2021 at 08:46:05 UTC, Ola Fosheim Grøstad wrote: I think the downsides are conceptual and technical, not social. If you can implement a version counter then you get all kinds of problems, like first compilation succeeding, then the second compilation failing with no code changes. Also, you can no longer cache intermediate representations between compilations without a rather significant additional machinery. It is better to do this in a more functional way, so you can generate a file, but it isn't written to disk, it is an abstract entity during compilation and is turned into something concrete after compilation. So, anything that can be deduced from the input is fair game, but allowing arbitrary I/O is a completely different beast, compilation has to be idempotent. It should not be possible to write a program where the first compilation succeeds and the second compilation fails with no code changes between the compilation executions. Such failures should be limited to the build system so that you can quickly correct the problem. IMHO, a good productive language makes debugging easier, faster and less frequently needed. Anything that goes against that is a move in the wrong direction. Right, I agree with all of this. I just think the way to get to it is to first allow everything, and then in a second step pare it down to something that does what people need while also being monitorable. This is as "simple" as merging every IO call the program does into its state count. (For my lang, I just go and hash every part of the program during compilation. So caching works on the basis of what actually goes into the binary.) But my view is, you have those issues anyways! You need to run a caching dub server, and you need to run it on a Docker image, and you need to pretty much mirror every upstream package that your Docker install pulls in, *anyways.* You can't escape the vagaries of the build environment changing under you by limiting the language. And everything you keep out of the language - IO, downloads, arbitrary commands whose output is relevant - the rest of your build environment usually does regardless. (And it will mess you up at the first, slightest provocation. Bloody Ubuntu and its breaking changes in patch releases...) So my view is the other way around - make the language the single point of contact for *all of that stuff*, make CTFE powerful enough to hash static libraries and process header files live during compilation, so you can pull as much of the complexity as possible into the controlled environment of the compiler. And then when you know what you need there, take a step back and frameworkize it, so you can do change detection inside your single build system. You can't get the entire OS on board, but you can maybe get all or most of your language library developers on board. Anyways, even agreeing that you're right, "look, we tried it and it didn't work, in fact it was a disaster, see discussions here and here, or download version 2019-03-06 nightly to try how it went" is just inherently a stronger argument. to find out what works and what doesn't, and you can't gather experience with what people actually want to do and how it works in practice if you lock things down from the start. In That's ok for a prototype, but not for a production language. I think most long-term successful languages straddle a line here. For instance, looking at Rust, the use of nightly and stable channels allows the language to experiment while also keeping a guarantee that once it commits to a feature enough to merge it into stable, it won't change "overnight". D is trying to do a similar thing with DIPs and preview flags and deprecations, but the jury's still out on how well it's working - or if not, if D can make it work. At any rate, with a lot of features like implicit conversions, I think people would find that they're harmless and highly useful if they'd just try them for a while.
Re: Silicon Valley D Meetup - April 15, 2021 - "Compile Time Function Execution (CTFE)"
On Sunday, 18 April 2021 at 04:41:44 UTC, Ola Fosheim Grostad wrote: On Sunday, 18 April 2021 at 00:38:13 UTC, Ali Çehreli wrote: I heard about safety issues around allowing full I/O during compilation but then the following points kind of convinced me: - If I am compiling a program, my goal is to execute that program anyway. What difference does it make whether the program's compilation is harmful vs. the program itself. I dont buy this, you can execute the code in a sandbox. Compilation should be idempotent, writing to disk/databases during compilation breaks this guarantee. I would not use a language that does not ensure this. This is a social issue more than a technical one. The framework can help, by limiting access to disk and URLs and allowing tracing and hijacking, but ultimately you have to rely on code to not do crazy things. And right now in D we just push this complexity out of the language and into the build system, because if you don't let people do crazy things, they just do crazy and also horribly hacky things instead. (*Cough* gen_ut_main *cough*.) In my opinion, the design approach should be to "default open, then restrict", rather than "default closed, then relax." This requires a certain willingness to break people's workflow, but if you default closed, you'll never get over your preconceptions, because you have to be able to do crazy things to find out what works and what doesn't, and you can't gather experience with what people actually want to do and how it works in practice if you lock things down from the start. In other words, I see no reason why "make one to throw it away" shouldn't apply to languages. Maybe we will decide one day to limit recursion for templates and CTFE, for instance, but if we do, it will be because of the experiences we gathered with unrestricted templates and the impact on compile times - if D had decided from day one to keep templates limited, we'd never have the wealth of experience and frameworks and selling points that D has with metaprogramming. You have to let people show you what they want to do and what comes of it, and you can't do that if you don't extend them enough rope to tangle themselves and their projects up first. There has to be a willingness to try and fail and backtrack. Most of my annoyances with D are issues where D isn't willing to take an additional step even though it would be technically very feasible. No implicit conversion for user-defined types, no arbitrary IO calls in CTFE, no returning AST trees from CTFE functions that are automatically inserted to create macros, and of course the cumbersome specialcased metaprogramming for type inspection instead of just letting us pass a type object to a ctfe function and calling methods on it. If some new language will overtake D (cx¹, fingers crossed!), it will be because of this design conservatism as much as any technological restriction in the frontend. ¹ I have a language, by the way! :) https://github.com/FeepingCreature/cx , but it's pre-pre-alpha. Native CTFE and macros are a beautiful thing though.
Re: What are virtual functions?
On Sunday, 18 April 2021 at 23:04:26 UTC, ShadoLight wrote: On Wednesday, 14 April 2021 at 14:06:18 UTC, FeepingCreature wrote: On Wednesday, 14 April 2021 at 13:43:20 UTC, Berni44 wrote: [..] Covariance is related ... [..] The opposite (contravariance) happens ... [..] Nice answer but, just to be clear - D only supports covariance on return types at the moment, and doesn't support contravariance on parameters, right? I remember contravariance being periodically requested in the past but, AFAICR, it has not been implemented, right? A quick search through the forums didn't turn anything up either... and this does not compile: ``` class A {} class B : A {} class Y { public void bar (B b) {} } class X : Y { public override void bar (A a){} } ``` ... That doesn't work?! Holy hell. I mean, run.dlang.io confirms, but ... *why not*?! If you already support return type covariance, parameter contravariance should be easy. It's the same thing! You don't need to do anything! Any B is directly a valid A! Like, sure, there's versions of this that don't trivially work, like mixing interface and class parents, but direct superclass contravariance should be easy. ... Weird. I don't get it. Reading https://issues.dlang.org/show_bug.cgi?id=3075 seems like it collides with overloading. Except ... it doesn't. Because you can't implement multiple overloaded methods with contravariance in a subclass, because it doesn't work for interfaces anyway (cause they occupy a different interface slot in the class and so aren't strictly Liskov.) So the selection of the function to override is still unambiguous. I don't get it.
Re: What are virtual functions?
On Wednesday, 14 April 2021 at 13:43:20 UTC, Berni44 wrote: I'm trying to understand, what virtual functions are. I found the [specs](https://dlang.org/spec/function.html#virtual-functions), but I can't make head or tail of it. - What is a `vtbl[]`? Obviously a function pointer table. But where to find this? The examples don't use it. Maybe something inside of the compiler? - Which of the eight functions in the example are virtual and and which not? OK B.abc is said to be virtual, as the comment states. But it seems never to be used. And why is it considered to be virtual? - There is also the term "covariant function", which is not explained. What is this? Recommended reading: https://en.wikipedia.org/wiki/Liskov_substitution_principle This is all related to object-oriented programming and class inheritance. Because we can put a subclass object into a superclass variable (`class Child : Parent { }; Parent parent = new Child;`), we cannot look at the *type* of an object variable to decide which methods to call, because the object itself may be of a subtype. As such, when we call a method `foo` on `Parent`, the compiler looks up the class info in a pointer in the first 8 bytes of the object, finds the method pointer for `foo`, and calls it with the object as a hidden parameter. (This is the `this` field.) So a virtual method is a method that is called "virtually", as compared to directly by name, by turning the method name into a function pointer call via the classinfo. The list of function pointers for methods in the class info is called the virtual method table, or vtable. Covariance is related to the Liskov principle, and just means that because `Child` can be treated as a `Parent`, a method that returns `Parent` in the superclass can be overridden (its vtable pointer replaced with a new one) by one that returns a `Child` in the subclass. In other words, as "Child class replaces Parent class", the "return type `Child`" can replace the "return type `Parent`"; ie. in the child class you can use a child class of the return type, ie. they "vary together" - covariance. The opposite (contravariance) happens for parameters: if a superclass method takes `Child`, the subclass can take `Parent` instead - again, because `Child` can turn into `Parent` per Liskov. A different way to think about this is that method parameter and return types form a contract that is defined by the superclass and fulfilled by the subclass, and the subclass can relax the call contract ("I demand from my caller") and restrict the return contract ("I promise my caller"). Since the `Child`, by Liskov, can do everything the `Parent` can do, demanding less - ie. a `Parent` instead of a `Child` - keeps the superclass's call contract valid, and promising more - ie. returning a `Child` instead of a `Parent`, which may have additional capabilities - keeps the superclass's return contract valid.
Re: alias Nullable.get this, your time is ending
On Monday, 1 March 2021 at 14:12:21 UTC, Steven Schveighoffer wrote: On 3/1/21 2:02 AM, FeepingCreature wrote: On Sunday, 28 February 2021 at 11:56:28 UTC, Martin Nowak wrote: Glad to announce the first beta for the 2.096.0 release, ♥ to the 53 contributors. http://dlang.org/download.html#dmd_beta http://dlang.org/changelog/2.096.0.html As usual please report any bugs at https://issues.dlang.org :looks longingly at "Remove alias Nullable.get this" PR: Soon... Can be done now against master. -Steve IT IS DONE.
alias Nullable.get this, your time is ending
On Sunday, 28 February 2021 at 11:56:28 UTC, Martin Nowak wrote: Glad to announce the first beta for the 2.096.0 release, ♥ to the 53 contributors. http://dlang.org/download.html#dmd_beta http://dlang.org/changelog/2.096.0.html As usual please report any bugs at https://issues.dlang.org -Martin :looks longingly at "Remove alias Nullable.get this" PR: Soon...
Re: byte array to string
On Thursday, 25 February 2021 at 06:47:11 UTC, Mike wrote: hi all, If i have an array: byte[3] = [1,2,3]; How to get string "123" from it? Thanks in advance. string str = format!"%(%s)"(array);
Re: byte array to string
On Thursday, 25 February 2021 at 06:57:57 UTC, FeepingCreature wrote: On Thursday, 25 February 2021 at 06:47:11 UTC, Mike wrote: hi all, If i have an array: byte[3] = [1,2,3]; How to get string "123" from it? Thanks in advance. string str = format!"%(%s)"(array); Er sorry, typo, that should be "%(%s%)". "Print the elements of the array, separated by nothing." Compare "%(%s, %)" for a comma separated list.
Re: Foo Foo = new Foo();
On Sunday, 21 February 2021 at 18:07:49 UTC, JN wrote: class Foo { } void main() { Foo Foo = new Foo(); } this kind of code compiles. Is this expected to compile? Yes, why wouldn't it? main is a different scope than global; you can override identifiers from global in main. And "Foo" only exists after the declaration, so it doesn't conflict.
Re: 200-600x slower Dlang performance with nested foreach loop
On Wednesday, 27 January 2021 at 02:14:39 UTC, H. S. Teoh wrote: Yes, definitely try this. This will completely eliminate the overhead of using an AA, which has to allocate memory (at least) once per entry added. Especially since the data has to be sorted eventually anyway, you might as well sort first then use the sortedness as a convenient property for fast de-duplication. Since .uniq traverses the range linearly, this will be cache-friendly, and along with eliminating GC load should give you a speed boost. T Associative arrays allocate per entry added?! https://github.com/dlang/druntime/blob/master/src/rt/aaA.d#L205 Oh God, associative arrays allocate per entry added!
Re: F*cked by memory corruption after assiging value to associative array
On Monday, 25 January 2021 at 11:15:28 UTC, frame wrote: After a while my program crashes. I'm inspecting in the debugger that some strings are overwritten after a struct is assigned to an associative array. - I have disabled the GC. - All happens in the same thread. - The strings belong to an object collection inside an object created from a d-DLL. - The object returned by the DLL function is added to the GC with GC.addRoot(). - This object also lives in a static array the whole time. - Not all objects are affected but many. - The struct itself looks okay also the key for the associative array has normal form. The data is not overwritten by another Thread (only one is running) but by the compiler. I'm watching it by memory location. It gets always visible first after that assignment. But how is this even possible? In theory, how could I ran into this issue? That should really not be possible. I suspect the memory used by the original data got reused for the associative array somehow. But if the GC is off from program start, that should really not occur. Do you maybe turn the GC off before the AA assignment, but after it's already marked that memory freed? Try turning it off completely from the commandline with --DRT-gcopt=gc:manual
Re: Handling referencing class parent instances in a GC friendly way.
On Monday, 30 November 2020 at 14:33:22 UTC, realhet wrote: Hi, class A{ A parent; A[] items; void myDestroy(){ items.each!(i => i.myDestroy); parent = null; // after this point I think the GC will release it automatically, and it will call ~this() too. Am I right? } } I have a hierarchy of class instances forward and backward linked to its items ant its parent. What is a proper way to destroy an instance of class A? Is calling instance.myDestroy sufficient? Am I right that this kind of uninitialization MUST not go into the ~this() destructor, because of the references the instance is holding, the system will never call the ~this()? Or is there a better way for this type of thing in Dlang? Thanks in advance! The GC will release it anyways. The advantage of a GC is that it is not deterred by cyclic references, so as soon as no more references into A exist, it will disappear, no matter the parent pointer. At least, that's the theory - in practice, since we don't have precise stack GC, any spurious or leftover pointer to an A can keep the whole tree alive, so the myDestroy cleanup method is still valid and recommended. Though you may want to do `items = null;` too.
Re: DConf Online 2020 was a big success!
yaaay
Re: DConf Online 2020...
On Tuesday, 8 September 2020 at 09:17:10 UTC, Mike Parker wrote: I was on the verge to cutting the schedule down to one day, but thanks to some last-minute submissions, looks like we'll have enough content now to stretch across two days! Thanks to everyone who submitted a proposal. I'll be in touch with each of you soon to discuss how to proceed. For everyone else, keep an eye on the DConf Online 2020 homepage for the schedule and other announcements. We're supposed to submit a five-minute sample no later than the 4th of October. And I just realized that technically, given the West Coast timezone is nine hours behind Germany, I can actually record mine at 6am at work tomorrow and still be comfortably on time. Which means I don't need to do it on a Sunday!~ Should I stop routinely pushing things out until the very last conceivable moment? *Maybe...* But clearly not today. :)
Re: Beta 2.094.0
On Sunday, 13 September 2020 at 19:16:24 UTC, Steven Schveighoffer wrote: Yeah, I don't know the intention originally. But I have definitely done exactly what the thread author stated (used __traits(getMember) on all the module to look for certain symbols). So my code would be broken too. Essentially, when you don't care about imports, they get ignored even if they were there by error. But when __traits(getMember) actually fails, now it becomes a problem. Honestly, I've never used __traits(allMembers, module) to look for imports. Most likely many people don't, since it doesn't work how you would ever expect. I'd rather we just got rid of that part of the output than break code that doesn't care about imports, but does care about the other things in the module. I don't want to have to write extra mixins to rule this stuff out. -Steve I've tried to do this before and failed due to this bug. If it's removed, we'd need a whole separate __traits infrastructure in order to walk imports in a project. Not fun. I don't think we should let backwards compatibility fix us from fixing cases where the existing behavior is genuinely broken. And __traits(allMembers, module) was *really* really broken. Much better to have allMembers return fields that work with getMembers, since that's very clearly how they're meant to pair up, and either ignore modules as "don't have the properties we're scanning for" or discard them via is() on the resulting symbol.
Re: DConf Online 2020...
On Tuesday, 8 September 2020 at 09:17:10 UTC, Mike Parker wrote: I was on the verge to cutting the schedule down to one day, but thanks to some last-minute submissions, looks like we'll have enough content now to stretch across two days! Yay! How close was it? Half the submissions in the last six hours?
Re: DConf Online 2020 Submission Deadline Extended
On Saturday, 5 September 2020 at 04:01:43 UTC, Mike Parker wrote: On Monday, 31 August 2020 at 08:36:09 UTC, Mike Parker wrote: I've received exactly one submission for DConf Online. Two keynotes + one talk does not make a conference. So this is the last call. The deadline has been extended to Sunday, September 6 AOE. This makes or breaks the conference. If we don't have enough talks submitted, it ain't happening. I've gotten one more submission. We'll need more than that. Let's go, folks! hi okay, if I'm literally the only one that's kind of problematic, yeah. Let's see how it goes on Sunday. I'd guess that ... like, either ultimately a structured online conference just isn't something people are interested in or think is useful, or the effort of recording videos poses too much of a roadblock. You wouldn't think that flying to London would be more effort than making a video, but it wouldn't surprise me. Or right now maybe people are keeping their ideas for the next in-person DConf, so if Corona keeps up we'd see more talks next year. You know what, let's ask. Anyone here who considered submitting but didn't, would you share why not?
Re: `enum x;` - what is it?
On Wednesday, 19 August 2020 at 14:43:22 UTC, Victor Porton wrote: On Wednesday, 19 August 2020 at 14:06:16 UTC, Victor Porton wrote: This declaration does compile: enum x; But what is it? Is it an equivalent of enum x { } ? What in the specification allows this looking a nonsense enum x; ? Oh, found: "An empty enum body (For example enum E;) signifies an opaque enum - the enum members are unknown." But what this "unknown" does mean? How "unknown" differs from "none" in this context? The specification is unclear. It does not define the meaning of unknown. I will submit a bug report. It means exactly what it says. The compiler doesn't know what members are in the enum. So you can't declare a variable of it, you can't use it directly.. you can p much only use it in pointers.
Re: `enum x;` - what is it?
On Wednesday, 19 August 2020 at 14:06:16 UTC, Victor Porton wrote: This declaration does compile: enum x; But what is it? Is it an equivalent of enum x { } ? What in the specification allows this looking a nonsense enum x; ? It's an enum type whose members we don't know. So we can't declare "x var;" but we can declare "x* var;". It's the enum version of "struct SomeExternCStruct;".
Re: D on lm32-CPU: string argument on stack instead of register
On Tuesday, 4 August 2020 at 17:36:53 UTC, Michael Reese wrote: Thanks for suggesting! I tried, and the union works as well, i.e. the function args are registered. But I noticed another thing about all workarounds so far: Even if calls are inlined and arguments end up on the stack, the linker puts code of the wrapper function in my final binary event if it is never explicitly called. So until I find a way to strip of uncalled functions from the binary (not sure the linker can do it), the workarounds don't solve the size problem. But they still make the code run faster. Try -ffunction-sections -Wl,--gc-sections. That should remove all unreferenced functions. It removes all unreferenced sections, and writes every function into a separate section.
Re: From the D Blog: A Pattern for Head-mutable Structures
On Thursday, 25 June 2020 at 11:55:14 UTC, Mike Parker wrote: Simen Kjærås outlines an approach to supporting head-mutable types in D without the need for compiler or language changes. The blog: https://dlang.org/blog/2020/06/25/a-pattern-for-head-mutable-structures/ Reddit: https://www.reddit.com/r/programming/comments/hfkq5e/a_pattern_for_headmutable_structures_in_d/ I've also submitted it to HN (please use the search box): https://news.ycombinator.com/newest What about immutable structs? There is no possible head-mutable type for them. Deprecate?
Re: How to compile to .bin/.iso format
On Wednesday, 17 June 2020 at 12:39:11 UTC, FeepingCreature wrote: On Wednesday, 17 June 2020 at 12:30:24 UTC, Quantium wrote: Hi all! I have a programm in D (The simplest OS), which should be compiled into .bin or .iso format to be possible to run it on VirtualBox. How can I compile it to .bin / .iso format and which compiler should I use? Try this page? https://wiki.osdev.org/D_Bare_Bones combined with https://dlang.org/phobos/core_volatile.html to replace volatile. Update: Tried and it works with ldc 1.20.1 (2.090.1) at least. The LDC version of the command is `ldc2 -betterC -m32 -c kernel.main.d -ofkernel.main.o -g`.
Re: How to compile to .bin/.iso format
On Wednesday, 17 June 2020 at 12:30:24 UTC, Quantium wrote: Hi all! I have a programm in D (The simplest OS), which should be compiled into .bin or .iso format to be possible to run it on VirtualBox. How can I compile it to .bin / .iso format and which compiler should I use? Try this page? https://wiki.osdev.org/D_Bare_Bones combined with https://dlang.org/phobos/core_volatile.html to replace volatile.
Re: What's the best way to find out which exceptions may be thrown ?
On Tuesday, 2 June 2020 at 13:58:13 UTC, Bienlein wrote: Because of the problems with checked exceptions they were deliberately left out in C#. Here is an interview with Anders Hejlsberg, the creator of C# at MS, where he explains the reasons for this decision: https://www.artima.com/intv/handcuffs.html This wouldn't seem to apply if checked exceptions were inferred by default, right? And the issues with Java generics don't apply to D, because our metaprogramming infers attributes anyways.
Re: DIP 1027---String Interpolation---Format Assessment
On Thursday, 27 February 2020 at 03:50:35 UTC, Walter Bright wrote: On 2/26/2020 4:46 PM, Adam D. Ruppe wrote: But DIP1027 had a fatal flaw: it made type safety impossible. I don't see how that is true. Because it turned a format string into a list of built-in types indistinguishable from a set of manual parameters. You cannot in principle tell the difference between "test $i" and ("test %s", i) - you cannot write a function that takes a string and then *any other type* and is also protected from being accidentally called with a format string. Features should be as simple as they can be, but no simpler. - The point of simplicity is predictability. DIP1027 is so simple that it crosses back into surprising.
Re: DIP 1027---String Interpolation---Format Assessment
On Wednesday, 26 February 2020 at 11:13:12 UTC, Petar Kirov [ZombineDev] wrote: On Wednesday, 26 February 2020 at 09:45:55 UTC, Walter Bright wrote: It is lowered to: f("hello %s", a); as designed. I don't know what's unwanted about it. In all other languages with string interpolation that I'm familiar with, `a` is not passed to the `i` parameter. --- [snip] To be fair, none of those languages care about an extra string allocation. But to be fair again, Adam/Steven's proposal can avoid the memory allocation while also not passing i implicitly, at the cost of not matching to the string type. But to be thrice fair, Adam/Steven's proposal would work with the minor extension `f(i"hello $a".format)`/`f(i"hello $a".to!string)`, in keeping with the trend of GC use requiring explicit opt-in.
Re: DIP 1027---String Interpolation---Format Assessment
On Monday, 24 February 2020 at 22:11:08 UTC, Walter Bright wrote: The semantics of an interpolated string must be defined by the DIP, not deferred to some template. If the implementation of those defined language features is done by a template, that is an implementation choice, not part of the DIP or spec. I don't understand this. The behavior of formatting strings is *currently* deferred to a template (std.format and co). This lets us do important decisions at compiletime, like writing the format string to a file or a string buffer piecewise without allocating memory. Why are you trying to get rid of this flexibility? As I understand it, the point of a format string template is to keep exactly this kind of flexibility in exactly the same places it is currently available to users, while simultaneously improving syntax legibility. To emphasize this again: the @gc format string would have *reduced* flexibility for 90% of our usecases (templated nogc/lowgc log library calls). As proposed, I don't see why I would have ever used it.
Re: From [Tuple!(A,B), ...] to Tuple!(A[], B[])
On Monday, 17 February 2020 at 11:07:33 UTC, foozzer wrote: Hi all, There's something in Phobos for that? Thank you Here you go: import std; // extract the types that make up the tuple auto transposeTuple(T : Tuple!Types[], Types...)(T tuples) { // templated function that extracts the ith field of an array of tuples as an array auto extractArray(int i)() { return tuples.map!(a => a[i]).array; } // return tuple of calls to extractArray, one for each tuple index return tuple(staticMap!(extractArray, aliasSeqOf!(Types.length.iota))); } void main() { Tuple!(int, double)[] array; array ~= tuple(1, 2.0); array ~= tuple(3, 4.0); Tuple!(int[], double[]) tuple = array.transposeTuple; assert(tuple[0] == [1, 3]); assert(tuple[1] == [2.0, 4.0]); }
Re: dub dustmite struggles
On Monday, 20 January 2020 at 06:48:08 UTC, DanielG wrote: I can't seem to figure out what dub's dustmite command is looking for with its regexes. No matter what I try - no matter how simple - the initial test fails. I am able to run dustmite standalone just fine with the following test script: cd example dub 2>&1 | grep -F "ScrollView6__initZ+0xd8): undefined reference to \`internal'" However, when I attempt using 'dub dustmite' with --linker-regex (or --linker-status, even), the initial test always fails. I've also tried simplifying the regex on the assumption that I'm not escaping things properly - to no avail. Is it perhaps something to do with my project structure? My project is a library containing an /example subfolder, containing an application dub project, and that's where my linker error occurs, not in the library itself. So that's where I'm attempting to run dub dustmite as well. I don't know how `dub dustmite` works, but my advice would be to use standalone dustmite and write a shellscript that handles your success/fail condition with an exit code. That's always worked for me, and it makes it easier to externally check what's happening. Ie. test.sh: --- #!/bin/sh dub 2>&1 |grep -F "ScrollView6__initZ+0xd8): undefined reference to \`internal'" --- dustmite example ../test.sh Then if you have to recurse into a dub project, just copy it into your example folder so it's compiled in, and repeat.
Re: dud: A dub replacement
On Monday, 11 November 2019 at 13:44:28 UTC, Robert Schadek wrote: Now that dud can parse dub files, the next step will be a semantic phase, checking the input for errors. After that, path expansion and dependency resolution. PR's are always welcome. Destroy! [1] https://github.com/symmetryinvestments/dud [2] https://github.com/symmetryinvestments/dubproxy Are you looking to replace dub as the reference build tool for D? (Please say yes...) Any estimate what the schedule looks like until dud can be used in practice?
Re: Beta 2.089.0
On Tuesday, 29 October 2019 at 06:06:56 UTC, FeepingCreature wrote: On Sunday, 27 October 2019 at 16:50:00 UTC, baz wrote: What does the author of the deprecation think about this case ("feep" IIRC ) ? Yeah that's a non-fix. It's a blind replacement of "a" with "a.get" that ignores the fact that Nullable!string has its own toString, ie. this is one of the cases where the `a.get` is actually not triggered at runtime. The fact that the deprecation still triggers is an issue with traits that has no clear and obvious solution. (I advocate Adam's approach of just disabling deprecations in traits outright.) I take it back. Actually on looking into it deeper, while the general issue is gnarly, the solution to the *specific issue* in the bug report is very simple, lol. PR up: https://github.com/dlang/phobos/pull/7257
Re: Beta 2.089.0
On Sunday, 27 October 2019 at 16:50:00 UTC, baz wrote: On Sunday, 27 October 2019 at 16:38:30 UTC, baz wrote: On Sunday, 27 October 2019 at 15:04:34 UTC, drug wrote: 27.10.2019 17:20, baz пишет: On Sunday, 27 October 2019 at 12:59:52 UTC, baz wrote: On Thursday, 17 October 2019 at 06:02:33 UTC, Martin Nowak wrote: As usual please report any bugs at https://issues.dlang.org -Martin Hi, I've tested my old stuff and found 2 regs. One deprecation in phobos due to Nullable.get and that was not detected and some weird linking errors, maybe due to typeinfo. https://issues.dlang.org/show_bug.cgi?id=20327 https://issues.dlang.org/show_bug.cgi?id=20328 Only 20328 is valid actually. I confirm the bugs related to Nullable.get (I have another one). I have no the reduced case but there are definitly issues with deprecated Nullable.get According to a little investigation the message would be caused by this unittest [1]. I would suggest to disable it (using version(none)) or to extract it from the struct to the global scope. It's not recommended to add unittest blocks in templatized types anyway, because when the test is not dependent on the template params, like here, it's always the same that gets executed for each instance. [1]: https://github.com/dlang/phobos/blob/master/std/typecons.d#L2889-L2897 BTW you're not allowed to do that // Issue 19799 @safe unittest { import std.format : format; const Nullable!string a = const(Nullable!string)(); format!"%s"(a.get); // added .get here } because the Nullable is in a null state, .get call crash the program in assert mode. Maybe you should revert the whole stuff ? What does the author of the deprecation think about this case ("feep" IIRC ) ? Yeah that's a non-fix. It's a blind replacement of "a" with "a.get" that ignores the fact that Nullable!string has its own toString, ie. this is one of the cases where the `a.get` is actually not triggered at runtime. The fact that the deprecation still triggers is an issue with traits that has no clear and obvious solution. (I advocate Adam's approach of just disabling deprecations in traits outright.)
Re: Oberon to D
On Tuesday, 15 October 2019 at 18:02:28 UTC, Mario Kröplin wrote: https://github.com/linkrope/oberon2d is a simple tool that translates source code from Oberon to D. It was intended to be thrown away after the resurrection of a single Oberon project. (So, don't expect too much.) But then, Bastiaan Veelo presented a very similar problem at DConf 2017. I'm a bit late, but I hope this could help. The example shows, by the way, that Oberon uses floored division while D uses the more common truncated division. What is truncated remainder ever useful for, anyways? All I know it as is "that broken remainder I have to work around when writing graphics code."