Re: Bug or feature? iota has different semantics for integer and float arguments

2023-01-06 Thread Ali Çehreli via Digitalmars-d-learn

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

2023-01-06 Thread Arredondo via Digitalmars-d-learn

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

2023-01-06 Thread Ali Çehreli via Digitalmars-d-learn

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

2023-01-06 Thread Richard (Rikki) Andrew Cattermole via Digitalmars-d-learn

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

2023-01-06 Thread Arredondo via Digitalmars-d-learn

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?

2023-01-06 Thread Salih Dincer via Digitalmars-d-learn

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?

2023-01-06 Thread Salih Dincer via Digitalmars-d-learn
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

2023-01-06 Thread jonatjano via Digitalmars-d-learn

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 ?