Re: 'auto' keyword

2023-03-12 Thread Ali Çehreli via Digitalmars-d-learn

On 3/12/23 06:07, DLearner wrote:

> 1. As a shorthand to make the type of the variable being declared the
> same as the type on the right hand side of an initial assignment.

As Adam explained, D already has type inference without a special keyword.

However, some places where 'auto' (or 'const', etc.) appear is not only 
for "shorthand" but for necessity.


Some types cannot be spelled-out at all:

auto foo() {
struct S {}
return S();
}

void main() {
pragma(msg, typeof(foo()));
auto s = foo();
}

The name 'S' is available only inside 'foo', so code outside has no 
choice but to use 'auto' (or 'const', etc.)


Having said that, it is still possible to alias the returned type, which 
may be cumbersome in some cases because you may have to come up with a 
clean expression for attempting to call the function. In this case it's 
trivial because foo does not take any parameter:


alias T = typeof(foo());
T t;// <-- There: I did not need to use 'auto'

Ali



Re: 'auto' keyword

2023-03-12 Thread kdevel via Digitalmars-d-learn

On Sunday, 12 March 2023 at 13:27:05 UTC, Adam D Ruppe wrote:

[...] *any* storage class will work for type inference. [...]


After heaving read [1] I immediately thought of this:

   void main ()
   {
  deprecated i = 3;
  i = 4;
   }
   $ dmd test.d
   test.d(4): Deprecation: variable `test.main.i` is deprecated

Does that make sense???

[1] https://issues.dlang.org/show_bug.cgi?id=7432
Issue 7432 - DMD allows variables to be declared as pure


Re: 'auto' keyword

2023-03-12 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 12 March 2023 at 15:31:07 UTC, Salih Dincer wrote:

Moreover, `auto ref` or `ref auto` is needed in functions.


That's because `ref` isn't part of the argument or return value's 
type, so it isn't covered by **type** inference. Instead, D has a 
totally separate feature for "`ref` inference".


Re: 'auto' keyword

2023-03-12 Thread Salih Dincer via Digitalmars-d-learn

On Sunday, 12 March 2023 at 13:07:58 UTC, DLearner wrote:
Is it correct that this _single_ keyword is used to indicate 
_two_ quite different things:


1. As a shorthand to make the type of the variable being 
declared the same as the type on the right hand side of an 
initial assignment.


The auto keyword is really helpful for shortening it.  But in at 
least 2 cases (one of which is interfaces) it should help the 
compiler.  For example, contrary to expected, it is dynamic array:


```d
auto arr = [ 1, 2, 3 ];
```

Moreover, `auto ref` or `ref auto` is needed in functions.

SDB@79


Re: 'auto' keyword

2023-03-12 Thread Adam D Ruppe via Digitalmars-d-learn

On Sunday, 12 March 2023 at 13:07:58 UTC, DLearner wrote:
Is it correct that this _single_ keyword is used to indicate 
_two_ quite different things:


No, it only actually does #2 in your thing. The type is optional 
meaning *any* storage class will work for type inference. `auto` 
is not special in variable declarations. (it can be special in 
other contexts though).


auto A = 5;
static A = 5;
const A = 5;

all the same.


Re: auto scope question?

2022-10-25 Thread WhatMeWorry via Digitalmars-d-learn



typeof(screen.output.findSplit("")) s;


Perfect. That was the "essence" of my question. But thanks to 
Ali, I don't have to use such esoteric syntax.  D is a wonderful 
language, but I seem to shoot myself in the foot :)


Re: auto scope question?

2022-10-25 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/25/22 6:07 PM, WhatMeWorry wrote:
I'm naturally getting a undefined identifier `s` error in the return.  
Is there some way to refactor my code?  I tried to declare s outside of 
the else brackets like:


auto screen = executeShell(cmdLine);
auto s;
...
{
     s = screen.output.findSplit("REG_SZ");
}

but that doesn't compile either.



string[] getPath(string cmdLine)
{
     auto screen = executeShell(cmdLine);

     if (screen.status != 0)
     {
     writeln(cmdLine, " failed");
     }
     else
     {
     writeln("screen.output = ", screen.output);
 auto s = screen.output.findSplit("REG_SZ");
     writeln("s[0] = ", s[0]);
     writeln("s[1] = ", s[1]);
     writeln("s[2] = ", s[2]);
     }
     return (s.split(';'));  // Error: undefined identifier `s`
}


As Ali mentioned, your logic is faulty -- you seem to write that the 
command failed, but then return something anyway.


Also, you are returning `string[]`, so just declaring `string[] s;` 
should be enough.


However, I did want to mention that if you do want to hoist a difficult 
to name type outside where it is declared with an auto, you can use 
`typeof`:


```d
typeof(screen.output.findSplit("")) s;
```

In this case, it's just `string[]`, but the idea here is you can name a 
type without naming it, by using `typeof` on the expression you would 
have called.


Hope this helps further your D knowledge ;)

-Steve


Re: auto scope question?

2022-10-25 Thread Ali Çehreli via Digitalmars-d-learn

On 10/25/22 15:07, WhatMeWorry wrote:

> auto screen = executeShell(cmdLine);
> auto s;

That can't work because there is no information to infer the type of 
's'. Judging from the return type of getPath, perhaps it's string[]:


string[] s;

This is the question we should answer first: What should happen when 
executeShell fails?


a) It is an error; the program should not continue. Then we can use 
'enforce' (this is my way of coding):


string[] getPath(string cmdLine)
{
import std.exception : enforce;

auto screen = executeShell(cmdLine);
enforce(screen.status == 0, format!"%s failed:\n%s"(cmdLine, 
screen.output));


writeln("screen.output = ", screen.output);
auto s = screen.output.findSplit("REG_SZ");
writeln("s[0] = ", s[0]);
writeln("s[1] = ", s[1]);
writeln("s[2] = ", s[2]);

return (s.split(';'));
}

b) It is not an error; getPath() should return empty array:

string[] getPath(string cmdLine)
{
string[] result;
auto screen = executeShell(cmdLine);

if (screen.status != 0)
{
writeln(cmdLine, " failed");
return null;  // <-- HERE (null converts to any array type)
}
else
{
// ...
// Now, 'return' is where 's' is defined:
return (s.split(';'));
}
}

Ali



Re: auto ref function parameter causes that non copyable struct is copied?

2021-11-10 Thread Sebastiaan Koppe via Digitalmars-d-learn

On Tuesday, 9 November 2021 at 19:30:20 UTC, tchaloupka wrote:

On Monday, 8 November 2021 at 23:26:39 UTC, tchaloupka wrote:

Bug or feature? :)


I've reported it in 
https://issues.dlang.org/show_bug.cgi?id=22498.


It doesn't copy. It just destructs the same object twice... Ouch.

Change the destructor to `~this() { printf("~this(%d)\n", n); n = 
12; }` and you'll see.


I have been looking at LDC's IR of this. `unwrap` takes a lvalue, 
but the compiler puts the object from `gen` on main's stack and 
gives a pointer to unwrap instead. `unwrap` is now the sole owner 
of the object, and calls the destructor before returning a ref to 
one of its fields.


I haven't figured out the interplay of features and optimizations 
here, but it looks like a leak. I would have expected @safe to 
catch this.


As you said in the bug, NVRO solves it (not sure why). As well as 
not passing a lvalue into `unwrap` in the first place.


Re: auto ref function parameter causes that non copyable struct is copied?

2021-11-09 Thread tchaloupka via Digitalmars-d-learn

On Monday, 8 November 2021 at 23:26:39 UTC, tchaloupka wrote:

Bug or feature? :)


I've reported it in 
https://issues.dlang.org/show_bug.cgi?id=22498.


Re: auto ref function parameter causes that non copyable struct is copied?

2021-11-08 Thread tchaloupka via Digitalmars-d-learn

On Tuesday, 9 November 2021 at 02:43:55 UTC, jfondren wrote:

On Tuesday, 9 November 2021 at 02:41:18 UTC, jfondren wrote:
The expectation is probably that `f.move` set `f` to 
`Foo.init`, but the docs say:


Posted too fast. Foo qualifies with its @disable:

```d
struct A { int x; }
struct B { int x; @disable this(this); }

unittest {
import core.lifetime : move;
auto a = A(5);
auto b = B(5);
a.move;
b.move;
assert(a == A(5));
assert(b == B(0));
}
```


Yes it should qualify so it should be cleaned out when moved.
When I change:

```D
auto ref unwrap(EX)(auto ref EX res) {
printf("unwrap()\n");
return res.get();
}
```

I get:

```
~this(0)
~this(0)
~this(0)
unwrap()
~this(42)
~this(0)
~this(42)
```

So the destructor isn't called from `gen()` -> there is 
[NRVO](https://dlang.org/glossary.html#nrvo) in play.


Also `pragma(msg, __traits(isRef, res));` prints false in unwrap 
in this case (which is expected), but how it gets there as a 
value when it's not moved and instead copied even though it has 
disabled copy constructor?

`isCopyable!(Value!Foo)` returns false as expected too.


Re: auto ref function parameter causes that non copyable struct is copied?

2021-11-08 Thread jfondren via Digitalmars-d-learn

On Tuesday, 9 November 2021 at 02:41:18 UTC, jfondren wrote:
The expectation is probably that `f.move` set `f` to 
`Foo.init`, but the docs say:


Posted too fast. Foo qualifies with its @disable:

```d
struct A { int x; }
struct B { int x; @disable this(this); }

unittest {
import core.lifetime : move;
auto a = A(5);
auto b = B(5);
a.move;
b.move;
assert(a == A(5));
assert(b == B(0));
}
```


Re: auto ref function parameter causes that non copyable struct is copied?

2021-11-08 Thread jfondren via Digitalmars-d-learn
On Tuesday, 9 November 2021 at 02:19:28 UTC, Stanislav Blinov 
wrote:

On Monday, 8 November 2021 at 23:26:39 UTC, tchaloupka wrote:


```
auto gen() {
Foo f;   // <--- this one
f.n = 42;
return value(f.move());
}

void main() {
Foo f;
f = gen().unwrap.move;
}
```
~this(0)
~this(0)
~this(0)
~this(42) <- this is a copy (that shouldn't exist) being 
destroyed

~this(0)
~this(42)



Is it a copy? I think the first destructor call is one of `f` 
in `gen` (marked by the comment above)


The expectation is probably that `f.move` set `f` to `Foo.init`, 
but the docs say:


"If T is a struct with a destructor or postblit defined, source 
is reset to its .init value after it is moved into target, 
otherwise it is left unchanged."


```d
struct A { int x; }
struct B { int x; this(this) { } }

unittest {
import core.lifetime : move;
auto a = A(5);
auto b = B(5);
a.move;
b.move;
assert(a == A(5));
assert(b == B(0));
}
```


Re: auto ref function parameter causes that non copyable struct is copied?

2021-11-08 Thread Stanislav Blinov via Digitalmars-d-learn

On Monday, 8 November 2021 at 23:26:39 UTC, tchaloupka wrote:


```
auto gen() {
Foo f;   // <--- this one
f.n = 42;
return value(f.move());
}

void main() {
Foo f;
f = gen().unwrap.move;
}
```
~this(0)
~this(0)
~this(0)
~this(42) <- this is a copy (that shouldn't exist) being 
destroyed

~this(0)
~this(42)



Is it a copy? I think the first destructor call is one of `f` in 
`gen` (marked by the comment above)


Re: auto vectorization notes

2020-03-28 Thread Bruce Carneal via Digitalmars-d-learn

On Saturday, 28 March 2020 at 18:01:37 UTC, Crayo List wrote:

On Saturday, 28 March 2020 at 06:56:14 UTC, Bruce Carneal wrote:

On Saturday, 28 March 2020 at 05:21:14 UTC, Crayo List wrote:

On Monday, 23 March 2020 at 18:52:16 UTC, Bruce Carneal wrote:

[snip]
Explicit SIMD code, ispc or other, isn't as readable or 
composable or vanilla portable but it certainly is performance 
predictable.


This is not true! The idea of ispc is to write portable code 
that will
vectorize predictably based on the target CPU. The object 
file/binary is not portable,

if that is what you meant.
Also, I find it readable.



There are many waypoints on the readability <==> performance 
axis.  If ispc works for you along that axis, great!


I find SIMT code readability better than SIMD but a little 
worse than auto-vectorizable kernels.  Hugely better 
performance though for less effort than SIMD if your platform 
supports it.


Again I don't think this is true. Unless I am misunderstanding 
you, SIMT and SIMD
are not mutually exclusive and if you need performance then you 
must use both.
Also based on the workload and processor SIMD may be much more 
effective than SIMT.j


SIMD might become part of the solution under the hood for a 
number of reasons including: ease of deployment, programmer 
familiarity, PCIe xfer overheads, kernel launch overhead, memory 
subsystem suitability, existing code base issues, ...


SIMT works for me in high throughput situations where it's hard 
to "take a log" on the problem.  SIMD, in auto-vectorizable or 
more explicit form, works in others.


Combinations can be useful but most of the work I've come in 
contact with splits pretty clearly along the memory bandwidth 
divide (SIMT on one side, SIMD/CPU on the other).  Others need a 
plus-up in arithmetic horsepower.  The more extreme the 
requirements, the more attractive SIMT appears. (hence my 
excitement about dcompute possibly expanding the dlang 
performance envelope with much less cognitive load than 
CUDA/OpenCL/SycL/...)


On the readability front, I find per-lane programming, even with 
the current thread-divergence caveats, to be easier to reason 
about wrt correctness and performance predictability than other 
approaches.  Apparently your mileage does vary.


When you have chosen SIMD, whether ispc or other, over SIMT what 
drove the decision?  Performance?  Ease of programming to reach a 
target speed?



















Re: auto vectorization notes

2020-03-28 Thread Crayo List via Digitalmars-d-learn

On Saturday, 28 March 2020 at 06:56:14 UTC, Bruce Carneal wrote:

On Saturday, 28 March 2020 at 05:21:14 UTC, Crayo List wrote:

On Monday, 23 March 2020 at 18:52:16 UTC, Bruce Carneal wrote:

[snip]
(on the downside you have to guard against compiler code-gen 
performance regressions)




auto vectorization is bad because you never know if your code 
will get vectorized next time you make some change to it and 
recompile.

Just use : https://ispc.github.io/


Yes, that's a downside, you have to measure your performance 
sensitive code if you change it *or* change compilers or 
targets.


Explicit SIMD code, ispc or other, isn't as readable or 
composable or vanilla portable but it certainly is performance 
predictable.


This is not true! The idea of ispc is to write portable code that 
will
vectorize predictably based on the target CPU. The object 
file/binary is not portable,

if that is what you meant.
Also, I find it readable.

I find SIMT code readability better than SIMD but a little 
worse than auto-vectorizable kernels.  Hugely better 
performance though for less effort than SIMD if your platform 
supports it.


Again I don't think this is true. Unless I am misunderstanding 
you, SIMT and SIMD
are not mutually exclusive and if you need performance then you 
must use both.
Also based on the workload and processor SIMD may be much more 
effective than SIMT.






Re: auto vectorization notes

2020-03-28 Thread Bruce Carneal via Digitalmars-d-learn

On Saturday, 28 March 2020 at 05:21:14 UTC, Crayo List wrote:

On Monday, 23 March 2020 at 18:52:16 UTC, Bruce Carneal wrote:

[snip]
(on the downside you have to guard against compiler code-gen 
performance regressions)




auto vectorization is bad because you never know if your code 
will get vectorized next time you make some change to it and 
recompile.

Just use : https://ispc.github.io/


Yes, that's a downside, you have to measure your performance 
sensitive code if you change it *or* change compilers or targets.


Explicit SIMD code, ispc or other, isn't as readable or 
composable or vanilla portable but it certainly is performance 
predictable.


I find SIMT code readability better than SIMD but a little worse 
than auto-vectorizable kernels.  Hugely better performance though 
for less effort than SIMD if your platform supports it.


Is anyone actively using dcompute (SIMT enabler)?  Unless I hear 
bad things I'll try it down the road as neither going back to 
CUDA nor "forward" to the SycL-verse appeals.























Re: auto vectorization notes

2020-03-27 Thread Crayo List via Digitalmars-d-learn

On Monday, 23 March 2020 at 18:52:16 UTC, Bruce Carneal wrote:
When speeds are equivalent, or very close, I usually prefer 
auto vectorized code to explicit SIMD/__vector code as it's 
easier to read.  (on the downside you have to guard against 
compiler code-gen performance regressions)


One oddity I've noticed is that I sometimes need to use 
pragma(inline, *false*) in order to get ldc to "do the right 
thing". Apparently the compiler sees the costs/benefits 
differently in the standalone context.


More widely known techniques that have gotten people over the 
serial/SIMD hump include:

 1) simplified indexing relationships
 2) known count inner loops (chunkify)
 3) static foreach blocks (manual inlining that the compiler 
"gathers")


I'd be interested to hear from others regarding their auto 
vectorization and __vector experiences.  What has worked and 
what hasn't worked in your performance sensitive dlang code?


auto vectorization is bad because you never know if your code 
will get vectorized next time you make some change to it and 
recompile.

Just use : https://ispc.github.io/



Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Per Nordlöw via Digitalmars-d-learn

On Sunday, 23 February 2020 at 18:40:03 UTC, Adam D. Ruppe wrote:
The error I currently get when clicking the documentation link 
https://phobos-next.dpldocs.info/ is


try it now.

I've been tweaking the time out and retry numbers lately so it 
is less likely to do this but still sometimes does when it 
regenerates...


but still that particular error you saw indicates i messed up 
an if condition somewhere, that path is supposed to be 
impossible. oops.


regardless it works now and you can see some of the new style 
tweaks I've been doing!


Wonderful!

Thanks


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Adam D. Ruppe via Digitalmars-d-learn

On Sunday, 23 February 2020 at 18:20:19 UTC, Per Nordlöw wrote:
The error I currently get when clicking the documentation link 
https://phobos-next.dpldocs.info/ is


try it now.

I've been tweaking the time out and retry numbers lately so it is 
less likely to do this but still sometimes does when it 
regenerates...


but still that particular error you saw indicates i messed up an 
if condition somewhere, that path is supposed to be impossible. 
oops.


regardless it works now and you can see some of the new style 
tweaks I've been doing!


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Per Nordlöw via Digitalmars-d-learn

On Sunday, 23 February 2020 at 18:18:25 UTC, Per Nordlöw wrote:

On Sunday, 23 February 2020 at 17:18:48 UTC, Andre Pany wrote:
If your Dub package is registered on code.dlang.org, this is 
automatically provided.


Example: http://code.dlang.org/packages/arsd-official
Click on the documentation link.

Beside that you can use e.g. Github Actions to create 
documentation.


Kind regards
Andre


I've fixed my phobos-next so that doc generation now works via

dub build --build=docs --compiler=dmd

Is this command called only when I tag my repo with a new 
version?


The error I currently get when clicking the documentation link 
https://phobos-next.dpldocs.info/ is



The project build failed. copy/paste this link to adam so he can 
fix the bug.


std.file.FileException@std/file.d(379): 
/dpldocs/phobos-next/master/adrdox-generated/: Is a directory


/home/me/d/dmd2/linux/bin64/../../src/phobos/std/file.d:273 
@trusted bool std.file.cenforce!(bool).cenforce(bool, scope 
const(char)[], scope const(char)*, immutable(char)[], ulong) 
[0x543266]
??:? @trusted void[] std.file.readImpl(scope const(char)[], scope 
const(char)*, ulong) [0x5ec90b]
/home/me/d/dmd2/linux/bin64/../../src/phobos/std/file.d:310 @safe 
void[] std.file.read!(immutable(char)[]).read(immutable(char)[], 
ulong) [0x543041]

dl.d:271 void dl.app(arsd.cgi.Cgi) [0x528000]
/home/me/arsd/cgi.d:3815 void 
arsd.cgi.doThreadScgiConnection!(arsd.cgi.Cgi, 
dl.app(arsd.cgi.Cgi), 
500L).doThreadScgiConnection(std.socket.Socket) [0x546e43]
/home/me/arsd/cgi.d:4361 void arsd.cgi.ConnectionThread.run() 
[0x53b2a8]

??:? void core.thread.Thread.run() [0x5c8a25]
??:? thread_entryPoint [0x6159cb]
??:? [0x7f0c425e76da]


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Per Nordlöw via Digitalmars-d-learn

On Sunday, 23 February 2020 at 17:18:48 UTC, Andre Pany wrote:
If your Dub package is registered on code.dlang.org, this is 
automatically provided.


Example: http://code.dlang.org/packages/arsd-official
Click on the documentation link.

Beside that you can use e.g. Github Actions to create 
documentation.


Kind regards
Andre


I've fixed my phobos-next so that doc generation now works via

dub build --build=docs --compiler=dmd

Is this command called only when I tag my repo with a new version?


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Basile B. via Digitalmars-d-learn

On Sunday, 23 February 2020 at 17:14:33 UTC, Per Nordlöw wrote:
I would like to setup auto-generation of online documentation 
for my public D libraries residing on Github and Gitlab.


What alternatives do I have?


for gitlab they have a system of pages that's quite easy to setup:

something like

.gitlab-ci.yml
---
#to get dmd and dub
image: dlang2/dmd-ubuntu

#special section to generate gitlab "pages"
pages:
  before_script:
  - apt-get install -y 
  - 
  script:
  - 
  artifacts:
paths:
- public
  only:
  - master
  - 
---

and then your doc is online and updated for each push.
It can be downloaded from the artifacts too, maybe in an 
automated way I think, but havent used this for now so cant say.


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 23 February 2020 at 17:38:35 UTC, Per Nordlöw wrote:

On Sunday, 23 February 2020 at 17:18:48 UTC, Andre Pany wrote:

Example: http://code.dlang.org/packages/arsd-official
Click on the documentation link.

Beside that you can use e.g. Github Actions to create 
documentation.


Kind regards
Andre


Thanks!

How do I check which dmd or dub command that is called to 
generate the docs?


They are generated using adrdox, a third-party documentation 
generator by Adam Ruppe:


https://github.com/adamdruppe/adrdox

The exact command used to generate the docs for dpldocs.info can 
be found here:


https://github.com/adamdruppe/dpldocs/blob/858e375b98883c9a46a6ff9a894f371fcfae23a0/dl.d#L301-L309


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Per Nordlöw via Digitalmars-d-learn

On Sunday, 23 February 2020 at 17:18:48 UTC, Andre Pany wrote:

Example: http://code.dlang.org/packages/arsd-official
Click on the documentation link.

Beside that you can use e.g. Github Actions to create 
documentation.


Kind regards
Andre


Thanks!

How do I check which dmd or dub command that is called to 
generate the docs?


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Andre Pany via Digitalmars-d-learn

On Sunday, 23 February 2020 at 17:14:33 UTC, Per Nordlöw wrote:
I would like to setup auto-generation of online documentation 
for my public D libraries residing on Github and Gitlab.


What alternatives do I have?


If your Dub package is registered on code.dlang.org, this is 
automatically provided.


Example: http://code.dlang.org/packages/arsd-official
Click on the documentation link.

Beside that you can use e.g. Github Actions to create 
documentation.


Kind regards
Andre


Re: Auto-generation of online documentation for my open libraries

2020-02-23 Thread Per Nordlöw via Digitalmars-d-learn

On Sunday, 23 February 2020 at 17:14:33 UTC, Per Nordlöw wrote:
I would like to setup auto-generation of online documentation 
for my public D libraries residing on Github and Gitlab.


What alternatives do I have?


I'm thinking something like http://ddocs.org announced here 
https://forum.dlang.org/thread/weuxppabkrreaxbqq...@forum.dlang.org.


Unfortunately http://ddocs.org seems to be down. Are there any 
mirrors up?


Re: auto keyword

2020-01-30 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jan 30, 2020 at 09:37:40AM +, Michael via Digitalmars-d-learn wrote:
[...]
> auto elements = buf.to!string.strip.split(" ").filter!(a => a != "");
> 
> That line strips white space from buf, splits it, removes empty
> elements and returns an array of strings. At least I thought so.

If you want an array of strings, just add .array to the end, and you
will get string[] back.


> Indeed elements can be treated as a string slice, but if i replace
> auto by string[] the compiler complains:
> Error: cannot implicitly convert expression filter(split(strip(to(buf)), "
> ")) of type FilterResult!(__lambda1, string[]) to string[]

That's because the actual type is a lazily-evaluated range.


> In order to use an explicit type I wonder what kind of type I might
> use instead of auto?

In this case, you actually can't spell out the type, because it's a
Voldemort type (it's only defined inside the function that constructs
it, and is not directly nameable outside).  Usually, a Voldemort type is
returned when you *shouldn't* be referring to it with an explicit type.
For example, in this case, if what you really want is an array of
strings then you should add .array at the end to get a string[].

If you wish to store the lazy range, for whatever reason, you can use
the typeof() operator to extract a type from it (without actually
spelling it out -- because you can't):

auto elements = buf.to!string.strip.split(" ").filter!(a => a != "");
alias E = typeof(elements);
E x;
x = elements;

Usually this is only useful if you wish the store the lazy range inside
some kind of aggregate type while retaining its lazy evaluation
semantics.  But if you expect it to be eagerly evaluated anyway, there's
no need to jump through hoops to get at the type of `elements`; just
stick .array to the end of it and get a string[] back.


T

-- 
"The whole problem with the world is that fools and fanatics are always so 
certain of themselves, but wiser people so full of doubts." -- Bertrand 
Russell. "How come he didn't put 'I think' at the end of it?" -- Anonymous


Re: auto keyword

2020-01-30 Thread Jonathan M Davis via Digitalmars-d-learn
On Thursday, January 30, 2020 2:37:40 AM MST Michael via Digitalmars-d-learn 
wrote:
> auto is surely a nice feature. Nonetheless I'd prefer to use
> explicit types. So when reading a code and I see the auto keyword
> I also have to find out what kind of type is meant.
>
> I have a line of code that looks like this:
> auto elements = buf.to!string.strip.split(" ").filter!(a => a !=
> "");
>
> That line strips white space from buf, splits it, removes empty
> elements and returns an array of strings. At least I thought so.
>
> Indeed elements can be treated as a string slice, but if i
> replace auto by string[] the compiler complains:
> Error: cannot implicitly convert expression
> filter(split(strip(to(buf)), " ")) of type
> FilterResult!(__lambda1, string[]) to string[]
>
> In order to use an explicit type I wonder what kind of type I
> might use instead of auto?

For code like that, you don't. A lot of code in D - especially code that
uses ranges - uses what are called Voldemort types. They are declared inside
the function and you have no access to them. They follow a known API, so you
know what to do with them, but you they have no name that you have access
to. Realistically though, even if you had access to the type's name, you
wouldn't want to use it explicitly anyway, because usually, it's a templated
type which is instantiated with another templated type and is likely several
layers deep. Using the explicit names would be hideous. Years ago (before we
had Voldemort types), there was a bug in ddoc that made functions that
returned auto not show up in the documentation. So, all of std.algorithm
returned explicit types, and they were so hideous that it just scared
people. It works _far_ better to just understand how to use these types and
not use their names explicitly. It also makes the code far more resilient to
changes, since as long as the return type retains the same API, it doesn't
matter how the return type is changed. A function like filter could have
its return type changed to something else, and the code calling it wouldn't
care so long as it was the same kind of range.

Since you probably aren't familiar with ranges in D (or you wouldn't be
trying to use them by name), I suggest that you read this:

http://ddili.org/ders/d.en/ranges.html

And in addition to the fact that you pretty much have to use auto with
range-based code, you're pretty much going to have to get used to dealing
with D code using auto heavily, because that's what most D code does.
Certainly, sometimes, you can use type names explicitly, but it's common
practice to use auto most of the time. It can take a bit of getting used to,
but ultimately, it actually results in more maintainable code.

- Jonathan M Davis





Re: Auto keyword and when to use it

2018-08-22 Thread XavierAP via Digitalmars-d-learn

On Tuesday, 21 August 2018 at 21:37:00 UTC, QueenSvetlana wrote:


I had a misunderstanding about the keyword auto because I 
wrongfully believed that it made the code like Python


Exactly, you are thinking still like D is Python or also 
dynamically typed. :) You will get when compiling errors that 
Python wouldn't detect until run-time (or with your private 
methods).


- A declaration with auto needs to include an initialization.
- The code will be equivalent as if replacing "auto" with the 
inferred type. It is not left for later to check.


I'm not terribly bothered btw by "Type = new Type()" but often 
type names get too long or include namespaces... 
"mylib.numeric.squareObjectWithPointyCorners = new 
mylib.numeric.squareObjectWithPointyCorners()"


Re: Auto keyword and when to use it

2018-08-21 Thread QueenSvetlana via Digitalmars-d-learn

On Tuesday, 21 August 2018 at 18:44:15 UTC, Jim Balter wrote:
Python is not statically typed; D is. Why are you talking about 
Python? You asked whether D's auto is like C#'s var ... it is, 
but it doesn't have C#'s pointless restriction of not being 
allowed for non-local declarations.


I think you misunderstood my point. Let me elaborate. In Python a 
type could change at anytime, for example:


number = 1

In Python the variable number will be treated as an int, but at 
any point in my code, that could change, in Python this is legal:


number = "one"

The code will compile and run. Now Python introduced type hints 
to tell the reader how to treat the variable.


The problem with the code is, when you have a class, take my 
Person example, a person will obviously have a first and last 
name, which should be strings, now without validation I can pass 
ints to those variables, which is undesirable. I would need a 
private function to check the types passed and reject it if they 
aren't strings, in addition to if the string is blank or contains 
foreign characters.


I had a misunderstanding about the keyword auto because I 
wrongfully believed that it made the code like Python, and for 
that I apologize. I thought you were allowed to make class 
variables auto, so for example:


class Person{

auto firstName
auto lastName
}

If this was allowed, when I create my person object, I can pass 
ints to firstName and lastName, which is obviously undesirable. I 
would need to check what value types were passed and reject them 
if they aren't strings.


As pointed out in the answers above, this isn't legal, which 
means, there is no need to check anything, it won't compile.


Re: Auto keyword and when to use it

2018-08-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, August 21, 2018 12:22:42 PM MDT QueenSvetlana via Digitalmars-d-
learn wrote:
> On Monday, 20 August 2018 at 17:55:11 UTC, JN wrote:
> > class Foo
> > {
> >
> > auto bar;
> >
> > }
> >
> > because now the compiler doesn't know what type 'bar' is
> > supposed to be.
>
> Just to clarify, even if I set bar in the constructor, I can't
> declare it with auto first, correct? I would have to declare a
> specific type?

Yes. As Mike's excellent response explained, auto is simply used to indicate
that you're not providing the explicit type and that it should be inferred
from the direct initialization of the variable. Whenever an explicit type is
not provided for a variable when declaring it, you _must_ use direct
initialization so that the type can be inferred. You can't do something like
have the type of a member variable inferred from what the constructor is
doing. And code like

auto foo;

is never legal.

- Jonathan M Davis





Re: Auto keyword and when to use it

2018-08-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, August 21, 2018 9:04:31 AM MDT Steven Schveighoffer via 
Digitalmars-d-learn wrote:
> On 8/20/18 9:15 PM, Mike Parker wrote:
> > I tend to use type inference liberally, almost always with
> > const/immutbale locals, though I tend to use auto only when the type
> > name is longer than four characters. For me, it's a nice way to save
> > keystrokes. Some take a dim view of that approach and prefer to use it
> > only when they actually require type inference. I mostly program alone,
> > though, and I have a number of habits others may label 'bad', so I'm
> > happy with my approach.
>
> I'm more extreme in this camp -- I use auto everywhere. Why? because at
> some point, I may change some type somewhere (oops, I should have wrote
> size_t instead of uint), and then I would have to go through and change
> all the places I put the concrete type if I hadn't used auto.
>
> While using functions, I also can use auto and not have to worry about
> the type. I know kind of what it is (integer type, string type, range
> type, etc), and not care what the exact type is.

I'd argue that it's generally better to use explicit types where possible in
function signatures so that the documentation is clearer, but overall, I
agree with you, and if I can use type inference, I almost always do.
However, it does seem like the sort of thing that many newcomers to D balk
at initially, whereas most of us who have been using it for a while have no
problem with it and prefer it.

- Jonathan M Davis





Re: Auto keyword and when to use it

2018-08-21 Thread Jim Balter via Digitalmars-d-learn

On Tuesday, 21 August 2018 at 18:18:25 UTC, QueenSvetlana wrote:

On Tuesday, 21 August 2018 at 16:15:32 UTC, XavierAP wrote:

Only if someone
likes "Type x = new Type()" instead of "auto x = new Type()" I 
would say they're clearly wrong.


As you stated it's up to the programmer to decided. I'm in 
favor of Type x = new Type()


There is nothing to recommend such redundancy; don't do it.

because when it comes to constructing a class it usually means 
more code to verify the types


Type inference doesn't require more code.


for example:


Your example has no bearing on any of the above ... it's not an 
example of it.




class Person {
  auto firstName;
  auto lastName;

  // constuctor to set first and last names

}


That code is meaningless and isn't legal. You need to either 
provide explicit types, or they need to be inferable from the 
type of the initializer.


The compiler doesn't know know what firstName or lastName is 
supposed to be and a programmer might make the obvious 
assumption and use them as strings.


The programmer can't make any assumption because the code is not 
remotely legal.


Doing this also means you have reject any type that isn't a 
string which means a private function to check the type that 
was pass to the constructor before initializing it. Where as if 
you declared it as a string to start of with, all you have to 
ensure is that it's not blank or contain illegal characters.


This is all incoherent. D is a statically typed language.

As the answer stated above doing what I showed in my example 
isn't allowed and this is where Python gets frustrating, 
because at any point the types could change. They introduced 
type hints, but it's not enforced, it just makes it more 
readable, you still have to write code to ensure the proper 
types were passed.


Python is not statically typed; D is. Why are you talking about 
Python? You asked whether D's auto is like C#'s var ... it is, 
but it doesn't have C#'s pointless restriction of not being 
allowed for non-local declarations.




Re: Auto keyword and when to use it

2018-08-21 Thread QueenSvetlana via Digitalmars-d-learn

On Monday, 20 August 2018 at 17:55:11 UTC, JN wrote:

class Foo
{
auto bar;
}

because now the compiler doesn't know what type 'bar' is 
supposed to be.


Just to clarify, even if I set bar in the constructor, I can't 
declare it with auto first, correct? I would have to declare a 
specific type?




Re: Auto keyword and when to use it

2018-08-21 Thread QueenSvetlana via Digitalmars-d-learn

On Tuesday, 21 August 2018 at 16:15:32 UTC, XavierAP wrote:

Only if someone
likes "Type x = new Type()" instead of "auto x = new Type()" I 
would say they're clearly wrong.


As you stated it's up to the programmer to decided. I'm in favor 
of Type x = new Type() because when it comes to constructing a 
class it usually means more code to verify the types, for example:



class Person {
  auto firstName;
  auto lastName;

  // constuctor to set first and last names

}

The compiler doesn't know know what firstName or lastName is 
supposed to be and a programmer might make the obvious assumption 
and use them as strings.


Doing this also means you have reject any type that isn't a 
string which means a private function to check the type that was 
pass to the constructor before initializing it. Where as if you 
declared it as a string to start of with, all you have to ensure 
is that it's not blank or contain illegal characters.


As the answer stated above doing what I showed in my example 
isn't allowed and this is where Python gets frustrating, because 
at any point the types could change. They introduced type hints, 
but it's not enforced, it just makes it more readable, you still 
have to write code to ensure the proper types were passed.


Re: Auto keyword and when to use it

2018-08-21 Thread XavierAP via Digitalmars-d-learn

On Monday, 20 August 2018 at 17:52:17 UTC, QueenSvetlana wrote:


So I can't declare class level variables with auto, correct? 
only local method variables?


One difference between D's auto and C#'s var or C++'s auto is 
that the latter languages allow automatically typed declarations 
only for local (method/function-scope) variables, and forbid them 
for class or struct member variables (aka fields); whereas D 
allows auto anywhere (even function/method return type! -- which 
C# and C++ allow as well but only case of anonymous 
methods/lambdas).


I'm in favor of the AAA ("Auto" Almost Always) paradigm, but as 
long as the type if obvious to a human reader. I don't favor them 
for numeric types for this reason (non obvious bitsize, 
signedness...) It's up to each programmer. Only if someone likes 
"Type x = new Type()" instead of "auto x = new Type()" I would 
say they're clearly wrong.


Re: Auto keyword and when to use it

2018-08-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 8/20/18 9:15 PM, Mike Parker wrote:
I tend to use type inference liberally, almost always with 
const/immutbale locals, though I tend to use auto only when the type 
name is longer than four characters. For me, it's a nice way to save 
keystrokes. Some take a dim view of that approach and prefer to use it 
only when they actually require type inference. I mostly program alone, 
though, and I have a number of habits others may label 'bad', so I'm 
happy with my approach.


I'm more extreme in this camp -- I use auto everywhere. Why? because at 
some point, I may change some type somewhere (oops, I should have wrote 
size_t instead of uint), and then I would have to go through and change 
all the places I put the concrete type if I hadn't used auto.


While using functions, I also can use auto and not have to worry about 
the type. I know kind of what it is (integer type, string type, range 
type, etc), and not care what the exact type is.


-Steve


Re: Auto keyword and when to use it

2018-08-20 Thread Mike Parker via Digitalmars-d-learn

On Monday, 20 August 2018 at 17:24:19 UTC, QueenSvetlana wrote:


I'm struggling to understand what the auto keyword is for and 
it's appropriate uses. From research, it seems to share the 
same capabilities as the var keyword in C#.


auto is one of the most misunderstood understood features in D. 
By that I mean, everyone understands the effect of auto, but 
aren't always accurate in describing it.


In D, every variable must have a storage class. The automatic 
storage class is the default and is never specified in the 
declaration:


int x = 10;

Other storage classes are const, immutable, and shared. These are 
also type constructors, so they become part of the type:


const int y = 11;  // type is const(int)
immutable int z = 12;  // type is immutable(int)
shared int s = 13; // type is shared(int)

D allows the type to be dropped in declarations that include an 
initializer. In those cases, the type will be inferred:


const y = 11;  // type is const(int)
immutable z = 12;  // type is immutable(int)
shared s = 13; // type is shared(int)

You can also drop the type in declarations with automatic 
storage, but `x = 10;` is not allowed as a variable declaration. 
You must include at minimum a type or a storage class. That's 
where auto comes in:


auto x = 10;  // type is int

So that's all it is. It's nothing special. It just means you're 
declaring a variable with the default storage class and want the 
compiler to infer the type.


So the question 'when should I use auto' is probably the wrong 
way to look at it. 'When should I use type inference' is a better 
way to frame it. And the answer to that is that there is no right 
answer.


I tend to use type inference liberally, almost always with 
const/immutbale locals, though I tend to use auto only when the 
type name is longer than four characters. For me, it's a nice way 
to save keystrokes. Some take a dim view of that approach and 
prefer to use it only when they actually require type inference. 
I mostly program alone, though, and I have a number of habits 
others may label 'bad', so I'm happy with my approach.


Re: Auto keyword and when to use it

2018-08-20 Thread JN via Digitalmars-d-learn

On Monday, 20 August 2018 at 17:52:17 UTC, QueenSvetlana wrote:

Great!

So I can't declare class level variables with auto, correct? 
only local method variables?


You can, globals, class members:

class Foo
{
auto bar = "hi";
}

Foo.bar will be of string type here, because "hi" is a string. 
What you can't do is:


class Foo
{
auto bar;
}

because now the compiler doesn't know what type 'bar' is supposed 
to be.


Re: Auto keyword and when to use it

2018-08-20 Thread Colin via Digitalmars-d-learn

On Monday, 20 August 2018 at 17:52:17 UTC, QueenSvetlana wrote:

Great!

So I can't declare class level variables with auto, correct? 
only local method variables?


You can use auto if you're setting the class level variable to a 
default.


class X {
  auto i = 42; // i will be an int

}


Re: Auto keyword and when to use it

2018-08-20 Thread QueenSvetlana via Digitalmars-d-learn

Great!

So I can't declare class level variables with auto, correct? only 
local method variables?


Re: Auto keyword and when to use it

2018-08-20 Thread JN via Digitalmars-d-learn

On Monday, 20 August 2018 at 17:24:19 UTC, QueenSvetlana wrote:
I'm new to D programming, but have I have a background with 
Python.


I'm struggling to understand what the auto keyword is for and 
it's appropriate uses. From research, it seems to share the 
same capabilities as the var keyword in C#. From the C# 
documentation, it states:


https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/var

... variables that are declared at method scope can have an 
implicit "type" var. An implicitly typed local variable is 
strongly typed just as if you had declared the type yourself, 
but the compiler determines the type.


Is the same true for auto? For example, if I have a class 
Person, I might have attributes such as FirstName, LastName 
which should obviously be strings but will D allow me to 
declare class level attributes with auto?


C# doesn't allow this.


It basically works like C#.

auto x = "hi";

will make x a string.

But if you later try:

x = 5;

it will throw an error, because x is a string. It's used to save 
you the typing of the type, it doesn't make the language 
dynamically typed.


Re: auto & class members

2018-05-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/22/18 4:40 AM, Robert M. Münch wrote:

On 2018-05-21 18:55:36 +, Steven Schveighoffer said:


When you use the alias, both are using the same exact lambda.


Ok. I didn't expect that the name is relevant in this case, instead 
assumed that only the types need to match.


The type is the problem. The type returned by filter is parameterized on 
that *specific* lambda. If you look at the error message, it says 
something like "lamda1" and "lambda4" in the type for filter.


In order to make this work, the compiler would have to make the name of 
the lambda based on the actual AST inside it. I think something like 
that should be done.





I see you are casting now as well,


Do I? Not that I'm aware of it in my pseudo-code example...


Haha, looking back, I see you didn't cast originally, which is probably 
the reason it didn't work :)


Here is the line from your revised example after Jonathan showed you how 
to declare a member of that type:


myB.mySubstream = myA.myStream.filter!(x => x == myMessage);

And here is the subsequent line:

myB.mySubstream = cast(myMessageType)myA.myStream.filter!(x => x == 
myMessage);


Both exactly the same, but one forces the cast. Your first line could 
have been done:


myB.mySubstream = 
cast(typeof(myB.mySubstream))myA.myStream.filter!(x => x == myMessage);


Giving a name helps to make the code less verbose, but essentially that 
is what you are doing -- forcing the cast.


What may make more sense (both for type sanity and for code reuse) is 
to wrap your call to filter into one place so it can be used wherever 
you need it:


auto wrapStream(S)(S str) { return str.filter!(x => x == myMessage); }

class b
{
    typeof(wrapStream(a.init.myStream)()) mySubStream;
}

void myFunc() {
    a myA = new a;
    b myB = new b;
    myB.mySubstream = myA.myStream.wrapStream;
}


This would require one wrap function per different lambda, right? Assume 
I have 50-100 of these. Maybe the myMessage value can be given as 
parameter and with this becomes more like a "filter factory". Not sure 
if this would work


Well, you then have to have 50-100 types of b with the correct member. 
Unless... you want to parameterize b, in which case it becomes REALLY easy:


class b(FilterType)
{
   FilterType mySubstream;
}

auto makeB(FilterType)(FilterType f)
{
   return new b!FilterType(f);
}

...

auto myB = myA.myStream.filter!(x => coolCrazyFunction(x)).makeB;

-Steve


Re: auto & class members

2018-05-22 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, May 22, 2018 10:40:55 Robert M. Münch via Digitalmars-d-learn 
wrote:
> This would require one wrap function per different lambda, right?
> Assume I have 50-100 of these. Maybe the myMessage value can be given
> as parameter and with this becomes more like a "filter factory". Not
> sure if this would work.

Pretty much the only time that this sort of thing pops up is when you have
to declare a variable that's a range (or some other similarly generic type)
separately from where it's initialized. I'd expect that your application
would have to be very large to have 50 - 100 instances of that. If you
really were hitting it a lot, then maybe it would make sense to try and
figure out a way to avoid having to declare a wrapper function, but in my
experience, this sort of thing simply doesn't come up all that often. It's
definitely an issue, and occasionally someone will come here and ask how to
deal with it, but I'd be worried if it came up often enough that creating a
wrapper function to deal with it was a problem.

The other way to fix the problem is to just call std.array.array on the
range to get a dynamic array. It does mean allocating, but you run into
fewer problems related to type inference, since you can then easily type
the type rather than having to use type inference to get it.

- Jonathan M Davis




Re: auto & class members

2018-05-22 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, May 22, 2018 10:43:38 Robert M. Münch via Digitalmars-d-learn 
wrote:
> On 2018-05-21 20:17:04 +, Jonathan M Davis said:
> > On Monday, May 21, 2018 16:05:00 Steven Schveighoffer via Digitalmars-d-
> >
> > learn wrote:
> >> Well one thing that seems clear from this example -- we now have
> >> __traits(isSame) to tell if lambdas are the same, but it looks like the
> >> compiler doesn't subscribe to that belief...
> >>
> >> https://run.dlang.io/is/FW3mVq
> >>
> >> We should fix that...
> >
> > Yeah. That part of lambdas has always been a problem. My guess here is
> > that the problem stems from the fact that they're declared in separate
> > scopes, but I don't know. Regardless of the reason for the failure
> > though, that example really needs to work, or most anything that cares
> > about lambdas being the same is going to have problems.
>
> I think that's exactly the problem: I assumed that it's about the
> lambdas and associated types but would have never guessed that names,
> scope etc. play a role as well. Is this somewhere documented? Or at
> least a hint, would help a lot to be aware of this pitfall.

The issue is that you actually have different lambdas. They _look_ the same,
but they aren't actually the same function. The compiler is not good about
recognizing that two lambdas are identical. When Steven said that they had
different names, he meant that it was like if you had declared:

int foo(int i)
{
return i + 42;
}

int bar(int i)
{
return i + 42;
}

Both functions are identical, but the compiler doesn't see that. It just
looks at the signatures - and while everything about them is functionally
equivalent, they have different names. Basically, the compiler is too dumb
to figure out when two lambdas are actually identical. Some work has been
done towards making it that smart, but there is still clearly more work to
be done. As for how well any of this is documented, I don't know, but I
suspect that at most, the spec has a line or two about it somewhere,
especially since it's really not something that was planned for per se. It's
just a natural fallout of how lambdas work and is surprisingly difficult to
fix.

- Jonathan M Davis




Re: auto & class members

2018-05-22 Thread Robert M. Münch via Digitalmars-d-learn

On 2018-05-21 18:55:36 +, Steven Schveighoffer said:

So the issue here is that the lambda function inside myFunc is 
DIFFERENT than the one inside b. They are both the same function, but 
with essentially different names.


Aha... that explains it pretty good.


When you use the alias, both are using the same exact lambda.


Ok. I didn't expect that the name is relevant in this case, instead 
assumed that only the types need to match.



I see you are casting now as well,


Do I? Not that I'm aware of it in my pseudo-code example...


What may make more sense (both for type sanity and for code reuse) is 
to wrap your call to filter into one place so it can be used wherever 
you need it:


auto wrapStream(S)(S str) { return str.filter!(x => x == myMessage); }

class b
{
typeof(wrapStream(a.init.myStream)()) mySubStream;
}

void myFunc() {
a myA = new a;
b myB = new b;
myB.mySubstream = myA.myStream.wrapStream;
}


This would require one wrap function per different lambda, right? 
Assume I have 50-100 of these. Maybe the myMessage value can be given 
as parameter and with this becomes more like a "filter factory". Not 
sure if this would work.


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: auto & class members

2018-05-22 Thread Robert M. Münch via Digitalmars-d-learn

On 2018-05-21 20:17:04 +, Jonathan M Davis said:


On Monday, May 21, 2018 16:05:00 Steven Schveighoffer via Digitalmars-d-
learn wrote:


Well one thing that seems clear from this example -- we now have
__traits(isSame) to tell if lambdas are the same, but it looks like the
compiler doesn't subscribe to that belief...

https://run.dlang.io/is/FW3mVq

We should fix that...


Yeah. That part of lambdas has always been a problem. My guess here is that
the problem stems from the fact that they're declared in separate scopes,
but I don't know. Regardless of the reason for the failure though, that
example really needs to work, or most anything that cares about lambdas
being the same is going to have problems.


I think that's exactly the problem: I assumed that it's about the 
lambdas and associated types but would have never guessed that names, 
scope etc. play a role as well. Is this somewhere documented? Or at 
least a hint, would help a lot to be aware of this pitfall.


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: auto & class members

2018-05-22 Thread Robert M. Münch via Digitalmars-d-learn

On 2018-05-21 18:13:16 +, Ali ‡ehreli said:

Templatized range types work well when they are used as template 
arguments themselves.


When you need to keep a single type like 'b' (i.e. b is not a 
template), and when you need to set a variable like mySubStream to a 
dynamic object, the solution is to use inputObject():

...


Thanks for the good example. The thing in my specific case is, that the 
streams are from a library, so no direct way to change their interface 
or so.


But anyway, the more background about the whole topic, the better.

--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: auto & class members

2018-05-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, May 21, 2018 16:05:00 Steven Schveighoffer via Digitalmars-d-
learn wrote:
> On 5/21/18 3:22 PM, Jonathan M Davis wrote:
> > That's basically what I was suggesting that he do, but I guess that I
> > wasn't clear enough.
>
> Well one thing that seems clear from this example -- we now have
> __traits(isSame) to tell if lambdas are the same, but it looks like the
> compiler doesn't subscribe to that belief...
>
> https://run.dlang.io/is/FW3mVq
>
> We should fix that...

Yeah. That part of lambdas has always been a problem. My guess here is that
the problem stems from the fact that they're declared in separate scopes,
but I don't know. Regardless of the reason for the failure though, that
example really needs to work, or most anything that cares about lambdas
being the same is going to have problems.

- Jonathan M Davis



Re: auto & class members

2018-05-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/21/18 3:22 PM, Jonathan M Davis wrote:


That's basically what I was suggesting that he do, but I guess that I wasn't
clear enough.


Well one thing that seems clear from this example -- we now have 
__traits(isSame) to tell if lambdas are the same, but it looks like the 
compiler doesn't subscribe to that belief...


https://run.dlang.io/is/FW3mVq

We should fix that...

-Steve


Re: auto & class members

2018-05-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, May 21, 2018 11:13:16 Ali Çehreli via Digitalmars-d-learn wrote:
> On 05/20/2018 10:46 AM, Robert M. Münch wrote:
>  > But I still don't understand why I can't write things explicitly but
>  > have to use an alias for this.
>
> Templatized range types work well when they are used as template
> arguments themselves.
>
> When you need to keep a single type like 'b' (i.e. b is not a template),
> and when you need to set a variable like mySubStream to a dynamic
> object, the solution is to use inputObject():
>
> import std.algorithm;
> import std.range;
>
> class a {
>  int[] myStream = [ 1, 2, 42, 100 ];
> }
>
>
> int myMessage = 42;
>
> class b {
>  InputRange!int mySubStream;
> }
>
> void myFunc() {
>  a myA = new a();
>  b myB = new b();
>
>  myB.mySubStream = inputRangeObject(myA.myStream.filter!(x => x ==
> myMessage));
>
>  assert(myB.mySubStream.equal([myMessage]));
> }
>
> void main() {
>  myFunc();
> }
>
> Now, mySubStream is a range variable that satisfies the input range
> interface and produces int elements. (Adjust accordingly.) You can use a
> more specialized range kind other than InputRange if the actual range
> supports it (e.g. ForwardRange!int, etc.):
>
>
> http://ddili.org/ders/d.en/ranges_more.html#ix_ranges_more.inputRangeObjec
> t
>
>https://dlang.org/phobos/std_range_interfaces.html#inputRangeObject

Wow. Someone actually uses those? I don't think that I've ever seen anyone
try except when they didn't understand ranges properly and thought that all
ranges derived from the interfaces in that module. I guess that they would
work in this case, but I think that the normal solution is to use typeof
(though as Robert here found, that can get a bit problematic when lambdas
get involved, whereas your solution here is pretty straightforward).

I'd be _very_ leery of using ForwardRange and the like though, since they're
going to have to allocate on every call to save, which gets expensive, and
far too often, range-based code doesn't call save correctly, meaning that
you'll often hit bugs using a forward range that's a class. Phobos is a
_lot_ better about it than it used to be, but I expect that there are still
a few such lingering bugs in there, and I'd expect the average range-based
code to screw it up. Really, the only way to get it right is to actually
test your code with reference type ranges.

If all you're using is a basic input range, then those interfaces just cost
you the one allocation and should be fine, but beyond that, I wouldn't
suggest using them if you can reasonably avoid it. And personally, I'd just
use Steven's solution of using a wrapper function so that you can ensure
that there's really only one lambda type involved, and typeof then works.

- Jonathan M Davis




Re: auto & class members

2018-05-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, May 21, 2018 14:55:36 Steven Schveighoffer via Digitalmars-d-
learn wrote:
> On 5/20/18 1:46 PM, Robert M. Münch wrote:
> > On 2018-05-20 17:40:39 +, Robert M. Münch said:
> >> Hi Jonathan, great! This got me a step further. So I can declare my
> >> member now. But I get an implict cast error when I try:
> >>
> >> class a {
> >> ... myStream;
> >> }
> >>
> >> class b {
> >> typeof(a.myStream.filter!(x => x == myMessage)) mySubStream;
> >> }
> >>
> >> void myFunc() {
> >> a myA = new a();
> >> b myB = new b();
> >>
> >> myB.mySubstream = myA.myStream.filter!(x => x == myMessage);
> >> }
> >>
> >> This gives (unnecessary stuff stripped):
> >>
> >> Error: cannot implicitly convert expression filter(...) of type
> >> app.myFunc.filter!(x => x == myMessage) to app.b.filter!(x => x ==
> >> myMessage)
> >
> > Answering myself: Using an alias helps.
> >
> > alias typeof(a.myStream.filter!(x => x == myMessage)) myMessageType;
>
> So the issue here is that the lambda function inside myFunc is DIFFERENT
> than the one inside b. They are both the same function, but with
> essentially different names.
>
> When you use the alias, both are using the same exact lambda.
>
> I see you are casting now as well, which looks horrible to me -- if you
> change something in your lambda now you are in for some trouble.
>
> What may make more sense (both for type sanity and for code reuse) is to
> wrap your call to filter into one place so it can be used wherever you
> need it:
>
> auto wrapStream(S)(S str) { return str.filter!(x => x == myMessage); }
>
> class b
> {
> typeof(wrapStream(a.init.myStream)()) mySubStream;
> }
>
> void myFunc() {
> a myA = new a;
> b myB = new b;
> myB.mySubstream = myA.myStream.wrapStream;
> }

That's basically what I was suggesting that he do, but I guess that I wasn't
clear enough.

- Jonathan M Davis




Re: auto & class members

2018-05-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/20/18 1:46 PM, Robert M. Münch wrote:

On 2018-05-20 17:40:39 +, Robert M. Münch said:

Hi Jonathan, great! This got me a step further. So I can declare my 
member now. But I get an implict cast error when I try:


class a {
... myStream;
}

class b {
typeof(a.myStream.filter!(x => x == myMessage)) mySubStream;
}

void myFunc() {
a myA = new a();
b myB = new b();

myB.mySubstream = myA.myStream.filter!(x => x == myMessage);
}

This gives (unnecessary stuff stripped):

Error: cannot implicitly convert expression filter(...) of type 
app.myFunc.filter!(x => x == myMessage) to app.b.filter!(x => x == 
myMessage)


Answering myself: Using an alias helps.

alias typeof(a.myStream.filter!(x => x == myMessage)) myMessageType;


So the issue here is that the lambda function inside myFunc is DIFFERENT 
than the one inside b. They are both the same function, but with 
essentially different names.


When you use the alias, both are using the same exact lambda.

I see you are casting now as well, which looks horrible to me -- if you 
change something in your lambda now you are in for some trouble.


What may make more sense (both for type sanity and for code reuse) is to 
wrap your call to filter into one place so it can be used wherever you 
need it:


auto wrapStream(S)(S str) { return str.filter!(x => x == myMessage); }

class b
{
   typeof(wrapStream(a.init.myStream)()) mySubStream;
}

void myFunc() {
   a myA = new a;
   b myB = new b;
   myB.mySubstream = myA.myStream.wrapStream;
}

-Steve


Re: auto & class members

2018-05-21 Thread Ali Çehreli via Digitalmars-d-learn

On 05/20/2018 10:46 AM, Robert M. Münch wrote:

> But I still don't understand why I can't write things explicitly but
> have to use an alias for this.

Templatized range types work well when they are used as template 
arguments themselves.


When you need to keep a single type like 'b' (i.e. b is not a template), 
and when you need to set a variable like mySubStream to a dynamic 
object, the solution is to use inputObject():


import std.algorithm;
import std.range;

class a {
int[] myStream = [ 1, 2, 42, 100 ];
}


int myMessage = 42;

class b {
InputRange!int mySubStream;
}

void myFunc() {
a myA = new a();
b myB = new b();

myB.mySubStream = inputRangeObject(myA.myStream.filter!(x => x == 
myMessage));


assert(myB.mySubStream.equal([myMessage]));
}

void main() {
myFunc();
}

Now, mySubStream is a range variable that satisfies the input range 
interface and produces int elements. (Adjust accordingly.) You can use a 
more specialized range kind other than InputRange if the actual range 
supports it (e.g. ForwardRange!int, etc.):



http://ddili.org/ders/d.en/ranges_more.html#ix_ranges_more.inputRangeObject

  https://dlang.org/phobos/std_range_interfaces.html#inputRangeObject

Ali



Re: auto & class members

2018-05-20 Thread Robert M. Münch via Digitalmars-d-learn

On 2018-05-20 17:40:39 +, Robert M. Münch said:

Hi Jonathan, great! This got me a step further. So I can declare my 
member now. But I get an implict cast error when I try:


class a {
... myStream;
}

class b {
typeof(a.myStream.filter!(x => x == myMessage)) mySubStream;
}

void myFunc() {
a myA = new a();
b myB = new b();

myB.mySubstream = myA.myStream.filter!(x => x == myMessage);
}

This gives (unnecessary stuff stripped):

Error: cannot implicitly convert expression filter(...) of type 
app.myFunc.filter!(x => x == myMessage) to app.b.filter!(x => x == 
myMessage)


Answering myself: Using an alias helps.

alias typeof(a.myStream.filter!(x => x == myMessage)) myMessageType;

class b {
myMessageType mySubStream;
}

void myFunc() {
a myA = new a();
b myB = new b();

	myB.mySubstream = cast(myMessageType)myA.myStream.filter!(x => x == 
myMessage);

}

But I still don't understand why I can't write things explicitly but 
have to use an alias for this.


--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: auto & class members

2018-05-20 Thread Robert M. Münch via Digitalmars-d-learn

On 2018-05-20 14:49:59 +, Jonathan M Davis said:


In cases like this, typeof is your friend. e.g. something like

typeof(myStream.filter!(a => a == myMessage)) mySubStream;


Hi Jonathan, great! This got me a step further. So I can declare my 
member now. But I get an implict cast error when I try:


class a {
... myStream;
}

class b {
typeof(a.myStream.filter!(x => x == myMessage)) mySubStream;
}

void myFunc() {
a myA = new a();
b myB = new b();

myB.mySubstream = myA.myStream.filter!(x => x == myMessage);
}

This gives (unnecessary stuff stripped):

Error: cannot implicitly convert expression filter(...) of type 
app.myFunc.filter!(x => x == myMessage) to app.b.filter!(x => x == 
myMessage)


Why is myFunc now entering the game? I mean it's just the function 
containing the code. It seems that:


typeof(myA.myStream.filter!(x => x == myMessage))

and

typeof(a.myStream.filter!(x => x == myMessage)) are not the same.

But inside class b I can't use a specific variable instance. And in 
myFunc, I can't use a class type but need the specific instance.


Any further idea?



though you might have trouble with the lambda being subtly different type
even if you replace myMessage in it with something that will work in the
scope that mySubStream is being declared.


Not sure if the above problem is exactly what you mention here. This is 
all pretty tricky.




However, that could be fixed by
doing something like replacing the lambda with a free function or just
creating a function that returns what you want to assign to mySubStream.
Then you could just do something like

typeof(myHelperFunc(myStream)) mySubStream;

The exact solution can get a bit annoying in cases like this (it's arguably
the biggest downside to auto returns), but typeof does provide a way out if
you can get the expression to it to work. It is easier with local variables
than member variables though, since you don't necessarily have everything
you want to use in the expression that will give the variable its value
available at the point that the variable is declared - but that's why
a helper function can help, since it provides a way to encapsulate the
expression and reuse it between the assignment and the declaration.


Not sure I understand every aspect but it's getting clearer... Thanks so far.

--
Robert M. Münch
http://www.saphirion.com
smarter | better | faster



Re: auto & class members

2018-05-20 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 20, 2018 16:30:10 Robert M. Münch via Digitalmars-d-learn 
wrote:
> I use the D RX lib [1] and can create a filtered stream using the auto
> keyword:
>
> struct a {
>   SubjectObject!myType myStream;
>   ??? mySubStream;
> }
>
> void myfunc(){
>   a myA = new a();
>
>   auto mySubStream = a.myStream.filter!(a => a == myMessage);
>   ...
> }
>
> The problem is, that I don't find out what the type of mySubStream is,
> which I would like to make a member of the struct, so that I can
> reference it outside the function too.
>
> How can I find out the type of an auto? This here seems to be a pretty
> complicated templated, nested type, whatever result.
>
> [1] https://github.com/lempiji/rx

In cases like this, typeof is your friend. e.g. something like

typeof(myStream.filter!(a => a == myMessage)) mySubStream;

though you might have trouble with the lambda being subtly different type
even if you replace myMessage in it with something that will work in the
scope that mySubStream is being declared. However, that could be fixed by
doing something like replacing the lambda with a free function or just
creating a function that returns what you want to assign to mySubStream.
Then you could just do something like

typeof(myHelperFunc(myStream)) mySubStream;

The exact solution can get a bit annoying in cases like this (it's arguably
the biggest downside to auto returns), but typeof does provide a way out if
you can get the expression to it to work. It is easier with local variables
than member variables though, since you don't necessarily have everything
you want to use in the expression that will give the variable its value
available at the point that the variable is declared - but that's why
a helper function can help, since it provides a way to encapsulate the
expression and reuse it between the assignment and the declaration.

- Jonathan M Davis




Re: Auto expiring cache library

2018-04-27 Thread Jack Stouffer via Digitalmars-d-learn

On Friday, 27 April 2018 at 09:07:31 UTC, Pasqui23 wrote:
I want a library that offers an in-memory data structure,such 
that I can write,for example:


cache.insert(key,value,expiry)

and I can retrieve the value with something like 
cache[key],unless it has passed expiry seconds.


Can be done?What library should I use?


Memcached


Re: auto-decoding

2018-04-01 Thread Seb via Digitalmars-d-learn

On Sunday, 1 April 2018 at 02:44:32 UTC, Uknown wrote:
If you want to stop auto-decoding, you can use 
std.string.representation like this:


import std.string : representation;
auto no_decode = some_string.representation;

Now no_decode wont be auto-decoded, and you can use it in place 
of some_string. You can also use std.utf to decode by graphemes 
instead.


.representation gives you an const(ubyte)[]

What you typically want is const(char)[], for this you can use 
std.utf.byCodeUnit


https://dlang.org/phobos/std_utf.html#byCodeUnit

There's also this good article:

https://tour.dlang.org/tour/en/gems/unicode


Re: auto-decoding

2018-03-31 Thread Uknown via Digitalmars-d-learn

On Sunday, 1 April 2018 at 01:19:08 UTC, auto wrote:

What is auto decoding and why it is a problem?


Auto-decoding is essentially related to UTF representation of 
Unicode strings. In D, `char[]` and `string` represent UTF8 
strings, `wchar[]` and `wstring` represent UTF16 strings and 
`dchar[]` and `dstring` represent UTF32 strings. You need to know 
how UFT works in order to understand auto-decoding. Since in 
practice most code deals with UTF8 I'll explain wrt that. 
Essentially, the problem comes down to the fact that not all the 
Unicode characters are representable by 8 bit `char`s (for UTF8). 
Only the ASCII stuff is represented by the "normal" way. UTF8 
uses the fact that the first few buts in a char are never used in 
ASCII, to tell how many more `char`s ahead that character is 
encoded in. You can watch this video for a better 
understanding[0]. By default though, if one were to traverse a 
`char` looking for characters, they would get unexpected results 
with Unicode data


Auto-decoding tries to solve this by automatically applying the 
algorithm to decode the characters to Unicode "Code-Points". This 
is where my knowledge ends though. I'll give you pros and cons of 
auto-decoding.


Pros:
 * It makes Unicode string handeling much more easier for 
beginners.

 * Much less effort in general, it seems to "just work™"

Cons:
 * It makes string handling slow by default
 * It may be the wrong thing, since you may not want Unicode 
code-points, but graphemes instead.
 * Auto-decoding throws exceptions on reaching invalid 
code-points, so all string

handling code in general throws exceptions.

If you want to stop auto-decoding, you can use 
std.string.representation like this:


import std.string : representation;
auto no_decode = some_string.representation;

Now no_decode wont be auto-decoded, and you can use it in place 
of some_string. You can also use std.utf to decode by graphemes 
instead.


You should also read this blog post: 
https://jackstouffer.com/blog/d_auto_decoding_and_you.html


And this forum post: 
https://forum.dlang.org/post/eozguhavggchzzruz...@forum.dlang.org


[0]: https://www.youtube.com/watch?v=MijmeoH9LT4


Re: Auto-decoding

2017-07-15 Thread Seb via Digitalmars-d-learn

On Saturday, 15 July 2017 at 18:47:25 UTC, Joakim wrote:

On Saturday, 15 July 2017 at 18:14:48 UTC, aberba wrote:

So what is the current plan? :)


Andrei has talked about having a non-auto-decoding path for 
those who know what they're doing and actively choose that 
path, while keeping auto-decoding the default, so as not to 
break existing code.  Jack has been submitting PRs for this, 
but it is probably tedious work, so progress is slow and I 
don't know how much more remains to be done:


https://github.com/dlang/phobos/pulls?q=is%3Apr+auto-decoding+is%3Aclosed


The idea is that once DIP1000 has matured, more focus on compiler 
support for reference-counting will be given with the aim of 
improving the @nogc experience. One example is DIP1008 for @nogc 
exceptions [1], but another one that is important in this context 
is RCString [2]. The idea is that RCString will be a new opt-in 
string type without auto-decoding and GC.


Another idea in the game is `version(NoAutoDecode)`:

https://github.com/dlang/phobos/pull/5513

However, here's unfortunately still unclear whether that could 
result in a working solution.


[1] https://github.com/dlang/DIPs/blob/master/DIPs/DIP1008.md
[2] https://github.com/dlang/phobos/pull/4878


Re: Auto-decoding

2017-07-15 Thread Joakim via Digitalmars-d-learn

On Saturday, 15 July 2017 at 18:14:48 UTC, aberba wrote:

On Saturday, 15 July 2017 at 05:54:32 UTC, ag0aep6g wrote:

On 07/15/2017 06:21 AM, bauss wrote:

[...]


1) Drop two elements from "Bär". With auto-decoding you get 
"r", which is nice. Without auto-decoding you get [0xA4, 'r'] 
where 0xA4 is the second half of the encoding of 'ä'. You have 
to know your Unicode to understand what is going on there.


[...]


So what is the current plan? :)


Andrei has talked about having a non-auto-decoding path for those 
who know what they're doing and actively choose that path, while 
keeping auto-decoding the default, so as not to break existing 
code.  Jack has been submitting PRs for this, but it is probably 
tedious work, so progress is slow and I don't know how much more 
remains to be done:


https://github.com/dlang/phobos/pulls?q=is%3Apr+auto-decoding+is%3Aclosed


Re: Auto-decoding

2017-07-15 Thread ag0aep6g via Digitalmars-d-learn

On 07/15/2017 08:14 PM, aberba wrote:

So what is the current plan? :)


As far as I'm aware, there's no concrete plan to change anything. We 
just gotta deal with auto-decoding for the time being.


Re: Auto-decoding

2017-07-15 Thread aberba via Digitalmars-d-learn

On Saturday, 15 July 2017 at 05:54:32 UTC, ag0aep6g wrote:

On 07/15/2017 06:21 AM, bauss wrote:

[...]


1) Drop two elements from "Bär". With auto-decoding you get 
"r", which is nice. Without auto-decoding you get [0xA4, 'r'] 
where 0xA4 is the second half of the encoding of 'ä'. You have 
to know your Unicode to understand what is going on there.


[...]


So what is the current plan? :)


Re: Auto-decoding

2017-07-14 Thread ag0aep6g via Digitalmars-d-learn

On 07/15/2017 06:21 AM, bauss wrote:
I understand what it is and how it works, but I don't understand 
anything of how it solves any problems?


Could someone give an example of when auto-decoding actually is useful 
in contrast to not using it?


1) Drop two elements from "Bär". With auto-decoding you get "r", which 
is nice. Without auto-decoding you get [0xA4, 'r'] where 0xA4 is the 
second half of the encoding of 'ä'. You have to know your Unicode to 
understand what is going on there.


2) Search for 'ä' (one wchar/dchar) in the `string` "Bär". With 
auto-decoding, you pop the 'B' and then there's your 'ä'. Without 
auto-decoding, you can't find 'ä', because "Bär" doesn't have a single 
element that matches 'ä'. You have to search for "ä" (two `char`s) instead.


The goal of auto-decoding was to make it so that you don't have to think 
about Unicode all the time when processing strings. Instead you could 
think in terms of "characters". But auto-decoding falls flat on that 
goal, which is why it's disliked. You still have to think about Unicode 
stuff for correctness (combining characters, graphemes), and now you 
also have to worry about the performance of auto-decoding.


Re: Auto recursive function

2017-01-12 Thread thedeemon via Digitalmars-d-learn

On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu wrote:

Hi,

I am currently trying to create a function 
makeMultidimensionalArray which allocates memory for a 
multidimensional array.


You were very close to the answer:

auto makeMultidimensionalArray(int N, T, Allocator)(auto ref 
Allocator alloc, size_t[N] lengths)

{
static if (lengths.length == 1)
{
return makeArray!T(alloc, lengths[0]);
}
else
{
alias E = typeof(makeMultidimensionalArray!(N-1,T)(alloc, 
lengths[1..$]));

auto ret = makeArray!E(alloc, lengths[0]);
foreach (ref e; ret)
e = makeMultidimensionalArray!(N-1, T)(alloc, 
lengths[1..$]);

return ret;
}
}


The key point is that return type depends on length of "lengths" 
array (dimensionality), so if this length is only known at 
runtime this is a dependent type, something D lacks (you'll need 
Idris or Agda for those). In D return type must be known at 
compile time and hence the length of "lengths" must be a compile 
time argument. With such argument everything compiles smoothly.


Re: Auto recursive function

2017-01-12 Thread Bauss via Digitalmars-d-learn

On Thursday, 12 January 2017 at 00:30:33 UTC, Ignacious wrote:
On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu 
wrote:

[...]



If you change the return type to a void* your code basically 
works.



void* makeMultidimensionalArray(T, Allocator)(auto ref 
Allocator alloc, size_t[] lengths)

{
if (lengths.length == 1)
{
int x = 0x01FEEF01;
return cast(void*)makeArray!T(alloc, lengths[0], x);
}
else
{
alias E = typeof(makeMultidimensionalArray!T(alloc, 
lengths[1..$]));


auto ret = makeArray!E(alloc, lengths[0]);
foreach (ref e; ret)
e = makeMultidimensionalArray!T(alloc, 
lengths[1..$]);

return cast(void*)ret;
}
}

The problem is that then you need to cast back and that 
essentially results in the original problem. Can be done but 
probably gonna have to use string mixins.


That isn't a solution and will probably introduce other bugs.

As soon as you have to result to using void* is an indication of 
bad design IMO, because it leads to very unsafe possibilities.


Re: Auto recursive function

2017-01-11 Thread Ignacious via Digitalmars-d-learn

On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu wrote:

Hi,

I am currently trying to create a function 
makeMultidimensionalArray which allocates memory for a 
multidimensional array. It is very similar with [1],

the difference being that it is uninitialized. Here is the code:

auto makeMultidimensionalArray(T, Allocator)(auto ref Allocator 
alloc, size_t[] lengths)

{
if (lengths.length == 1)
{
return makeArray!T(alloc, lengths[0]);
}
else
{
alias E = typeof(makeMultidimensionalArray!T(alloc, 
lengths[1..$]));

auto ret = makeArray!E(alloc, lengths[0]);
foreach (ref e; ret)
e = makeMultidimensionalArray!T(alloc, 
lengths[1..$]);

return ret;
}
}

The lengths[] specifies the lengths for each dimension. The 
problem with this code is that auto is going to be evaluated to 
T[] for the first time and when it
recurs, creating T[][] I get the error "mismatched function 
return type inference of T[][] and T[]". Is there a way to 
surpass that? I saw that in [1]
the recursive call is done by prefixing the function name with 
a '.'; I tried that but it doesn't work. I must be missing 
something, any ideas?


Thanks,
RazvanN

[1] 
https://github.com/dlang/phobos/blob/master/std/experimental/ndslice/slice.d#L834



If you change the return type to a void* your code basically 
works.



void* makeMultidimensionalArray(T, Allocator)(auto ref Allocator 
alloc, size_t[] lengths)

{
if (lengths.length == 1)
{
int x = 0x01FEEF01;
return cast(void*)makeArray!T(alloc, lengths[0], x);
}
else
{
alias E = typeof(makeMultidimensionalArray!T(alloc, 
lengths[1..$]));


auto ret = makeArray!E(alloc, lengths[0]);
foreach (ref e; ret)
e = makeMultidimensionalArray!T(alloc, lengths[1..$]);
return cast(void*)ret;
}
}

The problem is that then you need to cast back and that 
essentially results in the original problem. Can be done but 
probably gonna have to use string mixins.


Re: Auto recursive function

2017-01-11 Thread Ignacious via Digitalmars-d-learn

On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu wrote:

Hi,

I am currently trying to create a function 
makeMultidimensionalArray which allocates memory for a 
multidimensional array. It is very similar with [1],

the difference being that it is uninitialized. Here is the code:

auto makeMultidimensionalArray(T, Allocator)(auto ref Allocator 
alloc, size_t[] lengths)

{
if (lengths.length == 1)
{
return makeArray!T(alloc, lengths[0]);
}
else
{
alias E = typeof(makeMultidimensionalArray!T(alloc, 
lengths[1..$]));

auto ret = makeArray!E(alloc, lengths[0]);
foreach (ref e; ret)
e = makeMultidimensionalArray!T(alloc, 
lengths[1..$]);

return ret;
}
}

The lengths[] specifies the lengths for each dimension. The 
problem with this code is that auto is going to be evaluated to 
T[] for the first time and when it
recurs, creating T[][] I get the error "mismatched function 
return type inference of T[][] and T[]". Is there a way to 
surpass that? I saw that in [1]
the recursive call is done by prefixing the function name with 
a '.'; I tried that but it doesn't work. I must be missing 
something, any ideas?


Thanks,
RazvanN

[1] 
https://github.com/dlang/phobos/blob/master/std/experimental/ndslice/slice.d#L834



This is probably not possible. You are trying to have multiple 
return types for the same function. You are thinking that each 
recursive call is a new template but that doesn't seem to be the 
case.



Instead, maybe try using string mixins to generate the 
allocations. Should be quite easy and will work.


You could also try to use a helper function that you pass the 
fully declared array(all dimensions) and the helper function then 
allocates each dimension recursively... The difference is that 
you are not passing around/returning sub-arrays so you don't have 
to worry about type mismatches.








Re: Auto recursive function

2017-01-11 Thread Martin Nowak via Digitalmars-d-learn

On Wednesday, 11 January 2017 at 19:39:17 UTC, Ali Çehreli wrote:
return choose(lengths.length == 1, one!T(alloc, 
lengths[0]), two!T(alloc, lengths));


Well, choose is the right tool when the choice can only be made 
at runtime. That would be uncommon for dimensionality.


Anyhow mentioning ndslice for multi-dim seems like the sanest tip 
here.

https://github.com/libmir/mir


Re: Auto recursive function

2017-01-11 Thread Razvan Nitu via Digitalmars-d-learn

On Wednesday, 11 January 2017 at 19:30:05 UTC, Stefan Koch wrote:
On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu 
wrote:

Hi,

I am currently trying to create a function 
makeMultidimensionalArray which allocates memory for a 
multidimensional array. It is very similar with [1],
the difference being that it is uninitialized. Here is the 
code:


[...]


I believe you should not do this with recursion.
Because that'll instantiate the template multiple times with 
different types.

What is wrong with using ndslice here ?


Maybe you want to allocate memory for more complex data 
structures;
Using the function I am implementing, you will have the 
multidimensional
array initialized with the default values; you don't have to pass 
a slice

from which the initialization data is taken.


Re: Auto recursive function

2017-01-11 Thread Ali Çehreli via Digitalmars-d-learn

On 01/11/2017 11:30 AM, Stefan Koch wrote:

On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu wrote:

Hi,

I am currently trying to create a function makeMultidimensionalArray
which allocates memory for a multidimensional array. It is very
similar with [1],
the difference being that it is uninitialized. Here is the code:

[...]


I believe you should not do this with recursion.
Because that'll instantiate the template multiple times with different
types.
What is wrong with using ndslice here ?



Agreed but the question is still valid. I had similar cases before where 
std.range.choose looked like a solution but did not work. Here's my 
current attempt, which fails:


import std.stdio;
import std.experimental.allocator.gc_allocator;
import std.experimental.allocator;

auto one(T, Allocator)(auto ref Allocator alloc, size_t length) {
return makeArray!T(alloc, length);
}

auto two(T, Allocator)(auto ref Allocator alloc, size_t[] lengths) {


// Error: forward reference to inferred return type of function call 
'makeMultidimensionalArray!int(alloc, lengths[1..__dollar])'



alias E = typeof(makeMultidimensionalArray!T(alloc, lengths[1..$]));
auto ret = makeArray!E(alloc, lengths[0]);
foreach (ref e; ret)
e = makeMultidimensionalArray!T(alloc, lengths[1..$]);
return ret;
}

auto makeMultidimensionalArray(T, Allocator)(auto ref Allocator alloc, 
size_t[] lengths)

{
import std.range: choose;

return choose(lengths.length == 1, one!T(alloc, lengths[0]), 
two!T(alloc, lengths));

}

void main() {
writeln(makeMultidimensionalArray!int(GCAllocator.instance, [3, 4]));
}

Ali



Re: Auto recursive function

2017-01-11 Thread Martin Nowak via Digitalmars-d-learn

On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu wrote:
auto makeMultidimensionalArray(T, Allocator)(auto ref Allocator 
alloc, size_t[] lengths)

{
if (lengths.length == 1)


Looks like `static if` would fix your specific problem.



Re: Auto recursive function

2017-01-11 Thread Stefan Koch via Digitalmars-d-learn

On Wednesday, 11 January 2017 at 19:23:10 UTC, Razvan Nitu wrote:

Hi,

I am currently trying to create a function 
makeMultidimensionalArray which allocates memory for a 
multidimensional array. It is very similar with [1],

the difference being that it is uninitialized. Here is the code:

[...]


I believe you should not do this with recursion.
Because that'll instantiate the template multiple times with 
different types.

What is wrong with using ndslice here ?



Re: Auto field member?

2016-03-02 Thread Rikki Cattermole via Digitalmars-d-learn

On 02/03/16 3:50 PM, Hanh wrote:

Hi,

Is there a way to declare a class field 'auto'? I have a problem when I
try to 'promote' a variable to a field.

import std.csv;
import std.typecons;

class Test {
 this() {
 auto text = "Joe,Carpenter,30\nFred,Blacksmith,40\r\n";
 auto reader = csvReader!(Tuple!(string, string,
int))(text); // how to make this a field?
 }
}

csvReader returns a private type so I can't specify the type explicitly.

Thanks,
--h


You have two options.
a) parse and store into your own data structure.
b) use std.traits ReturnType to get the type to declare.



Re: Auto ref function : How is this possible ?

2015-04-15 Thread Ali Çehreli via Digitalmars-d-learn

On 04/15/2015 10:50 AM, Ali Çehreli wrote:


pragma(msg) has been added to Programming in D but it is not available
online yet:



Sorry for the spam :( but apparently it is already online:

  http://ddili.org/ders/d.en/templates.html#ix_templates.pragma

Ali



Re: Auto ref function : How is this possible ?

2015-04-15 Thread Ali Çehreli via Digitalmars-d-learn

On 04/13/2015 07:44 AM, matovitch wrote:

Thanks for the tip ! I was looking at something like this.


pragma(msg) has been added to Programming in D but it is not available 
online yet:



https://bitbucket.org/acehreli/ddili/src/ae49747a850fabc3a3e66dcdb3626a991c53632e/src/ders/d.en/templates.d?at=master#cl-696

Ali



Re: Auto ref function : How is this possible ?

2015-04-13 Thread matovitch via Digitalmars-d-learn

Thanks for the tip ! I was looking at something like this.


Re: Auto ref function : How is this possible ?

2015-04-13 Thread Steven Schveighoffer via Digitalmars-d-learn

On 4/11/15 6:08 AM, matovitch wrote:

Hi,

I just learn about auto ref functions and tried this :

import std.stdio;

auto ref foo(int i, ref float f)
{
  if (i  f)
  {
  return i;
  }
  else
  {
  return f;
  }
}

void main()
{
  int i = 1;
  float f1 = 1.1;
  float f2 = 0.9;
  writeln(foo(i, f1));
  writeln(foo(i, f2));
}

Tricky questions : Does it compiles ? If yes what does it do ?
Then my question : How is this possible ?


D has great compile-time tools to examine what the compiler is doing.

A great feature of D for investigating compiler internals is pragma(msg, 
...). This prints at compile time some message (a string) that is based 
on the state at the time. For example:


void main()
{
 int i = 1;
 float f1 = 1.1;
 float f2 = 0.9;
 pragma(msg, typeof(foo(i, f1)).stringof); // prints what type 
foo returns

 auto x = foo(i, f2);
 pragma(msg, typeof(x).stringof); // same thing, but easier to 
understand.

}

result (prints while compiling):

float
float

-Steve


Re: Auto ref function : How is this possible ?

2015-04-11 Thread matovitch via Digitalmars-d-learn
In fact I am now thinking it's great...I tried with string 
instead of float and got a clear error message. I should have 
read the spec more thoroughly.


Re: Auto ref function : How is this possible ?

2015-04-11 Thread matovitch via Digitalmars-d-learn

(you can remove the ref stuff)


Re: Auto ref function : How is this possible ?

2015-04-11 Thread matovitch via Digitalmars-d-learn
Ok this explain it : 
http://dlang.org/function.html#auto-functions. It should return a 
float.


Re: auto function attributes based on type

2015-03-12 Thread ketmar via Digitalmars-d-learn
On Thu, 12 Mar 2015 04:51:40 +, amber wrote:

 On Thursday, 12 March 2015 at 04:04:28 UTC, weaselcat wrote:
 On Thursday, 12 March 2015 at 03:12:15 UTC, amber wrote:
 ...
 http://dlang.org/function.html#function-attribute-inference might be a
 good read if you haven't read it already.
 
 I did read it but didn't really understand it, so I've come to D.learn
 for more help.
 
 I think it means I can just write the function like so:
 
 struct S(T) {
  someFunc(int i) {// impl}
 }
 
 and if possible it will be pure, nothrow, @safe and @nogc.

yes. all templated functions (and `someFunc()` is templated due to `S` 
being templated) are subjects of attribute inference. due to this fact 
people sometimes writing even free functions as argument-less templates,

  void freeFunc() (...) { ... }

so compiler will infer attributes for `freeFunc()`. this has almost no 
cost, as compiler will merge all produced templates into one.

signature.asc
Description: PGP signature


Re: auto function attributes based on type

2015-03-12 Thread weaselcat via Digitalmars-d-learn

On Thursday, 12 March 2015 at 05:01:50 UTC, amber wrote:

On Thursday, 12 March 2015 at 04:51:42 UTC, amber wrote:

On Thursday, 12 March 2015 at 04:04:28 UTC, weaselcat wrote:

On Thursday, 12 March 2015 at 03:12:15 UTC, amber wrote:

...
http://dlang.org/function.html#function-attribute-inference 
might be a good read if you haven't read it already.


I did read it but didn't really understand it, so I've come to 
D.learn for more help.


I think it means I can just write the function like so:

struct S(T) {
   someFunc(int i) {// impl}
}

and if possible it will be pure, nothrow, @safe and @nogc.



thanks,
amber


This works nicely after checking with 
__traits(getFunctionAttributes, S!T.someFunc)


Very cool :)

bye,
amber


You can also use the __PRETTY_FUNCTION__ keyword to display 
information about a function.

http://dlang.org/traits.html#specialkeywords


Re: auto function attributes based on type

2015-03-11 Thread weaselcat via Digitalmars-d-learn

On Thursday, 12 March 2015 at 03:12:15 UTC, amber wrote:

...
http://dlang.org/function.html#function-attribute-inference might 
be a good read if you haven't read it already.


Re: auto function attributes based on type

2015-03-11 Thread amber via Digitalmars-d-learn

On Thursday, 12 March 2015 at 04:04:28 UTC, weaselcat wrote:

On Thursday, 12 March 2015 at 03:12:15 UTC, amber wrote:

...
http://dlang.org/function.html#function-attribute-inference 
might be a good read if you haven't read it already.


I did read it but didn't really understand it, so I've come to 
D.learn for more help.


I think it means I can just write the function like so:

struct S(T) {
someFunc(int i) {// impl}
}

and if possible it will be pure, nothrow, @safe and @nogc.



thanks,
amber


Re: auto function attributes based on type

2015-03-11 Thread amber via Digitalmars-d-learn

On Thursday, 12 March 2015 at 04:51:42 UTC, amber wrote:

On Thursday, 12 March 2015 at 04:04:28 UTC, weaselcat wrote:

On Thursday, 12 March 2015 at 03:12:15 UTC, amber wrote:

...
http://dlang.org/function.html#function-attribute-inference 
might be a good read if you haven't read it already.


I did read it but didn't really understand it, so I've come to 
D.learn for more help.


I think it means I can just write the function like so:

struct S(T) {
someFunc(int i) {// impl}
}

and if possible it will be pure, nothrow, @safe and @nogc.



thanks,
amber


This works nicely after checking with 
__traits(getFunctionAttributes, S!T.someFunc)


Very cool :)

bye,
amber





Re: Auto-add static field when inherit // mixins, templates?

2014-08-22 Thread Chris Nicholson-Sauls via Digitalmars-d-learn


class A
{
string getName(this Klass)()
{
return Klass.stringof;
}
}


class B : A
{}


void main()
{
import std.stdio;

auto a = new A;
auto b = new B;
writeln(a.getName());
writeln(b.getName());
}

##

This is about as close as you're going to get without some 
hackery.


Re: Auto-add static field when inherit // mixins, templates?

2014-08-21 Thread MarisaLovesUsAll via Digitalmars-d-learn
I found a rough solution. It's not ideal and I still want to make 
autoinject, but it works.


mixin template Manager(T) {};
class Component {};
class Sprite:Component
{
mixin Manager!Sprite;
};


1) How to make mixin inject automatic?
2) If it's impossible, how to use mixin Manager; without 
!Sprite ?

mixin template Manager(this T) {}; isn't working.

Regards, Alex

On Thursday, 21 August 2014 at 09:38:13 UTC, MarisaLovesUsAll 
wrote:
tl;dr - how to get child classname from inherited parent 
function at compile time?

class A { string getName(); };
class B { };
B foo = new B;
assert(foo.getName() == B);
...

Hi! I'm stuck at one issue, and I don't know how to solve it. I 
think this is about mixins/templates, isn't it?
When inherit from base class Component, I need to auto-create 
child own static fields with child type.

It should look like this, after compilation:

class Component
{
//it doesn't matter to have any fields here
//but it's important to be able to create an instance of 
Component
//and when inherit, all childs will get their own static T 
list; where T is a type of child.

};
class Sprite:Component
{
static Sprite list; //auto-added
static void fun() { } //auto-added, operates with Sprite
}
class Camera:Component
{
static Camera list; //auto-added
static void fun() { } //auto-added, operates with Camera 
instead of Sprite

}
...
//so this must be correct:
Component foo;
Sprite bar;
void foobar(Component one) { }
foobar(Sprite);
...

Sorry for bad English.
Best regards, Alex


Re: Auto-add static field when inherit // mixins, templates?

2014-08-21 Thread anonymous via Digitalmars-d-learn

On Thursday, 21 August 2014 at 12:58:13 UTC, MarisaLovesUsAll
wrote:
I found a rough solution. It's not ideal and I still want to 
make autoinject, but it works.


mixin template Manager(T) {};
class Component {};
class Sprite:Component
{
mixin Manager!Sprite;
};


1) How to make mixin inject automatic?


You could use this pattern:

interface Component {}
class ComponentImpl(T) {}
class Sprite : ComponentImpl!Sprite {}

It's not 100% automatic, but the duplication of Sprite is in
the same line. And it's not as easy to forget as a mixin,
especially when Component does declare methods that ComponentImpl
implements.

2) If it's impossible, how to use mixin Manager; without 
!Sprite ?

mixin template Manager(this T) {}; isn't working.


You can use `typeof(this)` in Manager:

mixin template Manager()
{
 void someMethod(typeof(this) otherInstance) {}
}


Re: Auto-add static field when inherit // mixins, templates?

2014-08-21 Thread MarisaLovesUsAll via Digitalmars-d-learn

On Thursday, 21 August 2014 at 13:19:06 UTC, anonymous wrote:

1) How to make mixin inject automatic?


You could use this pattern:

interface Component {}
class ComponentImpl(T) {}
class Sprite : ComponentImpl!Sprite {}

From my view, it's an architectural crutch. %)


You can use `typeof(this)` in Manager:

mixin template Manager()
{
 void someMethod(typeof(this) otherInstance) {}
}

Thanks, it works.

...I also have more questions %)

When I make mixin injection in one class, I want auto-injection 
in another class. How can I do this?


class Component:GameObject
{
//second injection must be here and must be automatic
};

class Sprite:Component
{
mixin Manager; //first injection must activate second 
injection by misterious way

};

mixin template Manager() {}
mixin template ComponentCaster(string type) {} //where 'type' is 
a type obtained from Manager

//by typeof(this).stringof. As example, Sprite.

...compile-time code generation is pain %) I think, it will be 50 
times easier if we have built-in compiler script language. Or 
just a library that will be able to execute code in compile time.


Sorry for Engrish.
Regards, Alex


Re: Auto-add static field when inherit // mixins, templates?

2014-08-21 Thread Ary Borenszweig via Digitalmars-d-learn

On 8/21/14, 6:38 AM, MarisaLovesUsAll wrote:

tl;dr - how to get child classname from inherited parent function at
compile time?
class A { string getName(); };
class B { };
B foo = new B;
assert(foo.getName() == B);
...

Hi! I'm stuck at one issue, and I don't know how to solve it. I think
this is about mixins/templates, isn't it?
When inherit from base class Component, I need to auto-create child own
static fields with child type.
It should look like this, after compilation:

class Component
{
 //it doesn't matter to have any fields here
 //but it's important to be able to create an instance of Component
 //and when inherit, all childs will get their own static T list;
where T is a type of child.
};
class Sprite:Component
{
 static Sprite list; //auto-added
 static void fun() { } //auto-added, operates with Sprite
}
class Camera:Component
{
 static Camera list; //auto-added
 static void fun() { } //auto-added, operates with Camera instead of
Sprite
}
...
//so this must be correct:
Component foo;
Sprite bar;
void foobar(Component one) { }
foobar(Sprite);
...

Sorry for bad English.
Best regards, Alex


I'll tell you how it's done in Crystal in case someone wants to come up 
with a proposal to make it work in D.


~~~
class Foo
  macro inherited
def method_in_{{@class_name.downcase.id}}
  puts Hello {{@class_name.id}}!
end
  end
end

class Bar  Foo
end

Bar.new.method_in_bar #= Hello Bar!
~~~

When you inherit a class, the macro inherited is automatically 
executed by the compiler in the context of the inheriting class. There 
you can use special variables like @class_name and interpolate them 
with {{ ... }}.


I guess a similar thing to do in D would be to define a function to be 
executed at compile time and automatically mix it, and the context of 
execution would be the inherited class.


(sorry if this is of no interest to all of you, let me know if I should 
stop trying to bring ideas to D from other languages)


Re: Auto-add static field when inherit // mixins, templates?

2014-08-21 Thread anonymous via Digitalmars-d-learn

On Thursday, 21 August 2014 at 19:58:18 UTC, MarisaLovesUsAll
wrote:
When I make mixin injection in one class, I want auto-injection 
in another class. How can I do this?


class Component:GameObject
{
//second injection must be here and must be automatic
};

class Sprite:Component
{
mixin Manager; //first injection must activate second 
injection by misterious way

};


I don't think this is possible.


mixin template Manager() {}
mixin template ComponentCaster(string type) {} //where 'type' 
is a type obtained from Manager

//by typeof(this).stringof. As example, Sprite.


Maybe you can explain what you're trying to achieve with all
this. There may be a different/better way to do it.


Re: Auto-add static field when inherit // mixins, templates?

2014-08-21 Thread anonymous via Digitalmars-d-learn

On Thursday, 21 August 2014 at 20:05:13 UTC, Ary Borenszweig
wrote:
I'll tell you how it's done in Crystal in case someone wants to 
come up with a proposal to make it work in D.


~~~
class Foo
  macro inherited
def method_in_{{@class_name.downcase.id}}
  puts Hello {{@class_name.id}}!
end
  end
end

class Bar  Foo
end

Bar.new.method_in_bar #= Hello Bar!
~~~


I think such a feature would clash with a D principle: A base
class (Foo) cannot know about (or depend on) all its subclasses
(Bar), because it may be compiled separately from them.

Now, if it were only about printing the most derived class name 
(I know, it isn't), you could that in D with typeid:


import std.stdio;
class Foo
{
 void whoami()
 {
 writeln(typeid(this));
 }
}
class Bar : Foo {}
void main()
{
 Foo f = new Bar;
 f.whoami();
}


Re: Auto-add static field when inherit // mixins, templates?

2014-08-21 Thread MarisaLovesUsAll via Digitalmars-d-learn

On Thursday, 21 August 2014 at 20:16:33 UTC, anonymous wrote:

Maybe you can explain what you're trying to achieve with all
this. There may be a different/better way to do it.


Sure.
Class tree: GameObject-Component-Sprite.
GameObject structure:
Component[];
Component addComponent(Component component);

First feature is Components Manager. It's an array and 
register()/remove() functions, just like in GameObject, but it's 
static and unique to all inherited classes.

static T[] list;
static void register(T obj);
static void remove(T obj);
So, if I do this
class Sprite:Component {};
'T' becomes 'Sprite', and Manager functionality adds to class.
It also will be able to create instance of class Component 
because of Components list in GameObject. And Component type must 
be one because it's easier to use one name for inheritance and 
for storing Components.

I did this by mixins, but it's not automatic.

And second feature. When I create Sprite and add it in 
GameObject, there will be no 'cast(Sprite)' constructions; type 
of return value must be argument's type.

Code:
Component addComponent(Component component);
Sprite shell = cast(Sprite) this.addComponent(new 
Sprite(shell_1.png)); //I want remove 'cast(Sprite)' from here


I found a solution for one class:
class Component
{
Sprite toSprite() @property
{
return cast(Sprite) this;
}
alias toSprite this;
}
And it works. Now I want to add this solution in class Component, 
working with all inherited classes.
As I realize, this is rough and impossible, and I need to do some 
template magic in GameObject code.


Sorry for Engrish.
Regards, Alex


Re: Auto attributes for functions

2014-08-20 Thread Jonathan M Davis via Digitalmars-d-learn
On Wed, 20 Aug 2014 01:38:52 +
uri via Digitalmars-d-learn digitalmars-d-learn@puremagic.com wrote:

 Hi all,

 Bit new to D so this might be a very naive question...

 Can the compiler auto infer function attributes?

 I am often adding as many attributes as possible and use the
 compiler to show me where they're not applicable and take them
 away. It would be great if this could be achieved like so:

 auto function() @auto
 {}

 instead of manually writing:

 auto function() pure @safe nothrow @nogc const
 {}

Currently, just templated functions get their attributes inferred. The biggest
problem with inferring them for all functions is that you can declare a
function without defining it in the same place (e.g. if you're using .di
files), in which case the compiler has no function body to use for attribute
inferrence.

There have been discussions on ways to reasonably infer attributes under more
circumstances, but nothing has come of them yet. However, I'd expect that
there will be at least some improvements to the situation at some point given
that there is a general consensus that while the attributes are quite useful,
it's also rather annoying to have to keep typing them all.

- Jonathan M Davis


Re: Auto attributes for functions

2014-08-20 Thread ed via Digitalmars-d-learn
On Wednesday, 20 August 2014 at 09:13:15 UTC, Jonathan M Davis 
via Digitalmars-d-learn wrote:

On Wed, 20 Aug 2014 01:38:52 +
uri via Digitalmars-d-learn digitalmars-d-learn@puremagic.com 
wrote:



Hi all,

Bit new to D so this might be a very naive question...

Can the compiler auto infer function attributes?

I am often adding as many attributes as possible and use the
compiler to show me where they're not applicable and take them
away. It would be great if this could be achieved like so:

auto function() @auto
{}

instead of manually writing:

auto function() pure @safe nothrow @nogc const
{}


Currently, just templated functions get their attributes 
inferred. The biggest
problem with inferring them for all functions is that you can 
declare a
function without defining it in the same place (e.g. if you're 
using .di
files), in which case the compiler has no function body to use 
for attribute

inferrence.

There have been discussions on ways to reasonably infer 
attributes under more
circumstances, but nothing has come of them yet. However, I'd 
expect that
there will be at least some improvements to the situation at 
some point given
that there is a general consensus that while the attributes are 
quite useful,

it's also rather annoying to have to keep typing them all.

- Jonathan M Davis


Thanks guys for the info.

/uri


Re: Auto attributes for functions

2014-08-19 Thread Meta via Digitalmars-d-learn

On Wednesday, 20 August 2014 at 01:38:53 UTC, uri wrote:

Hi all,

Bit new to D so this might be a very naive question...

Can the compiler auto infer function attributes?

I am often adding as many attributes as possible and use the 
compiler to show me where they're not applicable and take them 
away. It would be great if this could be achieved like so:


auto function() @auto
{}

instead of manually writing:

auto function() pure @safe nothrow @nogc const
{}

cheers,
uri


Only if they're template functions.

//inferred as @safe pure nothrow @nogc
auto fun()() {}

//Compiler treats this is @system impure throwing @gc
//(if the latter three existed)
auto fun() {}

I think Andrei suggested in the past that functions with a return 
type of auto have attributes inferred for them as well, but 
some people were against it, and nobody's tried implementing it 
yet.


Re: auto ref function parameters in a free function

2014-08-03 Thread Martijn Pot via Digitalmars-d-learn

On Sunday, 3 August 2014 at 19:07:32 UTC, Vlad Levenfeld wrote:

This doesn't work:

bool less_than (T)(auto ref T a, auto ref T b)
{
return a  b;
}

Error: auto can only be used for template function parameters

What am I doing wrong? Is this not a template function?


I think you can just skip 'auto'.

Have a look at http://dlang.org/function.html , especially the 
function parameters section.


  1   2   >