Re: Bug or feature? iota has different semantics for integer and float arguments
On 1/6/23 17:50, Arredondo wrote: > Would anyone volunteer to file a bug report? Me! Me! :) https://issues.dlang.org/show_bug.cgi?id=23604 Ali
Re: Bug or feature? iota has different semantics for integer and float arguments
On Saturday, 7 January 2023 at 00:52:20 UTC, Ali Çehreli wrote: Although that difference is a bug, iota does have a special floating point implementation to prevent the accumulation of floating point errors. Thank you for this clarification Ali. I appreciate the fact that there is a specialized implementation for float types in an attempt to mitigate error accumulation. After posting my previous message I became convinced that the behavior I was seeing was indeed a bug. The specialized fp implementation simply does not conform to the semantics specified in the documentation: "If begin < end && step < 0 or begin > end && step > 0 or begin == end, then an empty range is returned." The culprit is this assert in the `in` block of the fp implementation: ``` assert((end - begin) / step >= 0, "iota: incorrect startup parameters"); ``` This effectively prevents iota from ever returning an empty range. Git blame points to a commit from March 2015. It's unbelievable to me this hasn't been fixed in almost 8 years. Would anyone volunteer to file a bug report? I attempted to do it myself but I would need to create an account in the Issue Tracking System, and apparently it doesn't accept gmail addresses anymore? (facepalm). Arredondo.
Re: Bug or feature? iota has different semantics for integer and float arguments
On 1/6/23 15:23, Arredondo wrote: > then you get an exception (incorrect startup parameters). Although that difference is a bug, iota does have a special floating point implementation to prevent the accumulation of floating point errors. I mention it as item 4 here: https://www.youtube.com/watch?v=gwUcngTmKhg&t=634s Briefly, iota's regular popFront() is a trivial front += step but it is ++n for floating types so that front can be begin + (n * step) for them. The iota discussion starts at an earlier point in the video here: https://www.youtube.com/watch?v=gwUcngTmKhg&t=558s Ali
Re: how to use dmd.lexer.Lexer
Dmd is a separate code base and is not available in a regular D build. You have to provide it and then link it in. The easiest way to do it is by using dmd-fe via dub. Examples: https://github.com/dlang/dmd/tree/master/compiler/test/dub_package So something like this: ```json { "name": "lexer_test", "dependencies": { "dmd:frontend": "~>2.101.0" } } ``` source/lexer_test.d: ```d module lexer_test.d; void main() { import dmd.globals; import dmd.lexer; import dmd.tokens; immutable expected = [ TOK.void_, TOK.identifier, TOK.leftParenthesis, TOK.rightParenthesis, TOK.leftCurly, TOK.rightCurly ]; immutable sourceCode = "void test() {} // foobar"; scope lexer = new Lexer("test", sourceCode.ptr, 0, sourceCode.length, 0, 0); lexer.nextToken; TOK[] result; do { result ~= lexer.token.value; } while (lexer.nextToken != TOK.endOfFile); assert(result == expected); } ``` And then just ``$ dub run``.
Bug or feature? iota has different semantics for integer and float arguments
Consider: ``` import std.range.iota; auto r = iota(5, 0); ``` `r` is an empty range, as it should be. But if you call: ``` auto r = iota(5.0, 0); ``` then you get an exception (incorrect startup parameters). This was unexpected, and a pain to debug. What is the rationale behind iota having different semantics depending on whether the arguments are floats or not? Arredondo.
Re: Is there a way to enforce UFCS?
On Friday, 6 January 2023 at 15:31:09 UTC, Salih Dincer wrote: If you don't want to get the above output you should use the previous example. But don't forget to connect alias and opCall. For example, you can use @property in version 2.0.83 without all the fanfare. I forgot one thing: if you implement getter/setter like below use inout as well. Actually, this must be a bit of a bug and neither I nor anyone else reported it! Ok they will say don't use @property. But this time the screen output will be like typeid. If you don't want that to happen, you have to use inout in getter functions. ```d struct Funy(T) { this(T x) { value = x; } T value; alias opCall this; @property: T opCall(T n) { return value = n; } T opCall() inout { return value; } } ``` SDB@79
Re: Is there a way to enforce UFCS?
On Thursday, 5 January 2023 at 23:05:17 UTC, thebluepandabear wrote: them or remove them. I agree, forbidding function call syntax would be a great usecase for `@property`. It will probably never get implemented though. In older versions, it worked when printing values with writeln. But due to an error in formattedWrite, the program breaks. So I stopped using @property. For example, you can't see the difference in: ```d struct Funy(T) { import std.conv : to; this(X)(X x) { value = x.to!T; } T value; alias value this; // [a] getter //@property T opAssign(T x) { // [b] setter return value = x; } alias opCall = opAssign; /* hack: `opAssign` methods are not used for initialization, but for subsequent assignments [c] incrementor: */ //@property T opOpAssign(string op: "+", X)(X x) { return value = value + x.to!T; } } import std.stdio; void main() { auto funy = Funy!uint(20); funy.value.writeln; // 20 funy = 10; funy.value.writeln; // 1 class Fun { Funy!int n; this(int i) { n = i; // or: n(i + 1); } } auto fun = new Fun(-2); fun.n.writeln; // -1 fun.n += 19.999; fun.n.writeln; // 18 } ``` Let's continue the fun... ```d struct Funy(T) { this(T x) { value = x; } T value; alias opCall this; //@property: T opCall(T n) { return value = n; } T opCall() { return value; } } import std.stdio; void main() { auto funy = Funy!uint(20); funy.value.writeln; // 20 funy = 10; funy.value.writeln; // 1 class Fun { Funy!int n; this(int i) { n = i; // or: n(i + 1); } } auto fun = new Fun(-2); fun.n.writeln; // -1 fun.n = 20; fun.n.writeln; // 0 } /* PRINTS: 20 10 Funy!int(-1) Funy!int(20) ``` If you don't want to get the above output you should use the previous example. But don't forget to connect alias and opCall. For example, you can use @property in version 2.0.83 without all the fanfare. SDB@79
how to use dmd.lexer.Lexer
Hello, I'm trying to write a script which parse a c header and then ouput basic bindings for multiple languages. I read from the forum some times ago that the D compiler could be used as a library and found [the lexer page in the documentation](https://dlang.org/library/dmd/lexer/lexer.html) but `import dmd.lexer: Lexer` fails with the following error : ``` modlibBinder.d(3): Error: unable to read module `lexer` modlibBinder.d(3):Expected 'dmd/lexer.d' or 'dmd/lexer/package.d' in one of the following import paths: import path[0] = . import path[1] = /usr/include/dmd/phobos import path[2] = /usr/include/dmd/druntime/import Failed: ["/usr/bin/dmd", "-v", "-o-", "modlibBinder.d", "-I."] ``` What are the steps to take to be able to call the lexer (and maybe also the parser) over a C header file ?