Re: Renaming Flag!"" in API

2020-10-12 Thread aliak via Digitalmars-d-learn

On Monday, 12 October 2020 at 10:24:44 UTC, FreeSlave wrote:

Let's say I use Flag type named 'myflagname' in API like this:

import std.typecons;

void func(Flag!"myflagname" flag)
{
//...
}

void main()
{
func(Yes.myflagname);
}

Later I realize that 'myflagname' is a bad name and I want to 
change it to something else. But if I do so, I break the 
existing code using this API as Flag with different name will 
be a different type and Yes.myflagname and No.myflagname won't 
fit in. I can't use alias as Yes and No relies on string 
literal.
Can this issue overcome somehow? Looks like a fundamental flaw 
with std.typecons.Flag.


One of the reason's Flag is there is because of what's known as 
the boolean trap [0]. If someone changes the name of a parameter, 
that can potentially mean the semantics have changed. Should Flag 
work then? And if it should, why not straight up bool?


https://wiki.qt.io/API_Design_Principles#The_Boolean_Parameter_Trap


Re: Is it possible to "overload" based on visibility?

2020-09-23 Thread aliak via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 19:27:13 UTC, Steven 
Schveighoffer wrote:



This is a bug in the language.


勞



Re: Is it possible to "overload" based on visibility?

2020-09-23 Thread aliak via Digitalmars-d-learn

On Wednesday, 23 September 2020 at 18:38:53 UTC, 60rntogo wrote:
There are really two questions here, one that I intended to ask 
and one that came out while I was trying to figure out the 
answer. Consider this simple code:


[...]


Yeah, you can make a property setter:

private void x(int newValue) { _x = newValue }

2. Is the behavior that allows me to call the private method 
intended? This is such a blatant violation of encapsulation 
that it feels like a bug either in the language or the 
implementation.


Definitely sounds like a bug! Feels like this has got to be a 
regression because I just tried this:


struct Foo {
private void f() {}
void f(int i) {}
}

And Foo.f() is callable from outside the module: 
https://run.dlang.io/is/FVyw7u






Re: vibe.d and my first web service

2020-07-18 Thread aliak via Digitalmars-d-learn

On Saturday, 18 July 2020 at 09:10:04 UTC, Mr. Backup wrote:

Hello,

I wanted to create simple web service to start learning more 
about D lang and compare with another languages. I have used 
"dub init -t vibe.d" to create basic example:


[...]


Think it's just Vibe.d:

I had a similar issue: 
https://github.com/vibe-d/vibe.d/issues/2436


And this is still open (default server doesn't clean itself up): 
https://github.com/vibe-d/vibe.d/issues/2245




Re: Can't get dub dustmite to work

2020-04-27 Thread Aliak via Digitalmars-d-learn

On Monday, 27 April 2020 at 06:23:08 UTC, Andre Pany wrote:

On Sunday, 26 April 2020 at 22:07:56 UTC, aliak wrote:

On Saturday, 25 April 2020 at 18:52:45 UTC, Andre Pany wrote:

[...]


I'm sorry I didn't follow.

You mean like:

"dub test"

??

I dont pass anything to the -b or -c flag if that's what you 
mean?



[...]


Yeah, that's a good tip. This output is because of a static 
assert in the sumtype library.




Yes, that was my question. `dub test` will use configuration 
`unittest`,
therefore you have to pass the configuration `unittest` to `dub 
dustmite` too.


Kind regards
André


Ah ok. Yes I was passing the unittest confit to dub dustmite.


Re: Can't get dub dustmite to work

2020-04-26 Thread aliak via Digitalmars-d-learn

On Saturday, 25 April 2020 at 18:52:45 UTC, Andre Pany wrote:


How do you call dub test causing the issue? Maybe there is a 
difference in the configuration/build type.


I'm sorry I didn't follow.

You mean like:

"dub test"

??

I dont pass anything to the -b or -c flag if that's what you mean?



Also a side remark. You cannot use the output of dmd when 
colouring is on. Dmd lies because the backticks used for 
colouring are not shown. But without them, regex search is 
failing.


Yeah, that's a good tip. This output is because of a static 
assert in the sumtype library.




I also wonder whether dub Dustmite should be enhanced to search 
for a plain text too. Because while using regex search there 
might be characters which have a regex meaning while user just 
want a simple text search. This could also cause issues.


Kind regards
Andre





Re: Can't get dub dustmite to work

2020-04-26 Thread aliak via Digitalmars-d-learn

On Saturday, 25 April 2020 at 19:00:55 UTC, Anonymouse wrote:

On Saturday, 25 April 2020 at 09:38:59 UTC, aliak wrote:

Then I run this dub dustmite command:

dub dustmite -b unittest ../dubdust --compiler-regex="never 
matches"


I have had zero luck with dustmite via dub. I would honestly 
recommend that you create a shell script that does `dub test 
2>&1 | grep "never matches"`, and just use that as a tester 
with dustmite directly.


Ok I got it working with that but it resulted in the wrong output 
(it was a bad test case basically" But expanding the shell script 
to


dub test 2>&1 | grep 'Error: static assert:  \"handler #0 of type 
`Optional!(Exception) function(FailureContainer container) pure 
nothrow @nogc @safe` never matches\"'


now results in

...
Loading ./source/result/failure.d
Loading ./source/result/package.d
Loading ./source/result/result.d
Loading ./tests/result.d
None => No
Hint: use --no-redirect to see test script output
Hint: read 
https://github.com/CyberShadow/DustMite/wiki#initial-test-fails
object.Exception@DustMite/dustmite.d(295): Initial test fails: 
Test script "dub test 2>&1 | grep 'Error: static assert:  
\"handler #0 of type  never matches\"'" exited with exit code 1 
(failure)


??:? _Dmain [0x10c56cf5e]


This is the full dustmite command:

dustmite --force . "dub test 2>&1 | grep 'Error: static assert:  
\"handler #0 of type `Optional!(Exception) 
function(FailureContainer container) pure nothrow @nogc @safe` 
never matches\"'"


Can't get dub dustmite to work

2020-04-25 Thread aliak via Digitalmars-d-learn
Trying to get dub dustmite to work, but I keep getting "initial 
test fails"


This is the error from a vanilla dub test:

```
result ~wip: building configuration "result-test-unittest"...
inout(SumType!(int, FailureContainer))
../../.dub/packages/sumtype-0.9.4/sumtype/src/sumtype.d(1322,4): 
Error: static assert:  "handler #1 of type Optional!(Exception) 
function(FailureContainer container) pure nothrow @nogc @safe 
never matches"
../../.dub/packages/sumtype-0.9.4/sumtype/src/sumtype.d(1165,14): 
   instantiated from here: matchImpl!(inout(SumType!(int, 
FailureContainer)))
source/result/result.d(136,20):instantiated from here: 
match!(inout(SumType!(int, FailureContainer)))
tests/result.d(20,20):instantiated from here: 
Result!(int, Exception)

dmd failed with exit code 1.
```

Then I run this dub dustmite command:

dub dustmite -b unittest ../dubdust --compiler-regex="never 
matches"


And I get:

```
...
Loading /Users/aliak/dev/dubdust/vibe-d/web/vibe/web/web.d
None => No
Hint: use --no-redirect to see test script output
Hint: read 
https://github.com/CyberShadow/DustMite/wiki#initial-test-fails
object.Exception@DustMite/dustmite.d(295): Initial test fails: 
Test script "/usr/local/Cellar/dub/1.20.0/bin/dub dustmite 
--vquiet --test-package=result --build=unittest --config=library 
\"--compiler=dmd\" \"--compiler-regex=never matches\"" exited 
with exit code 3 (failure)

```

* --no-redirect doesn't work in dub dustmite.
* I tried adding --compiler-status=1 with the same result
* I tired --combined with the same result

My dub.json for the unittest configuration is (incase that 
matters):

{
"name": "unittest",
"importPaths": [
"./tests"
],
"sourcePaths": [
"./tests"
]
},

Thanks for any help!



Re: Integration tests

2020-04-22 Thread aliak via Digitalmars-d-learn

On Wednesday, 22 April 2020 at 10:32:48 UTC, Russel Winder wrote:


Now I discover Python, Rust, and Go have far nicer abstractions 
for writing Internet code than D does. Does D really not have a 
TcpListener abstraction?


It really doesn't :(

And D has so much potential as server tech with the potential 
combination of fibers + TLS + shared + static introspection.


The package Vibe-d is quite nice though. I don't know if you've 
tried it but it's very simple to get a listener up with it.




To date all I can get is:

std.socket.SocketOSException@std/socket.d(2792): Unable to bind 
socket: Bad file descriptor


when trying to open a TCP server on 127.0.0.1:5, with 
Python, Rust, or Go it all worked first time. This is really 
sad given D has so many advantages over Rust. :-(





Re: Option and Result [was Integration tests]

2020-04-21 Thread aliak via Digitalmars-d-learn

On Tuesday, 21 April 2020 at 16:30:15 UTC, Russel Winder wrote:
On Mon, 2020-04-20 at 20:19 +, aliak via 
Digitalmars-d-learn wrote:


[…]



[0]: https://github.com/aliak00/optional


Rust has Option and Result, and most languages are rapidly 
introducing at least Option if not Result – and yes it is 
almost certain all this comes from Haskell.


Yeah it's a great abstraction that's part of modern languages 
now. Some static languages are even building syntax for it right 
in (e.g. swift, kotlin, v, zig - to name a few).


There've been a few attempts at building a Result type:

https://code.dlang.org/search?q=expect
And here: 
https://github.com/aliak00/ddash/blob/master/utils/source/ddash/utils/expect.d




Is Option intended for adding to Phobos?


Not that I am aware of. There was an attempt to PR an Option type 
way back when which never made it: 
https://github.com/dlang/phobos/pull/3915


There was a post here: 
https://forum.dlang.org/thread/hqtdekjtdgbhhbjgy...@forum.dlang.org





Re: Integration tests

2020-04-20 Thread aliak via Digitalmars-d-learn

On Friday, 17 April 2020 at 16:56:57 UTC, Russel Winder wrote:

Hi,

Thinking of trying to do the next project in D rather than 
Rust, but…


Rust has built in unit testing on a module basis. D has this so 
no problem.


Rust allows for integration tests in the tests directory of a 
project. These are automatically build and run along with all 
unit tests as part of "cargo test".


Does D have any integrated support for integration tests in the 
way

Rust does?


D does not recognise any special testing directories afaik. But 
you'll get the same affect as in rust if you have your 
integration tests in a file that is not the modules you are 
testing and run it after building the main library - or during 
even.


With Dub it's quite easy to set up, you can see the optional 
package as an example [0]. There's a tests directory that does 
not have access to the optional package's internals. There's also 
a unittest-compat configuration in dub.json that tests the 
package alongside vibed (another d package)


For auto mocking, the only thing I've see that provides some 
functionality is the unit-threaded package. But I've never tried 
it.


[0]: https://github.com/aliak00/optional


Re: dub sourceFiles

2020-04-01 Thread aliak via Digitalmars-d-learn

On Tuesday, 31 March 2020 at 15:23:48 UTC, Anonymouse wrote:
I have a library package that I split up into subpackages, but 
I'm having to do mental gymnastics to make it only compile the 
files I want.


The problem is that even if you specify some `sourceFiles`, it 
will build everything under the sun inside `sourcePaths`, which 
defaults to "source" or "src" depending on availability. 
There's no way to set it to an empty string, or something that 
doesn't exist.


```sdl
name "stuff"
targetType "library"

subPackage {
name "foo"

sourceFiles \
"source/foo.d"
}

subPackage {
name "bar"

sourceFiles \
"source/bar.d" \
"source/common.d"
}
```


$ dub build -v :foo
[...]
/usr/bin/dmd -Isource source/foo.d source/bar.d source/common.d


Since I didn't specify any `sourcePaths`, it here defaults to 
"source" and my subpackage only asking for "foo.d" was handed 
all of the files anyway.


What is the preferred solution here?

1. Use `excludedSourceFiles` and exclude files not to be 
compiled. Mental gymnastics needed when you have 12 files (the 
actual case).
2a. Keep source tree in something that isn't named "source" or 
"src", but keep an empty one around for dub to auto-include 
nothing from. I kind of want to avoid this.
2b. Keep real source files in "source", but declare 
`sourcePaths` to point to a dummy empty "ignoreme" directory.  
Crude but technically works.

3. Something else? Surely I'm not the first to run into this.

I could set up the subpackages to each have its own directory 
(2a), but I'd end up with twelve, not including the empty 
"source" acting as bait for dub.


Maybe this will help you: 
https://github.com/aliak00/dub-subpackages


I think it falls under the something else category. The "lib" 
folder does have a source directory but I'm pretty sure you can 
remove that and it will still work and compile only the sub 
projects you want it to.


But, dub is sometimes a mystery in how it works so shout if the 
above doesn't work!


Re: Pattern matching via switch?

2020-03-14 Thread aliak via Digitalmars-d-learn

On Saturday, 14 March 2020 at 19:04:28 UTC, 12345swordy wrote:

I.E.

switch (object)
case Type1 t1:
case Type2 t2:
case Type3 t3:


You can use the sumtype package 
(https://code.dlang.org/packages/sumtype):


alias T = SumType!(Type1, Type2, Type3);

T(object).match!(
(Type1 t1) => "t1",
(Type2 t2) => "t2",
(Type3 t3) => "t3",
);


Or you can make a quick template like:

template switch_(funs...) {
auto switch_(T)(auto ref T t) {
static foreach (fun; funs) {
static if (is(typeof(fun(T.init {
return fun(t);
}
}
}
}

struct A {}
struct B {}
struct C {}

void main()
{
auto a = C();
a.switch_!(
(A _) => "a",
(B _) => "b",
(C _) => "c",
).writeln;
}

The template above is a quick fix and will have some holes 
though. Off the top of my head if more than one lambda "fits" 
there'll be problems.




Re: Safely wrapping an uncopyable struct to implement an interface

2020-03-04 Thread aliak via Digitalmars-d-learn

On Wednesday, 4 March 2020 at 12:03:48 UTC, Gregor Mückl wrote:

Hi!

I've just created a situation in my code that is summarized by 
the following example. I don't know how to solve it with @safe 
code.


A third party library provides a struct that is not copyable:

// provided by third party
struct Foo {
@disable this() @safe;
@disable this(ref return scope Foo other) @safe;

void magic() @safe;
}

What I want to do is to provide a safe wrapper around it that 
adapts to another interface:


// intended common interface
interface IWrapper {
void bar() @safe;
}

Now, the obvious way to wrap this fails:

class FooWrapper : IWrapper {
Foo f;

this(Foo f) @safe {
this.f = f; // this fails because it would be a copy
}

override void bar() @safe
{
f.magic();
}
}

If Foo were a class, f would be a reference and everything 
would be fine. But f is a struct that can't be copied and 
taking a pointer to f makes FooWrapper obviously unsafe. How 
could I solve this?


I've come up with a workaround for my actual use case that 
doesn't need to use the uncopyable struct this way. But I'm 
curious if I'm missing something regarding references to 
structs.


You can use move maybe? : 
https://dlang.org/library/std/algorithm/mutation/move.html


So

this.f = f.move;

But you should be aware that it could cause problems when f has 
pointers to its internals. I.e. if Foo had a pointer to it's own 
member then the value of of that pointer to me "copied" over to 
this.f, but the address of the member in this.f is different that 
the original f's member address.






Re: in not working for arrays is silly, change my view

2020-03-02 Thread aliak via Digitalmars-d-learn
On Monday, 2 March 2020 at 23:27:22 UTC, Steven Schveighoffer 
wrote:


What I think is happening is that it determines nobody is using 
the result, and the function is pure, so it doesn't bother 
calling that function (probably not even the lambda, and then 
probably removes the loop completely).


I'm assuming for some reason, the binary search is not flagged 
pure, so it's not being skipped.


Apparently you're right: 
https://github.com/dlang/phobos/blob/5e13653a6eb55c1188396ae064717a1a03fd7483/std/range/package.d#L11107




If I change to this to ensure side effects:

bool makeImpure; // TLS variable outside of main

...

auto results = benchmark!(
() => makeImpure = r1.canFind(max),
() => makeImpure = r2.contains(max),
() => makeImpure = r3.canFind(max),
)(5_000);

writefln("%(%s\n%)", results); // modified to help with the 
comma confusion


I now get:
4 secs, 428 ms, and 3 hnsecs
221 μs and 9 hnsecs
4 secs, 49 ms, 982 μs, and 5 hnsecs

More like what I expected!


A damn! And here I was thinking that branch prediction made a 
HUGE difference! Ok, I'm taking my tail and slowly moving away 
now :) Let us never speak of this again.




-Steve





Re: in not working for arrays is silly, change my view

2020-03-02 Thread aliak via Digitalmars-d-learn
On Monday, 2 March 2020 at 21:33:37 UTC, Steven Schveighoffer 
wrote:

On 3/2/20 3:52 PM, aliak wrote:
On Monday, 2 March 2020 at 15:47:26 UTC, Steven Schveighoffer 
wrote:

On 3/2/20 6:52 AM, Andrea Fontana wrote:
On Saturday, 29 February 2020 at 20:11:24 UTC, Steven 
Schveighoffer wrote:
1. in is supposed to be O(lg(n)) or better. Generic code 
may depend on this property. Searching an array is O(n).


Probably it should work if we're using a "SortedRange".


int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
auto p = assumeSorted(a);

assert(3 in p);




That could work. Currently, you need to use p.contains(3). 
opIn could be added as a shortcut.


It only makes sense if you have it as a literal though, as 
p.contains(3) isn't that bad to use:


assert(3 in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].assumeSorted);

There's no guarantee that checking if a value is in a sorted 
list is any faster than checking if it's in a non sorted list. 
It's why sort usually switches from a binary-esque algorithm 
to a linear one at a certain size.


Well of course! A binary search needs Lg(n) comparisons for 
pretty much any value, whereas a linear search is going to end 
early when it finds it. So there's no guarantee that searching 
for an element in the list is going to be faster one way or the 
other. But Binary search is going to be faster overall because 
the complexity is favorable.


Overall tending towards infinity maybe, but not overall on the 
average case it would seem. Branch prediction in CPUs changes 
that in that with a binary search it is always a miss. Whereas 
with linear it's always a hit.




The list could potentially need to be _very_ large for 
p.contains to make a significant impact over canFind(p) AFAIK.


Here's a small test program, try playing with the numbers and 
see what happens:


import std.random;
import std.range;
import std.algorithm;
import std.datetime.stopwatch;
import std.stdio;

void main()
{
     auto count = 1_000;
     auto max = int.max;

     alias randoms = generate!(() => uniform(0, max));

     auto r1 = randoms.take(count).array;
     auto r2 = r1.dup.sort;
     auto elem = r1[uniform(0, count)];


auto elem = r1[$-1]; // try this instead



     benchmark!(
     () => r1.canFind(elem),
     () => r2.contains(elem),
     )(1_000).writeln;
}

Use LDC and -O3 of course. I was hard pressed to get the 
sorted contains to be any faster than canFind.


This begs the question then: do these requirements on in make 
any sense? An algorithm can be log n (ala the sorted search) 
but still be a magnitude slower than a linear search... what 
has the world come to 臘‍♂️


PS: Why is it named contains if it's on a SortedRange and 
canFind otherwise?




A SortedRange uses O(lgn) steps vs. canFind which uses O(n) 
steps.


canFind is supposed to tell the reader that it's O(n) and 
contains O(lgn)?




If you change your code to testing 1000 random numbers, instead 
of a random number guaranteed to be included, then you will see 
a significant improvement with the sorted version. I found it 
to be about 10x faster. (most of the time, none of the other 
random numbers are included). Even if you randomly select 1000 
numbers from the elements, the binary search will be faster. In 
my tests, it was about 5x faster.


Hmm... What am I doing wrong with this code? And also how are you 
compiling?:


void main()
{
auto count = 1_000_000;
auto max = int.max;

alias randoms = generate!(() => uniform(0, max - 1));

auto r1 = randoms.take(count).array;
auto r2 = r1.dup.sort;
auto r3 = r1.dup.randomShuffle;

auto results = benchmark!(
() => r1.canFind(max),
() => r2.contains(max),
() => r3.canFind(max),
)(5_000);

results.writeln;
}


$ ldc2 -O3 test.d && ./test
[1 hnsec, 84 μs and 7 hnsecs, 0 hnsecs]



Note that the compiler can do a lot more tricks for linear 
searches, and CPUs are REALLY good at searching sequential 
data. But complexity is still going to win out eventually over 
heuristics. Phobos needs to be a general library, not one that 
only caters to certain situations.


General would be the most common case. I don't think extremely 
large (for some definition of large) lists are the more common 
ones. Or maybe they are. But I'd be surprised. I also don't think 
phobos is a very data-driven library. But, that's a whole other 
conversation :)




-Steve





Re: in not working for arrays is silly, change my view

2020-03-02 Thread aliak via Digitalmars-d-learn
On Monday, 2 March 2020 at 15:47:26 UTC, Steven Schveighoffer 
wrote:

On 3/2/20 6:52 AM, Andrea Fontana wrote:
On Saturday, 29 February 2020 at 20:11:24 UTC, Steven 
Schveighoffer wrote:
1. in is supposed to be O(lg(n)) or better. Generic code may 
depend on this property. Searching an array is O(n).


Probably it should work if we're using a "SortedRange".


int[] a = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
auto p = assumeSorted(a);

assert(3 in p);




That could work. Currently, you need to use p.contains(3). opIn 
could be added as a shortcut.


It only makes sense if you have it as a literal though, as 
p.contains(3) isn't that bad to use:


assert(3 in [0, 1, 2, 3, 4, 5, 6, 7, 8, 9].assumeSorted);

-Steve


There's no guarantee that checking if a value is in a sorted list 
is any faster than checking if it's in a non sorted list. It's 
why sort usually switches from a binary-esque algorithm to a 
linear one at a certain size. The list could potentially need to 
be _very_ large for p.contains to make a significant impact over 
canFind(p) AFAIK.


Here's a small test program, try playing with the numbers and see 
what happens:


import std.random;
import std.range;
import std.algorithm;
import std.datetime.stopwatch;
import std.stdio;

void main()
{
auto count = 1_000;
auto max = int.max;

alias randoms = generate!(() => uniform(0, max));

auto r1 = randoms.take(count).array;
auto r2 = r1.dup.sort;
auto elem = r1[uniform(0, count)];

benchmark!(
() => r1.canFind(elem),
() => r2.contains(elem),
)(1_000).writeln;
}

Use LDC and -O3 of course. I was hard pressed to get the sorted 
contains to be any faster than canFind.


This begs the question then: do these requirements on in make any 
sense? An algorithm can be log n (ala the sorted search) but 
still be a magnitude slower than a linear search... what has the 
world come to 臘‍♂️


PS: Why is it named contains if it's on a SortedRange and canFind 
otherwise?




Re: in not working for arrays is silly, change my view

2020-03-02 Thread aliak via Digitalmars-d-learn
On Monday, 2 March 2020 at 15:50:08 UTC, Steven Schveighoffer 
wrote:

On 3/2/20 6:39 AM, JN wrote:
On Saturday, 29 February 2020 at 21:56:51 UTC, Ali Çehreli 
wrote:
Because you mentioned canFind, I think you want the semantics 
to be "is there an element with this value." If so, it would 
be confusing to use the same operator for two different 
things: For associative arrays, it means "is there an element 
accessible with this key."


Does it? I always viewed it as "is this value in list of keys"


Array keys are the element index..

So essentially:

int[int] c1;
int[] c2 = new int[4];
c1[3] = 10;
c2[3] = 10;

assert(3 in c1); // true
assert(3 in c2); // what should this do?

-Steve


If in were to mean "is this value in list of keys" then to be 
consistent:


3 in c2 == 3 < c2.length


Re: Is deprecating a template supposed to work?

2020-02-20 Thread aliak via Digitalmars-d-learn
On Thursday, 20 February 2020 at 23:21:23 UTC, MoonlightSentinel 
wrote:

On Thursday, 20 February 2020 at 22:31:16 UTC, aliak wrote:

Is this suppose to give a deprecation error message?

deprecated("a")
alias A(T) = B!T;

template B(T) {
alias B = T;
}

void main() {
A!int a; // should this cause a message "a" ?
}

??

Or am I using it wrong maybe?


It's a bug, see https://issues.dlang.org/show_bug.cgi?id=20190


Ah, I see. Thanks!


Is deprecating a template supposed to work?

2020-02-20 Thread aliak via Digitalmars-d-learn

Is this suppose to give a deprecation error message?

deprecated("a")
alias A(T) = B!T;

template B(T) {
alias B = T;
}

void main() {
A!int a; // should this cause a message "a" ?
}

??

Or am I using it wrong maybe?


Re: How do you find the struct types in a module? - getting Error: unknown

2020-02-13 Thread aliak via Digitalmars-d-learn
On Thursday, 13 February 2020 at 15:38:37 UTC, Steven 
Schveighoffer wrote:

On 2/13/20 9:47 AM, aliak wrote:

[...]


Not sure about your error, but here is a working version (don't 
use mixins, use __traits(getMember)):


import std.meta;
template ListOfStructs(alias mod)
{
enum isStruct(string m) = is(__traits(getMember, mod, m) == 
struct);

alias getMember(string m) = __traits(getMember, mod, m);
alias ListOfStructs = staticMap!(getMember, 
Filter!(isStruct, __traits(allMembers, mod)));

}

-Steve


It works without the mixin indeed! Thank you!


How do you find the struct types in a module? - getting Error: unknown

2020-02-13 Thread aliak via Digitalmars-d-learn

Hi,

I'm trying to get a typed list of structs in my current module 
that matches certain criteria. Something like:


module mod;

struct X {}
struct Y {}

alias allTypes = ListOfTypes!mod;

But I'm having a bit of trouble. I have this so far:

template ListOfTypes(alias T) {
import std.meta;
enum isStruct(string m) = is(mixin(m) == struct);
enum types = Filter!(isStruct, __traits(allMembers, T));
alias toType(string m) = mixin(m);
alias all = staticMap!(toType, types);
alias CommandGroupsOf = all;
}

pragma(msg, ListOfTypes!mod);

But that causes an error I've never seen before:

Error: unknown, please file report on issues.dlang.org
onlineapp.d(30,1):while evaluating `pragma(msg, 
CommandGroupsOf!(mod))`



Any workarounds or maybe insight in to the error?




Re: Hum Humm, Typedef

2019-12-01 Thread aliak via Digitalmars-d-learn

On Saturday, 30 November 2019 at 18:15:47 UTC, Treebeard wrote:
Hoom, hum, I met a dark forest of complains from the compilers 
here.


[...]


/me thinks it's a bug

Pushed a pr. Let's see.

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


Re: Referance usage in async function

2019-11-30 Thread aliak via Digitalmars-d-learn

On Saturday, 30 November 2019 at 13:45:00 UTC, kerdemdemir wrote:

I have simplified my problem which can be seen below.

import std.stdio;
import vibe.core.core;
import vibe.core.concurrency;
import vibe.data.json;

void main()
{
int[] list;

bool ListManipulator(ref int[] list)
{
list ~= 2;
list ~= 4;
return true;
}

bool ListManipulatorPointer( int[]* list)
{
*list ~= 2;
*list ~= 4;
return true;
}


auto future = vibe.core.concurrency.async(, 
list);

future.getResult();

writeln(list); > prints empty list

future = 
vibe.core.concurrency.async(, );

future.getResult();

writeln(list); > prints [2,4]
}


Why passing the pointer works meanwhile passing as reference 
does nothing? I feel that is more D issue than vibe.d which I 
can learn something I hope.


Erdem


Looks like a bug in vibe: 
https://github.com/vibe-d/vibe-core/blob/master/source/vibe/core/concurrency.d#L1141


The function async doesn't use auto ref on ARGS. So the arguments 
are value copies through. If it used auto ref all the way through 
then it'd probably work:


---
import std;

void async(CALLABLE, ARGS...)(CALLABLE callable, auto ref ARGS 
args) {

callable(args);
}

void main() {
int[] list;
bool ListManipulator(ref int[] list) {
list ~= 2;
list ~= 4;
return true;
}

async(, list);
writeln(list);
}


Re: How to wait for a shell process to finish on ctrl+c before exiting?

2019-11-25 Thread aliak via Digitalmars-d-learn
On Sunday, 24 November 2019 at 17:04:49 UTC, Steven Schveighoffer 
wrote:

On 11/24/19 10:44 AM, aliak wrote:

[...]


Hm.. are you sure that ctrl-c isn't also sending the signal to 
your child process? I thought it did.


-Steve


Yesh, you're right. That extra kill is unnecessary and was 
actually causing problems. So thanks for that!


Re: How to wait for a shell process to finish on ctrl+c before exiting?

2019-11-25 Thread aliak via Digitalmars-d-learn

On Sunday, 24 November 2019 at 16:05:14 UTC, mipri wrote:

On Sunday, 24 November 2019 at 15:44:00 UTC, aliak wrote:

[...]


This might be useful:
---
#! /usr/bin/env rdmd
import std;
import core.stdc.signal;

[...]


waitpid, of course! Thanks agin :)


How to wait for a shell process to finish on ctrl+c before exiting?

2019-11-24 Thread aliak via Digitalmars-d-learn
I'm writing some command line tooling stuff, and one of the 
command spins up a docker compose file (which in short, spins up 
some services and aggregates the output of each service to 
stdout).


When a user presses ctrl+c, i would like to pass on the ctrl+c to 
the spawned process and wait till it handles ctrl+c and then let 
go of the current process.


So far I have this:

int spawnedPid;

extern(C) int kill(int pid, int sig) nothrow @nogc @system;

extern(C) void interruptHandler(int sig) nothrow @nogc @system {
kill(spawnedPid, sig);
}

int spawnProcessAndWait(string[] cmd) {
auto pid = spawnProcess(cmd, stdin, stdout, stderr);
spawnedPid = pid.processID;
signal(SIGINT, );
int result = wait(pid);
return wait(pid);
}

It doesn't work. I think the call to kill doesn't wait? Is there 
a way to make it wait?


I can't call kill(Pid) or wait(Pid) inside the interrupt handler 
because those are not @nogc [0].


[0]: 
https://forum.dlang.org/thread/mtikzznfaahiltguv...@forum.dlang.org


Re: Spawning a process, then killing it on SIGINT

2019-11-24 Thread aliak via Digitalmars-d-learn
On Saturday, 23 November 2019 at 12:19:27 UTC, Steven 
Schveighoffer wrote:

On 11/23/19 4:54 AM, aliak wrote:
Is there a way to go about killing a process after spawning it 
on a SIGINT?


I can't do this for e.g. because kill is not @nogc.

Pid currentSpawnedPid;
extern(C) void killCurrentPidHandler(int sig) nothrow @nogc 
@system {

   kill(currentSpawnedPid, sig);
}

int main() {
   currentSpawnedPid = spawnProcess(["docker-compose", "up"], 
stdin, stdout, stderr);

   signal(SIGINT, );
   return wait(currentSpawnedPid);
}

Any other ways to go about this?


Yeah, fix phobos. kill should be @nogc/nothrow, and probably 
@safe.


-Steve


Looked in to it, seems step one is getting phobos compiling with 
dip1008 :/

Kill uses enforce.


Re: Spawning a process, then killing it on SIGINT

2019-11-24 Thread aliak via Digitalmars-d-learn

On Saturday, 23 November 2019 at 10:09:51 UTC, mipri wrote:

On Saturday, 23 November 2019 at 09:54:48 UTC, aliak wrote:
Is there a way to go about killing a process after spawning it 
on a SIGINT?


I can't do this for e.g. because kill is not @nogc.


Well, this works:

import std;
import core.stdc.signal;

extern(C) int kill(int pid, int sig) nothrow @nogc @system;

int currentSpawnedPid;
extern(C) void killCurrentPidHandler(int sig) nothrow @nogc 
@system {

  if (currentSpawnedPid > 1)
kill(currentSpawnedPid, sig);
}

int main() {
  auto pid = spawnProcess(["sleep", "50s"], stdin, stdout, 
stderr);

  currentSpawnedPid = pid.processID;
  signal(SIGINT, );
  return wait(pid);
}


Thanks, looks like I'll have to go that route.


Spawning a process, then killing it on SIGINT

2019-11-23 Thread aliak via Digitalmars-d-learn
Is there a way to go about killing a process after spawning it on 
a SIGINT?


I can't do this for e.g. because kill is not @nogc.

Pid currentSpawnedPid;
extern(C) void killCurrentPidHandler(int sig) nothrow @nogc 
@system {

  kill(currentSpawnedPid, sig);
}

int main() {
  currentSpawnedPid = spawnProcess(["docker-compose", "up"], 
stdin, stdout, stderr);

  signal(SIGINT, );
  return wait(currentSpawnedPid);
}

Any other ways to go about this?

Cheers,
- Ali


Re: deep copying a struct

2019-09-06 Thread aliak via Digitalmars-d-learn

On Friday, 6 September 2019 at 10:37:16 UTC, aliak wrote:

Are there any library APIs that allow this:


I just put this together. Any holes other the AA related ones?

Will it work with classes?

auto dupDeep(T)(ref T thing) {
import std.range: ElementType;
import std.traits: hasAliasing, Unqual, isArray;

static if (isArray!T) {
Unqual!(ElementType!T)[] copy;
foreach (elem; thing) {
copy ~= elem.dupDeep;
}
} else static if (hasAliasing!T) {
Unqual!T copy;
foreach (i, field; thing.tupleof) {
copy.tupleof[i] = field.dupDeep;
}
} else {
Unqual!T copy;
copy = thing;
}
return copy;
}



deep copying a struct

2019-09-06 Thread aliak via Digitalmars-d-learn

Are there any library APIs that allow this:

struct S {
int[] arr;
}

void main() {
const a = S([1,2,3]);
S b = a.copy; // deep dup/copy
}


I'd also like to avoid implementing a copy constructor for each 
type.


Re: advise about safety of using move in an opAssign with __traits(isRef

2019-08-18 Thread aliak via Digitalmars-d-learn

On Saturday, 17 August 2019 at 16:43:51 UTC, Paul Backus wrote:

On Friday, 16 August 2019 at 08:07:28 UTC, aliak wrote:
Hi, I'm trying to fix a use-case where you have a wrapper 
template type (it's an optional) and the wrapping type has 
@disable this(this). And having this scenario work:


struct S {
  @disable this(this);
}
Optional!S fun() {...}

Optional!S a;
a = fun.move;

Now that won't work because of the disabled copy


Are you sure? I tried to reproduce the error you're describing, 
and I couldn't do it. The following compiles and runs without 
any issues:


struct Wrapper(T) { T value; }
struct NoCopy { @disable this(this); }

Wrapper!NoCopy fun()
{
return Wrapper!NoCopy();
}

void main()
{
Wrapper!NoCopy a;
a = fun(); // already an rvalue, so moved implicitly
}

Can you give a more complete example of the problem you're 
having?


You'll get the error if you define an opAssign:

struct Wrapper(T) {
T value;
void opAssign(U : T)(Wrapper!U other) {
this.value = other.value;
}
}

struct S {
  @disable this(this);
}

Wrapper!S fun() { return Wrapper!S(S()); }

void main() {
Wrapper!S a;
a = fun;
}




Re: advise about safety of using move in an opAssign with __traits(isRef

2019-08-17 Thread aliak via Digitalmars-d-learn

On Friday, 16 August 2019 at 14:29:26 UTC, Paul Backus wrote:

On Friday, 16 August 2019 at 08:07:28 UTC, aliak wrote:

[...]


Even simpler:

void opAssign(auto ref Optional!T rhs) {
import core.lifetime: forward;
this._value = forward!rhs;
}


That doesn't work with private members unfortunately :( - i.e. 
this.value = forward!(rhs._value) - member inaccessible.


Is there a known workaround for that? If not then should I just 
copy the implementation in place to be correct?


advise about safety of using move in an opAssign with __traits(isRef

2019-08-16 Thread aliak via Digitalmars-d-learn
Hi, I'm trying to fix a use-case where you have a wrapper 
template type (it's an optional) and the wrapping type has 
@disable this(this). And having this scenario work:


struct S {
  @disable this(this);
}
Optional!S fun() {...}

Optional!S a;
a = fun.move;

Now that won't work because of the disabled copy, but you can 
either:


1) Add an explicit move function in the Optional type:
struct Optional {
  auto move(ref Optional!T target) {
import std.algorithm: move;
return move(this, target);
  }
}

Then you  could do:
fun.move(field);

First of all I find the readability confusing, so there's no way 
to know if fun is moving in to field or field is moving in to 
fun. But OTOH it matches the phobos move(T src, T target). So 
conventionally maybe ok. Also it's explicit, so it makes it clear 
at the call site that a move is happening.


2) use isRef inside opAssign like this:

void opAssign(auto ref Optional!T lhs) {
  static if (__traits(isRef, lhs)) {
this._value = lhs._value;
  } else {
import std.algorithm: move;
move(lhs._value, this._value);
  }
}

Then you could just do:

field = fun

And it'll just work since fun returns an rvalue. The second 
solution it seems like it'll just work correctly with the static 
if guard. But I'm not sure if there're any gotchas I should be 
aware of?


Any advice?



Re: Passing nested template function

2019-08-10 Thread aliak via Digitalmars-d-learn

On Saturday, 10 August 2019 at 17:45:43 UTC, Prateek Nayak wrote:
A nested function can be passed to another function evident 
from this example: https://run.dlang.io/is/6waRkB


However if the nested function is a template function, it 
raises an error

https://run.dlang.io/is/PQhkwl
The error being: cannot get frame pointer to the nested function

Is there a way to pass a nested template function to a function 
declared outside the outer function scope?


This looks like it could be a bug to me. If you explicitly 
instantiate the nested template and call dispatch like 
dispatch!(nested!0) then it works.


An alias template parameter can accept both a template and an 
instantiated template. I.e.


template X(T) {}
alias A = X; // ok
alias B = X!int; // ok

So it's unclear what should happen. At the least, the defaulted 
argument should be applied at the call site (Func(a)).


Note though that neither versions will work on ldc or gdc 
however. Because there's a bug [0] that has only been fixed in 
for dmd.


[0] https://github.com/dlang/dmd/pull/9282


cannot use local __lambda1 as parameter to non-global template

2019-07-26 Thread aliak via Digitalmars-d-learn

Can someone help me understand the details around why this fails?

import std;

struct W(T) {
T value;
auto hook(handlers...)() {
return handlers[0](value);
}
}

template f(handlers...) {
auto ref f(T)(auto ref T value) {
return value.hook!handlers;
}
}

@nogc void main() {
auto a = W!int(3);
auto b = a.f!((_) => "yes");
}

If I specifically type the lambda I pass in to f (i.e. (int _) => 
"yes") then it works. Or if I make hook a global template that 
takes a W!T as the first parameter it also works. Is there a work 
around for this?


Re: cannot use local __lambda1 as parameter to non-global template

2019-07-26 Thread aliak via Digitalmars-d-learn

On Friday, 26 July 2019 at 16:20:10 UTC, aliak wrote:
Can someone help me understand the details around why this 
fails?


import std;

struct W(T) {
T value;
auto hook(handlers...)() {
return handlers[0](value);
}
}

template f(handlers...) {
auto ref f(T)(auto ref T value) {
return value.hook!handlers;
}
}

@nogc void main() {
auto a = W!int(3);
auto b = a.f!((_) => "yes");
}

If I specifically type the lambda I pass in to f (i.e. (int _) 
=> "yes") then it works. Or if I make hook a global template 
that takes a W!T as the first parameter it also works. Is there 
a work around for this?


Err sorry, that was ldc pre the 5710 bug fix. In DMD I get this:

Error: @nogc function D main cannot call non-@nogc function 
onlineapp.main.f!(W!int).f


I guess it's allocating a delegate somewhere. Can I fix that?


Re: cannot use local __lambda1 as parameter to non-global template

2019-07-26 Thread aliak via Digitalmars-d-learn

On Friday, 26 July 2019 at 16:21:52 UTC, aliak wrote:

On Friday, 26 July 2019 at 16:20:10 UTC, aliak wrote:
Can someone help me understand the details around why this 
fails?


import std;

struct W(T) {
T value;
auto hook(handlers...)() {
return handlers[0](value);
}
}

template f(handlers...) {
auto ref f(T)(auto ref T value) {
return value.hook!handlers;
}
}

@nogc void main() {
auto a = W!int(3);
auto b = a.f!((_) => "yes");
}

If I specifically type the lambda I pass in to f (i.e. (int _) 
=> "yes") then it works. Or if I make hook a global template 
that takes a W!T as the first parameter it also works. Is 
there a work around for this?


Err sorry, that was ldc pre the 5710 bug fix. In DMD I get this:

Error: @nogc function D main cannot call non-@nogc function 
onlineapp.main.f!(W!int).f


I guess it's allocating a delegate somewhere. Can I fix that?


I can do this but ugh:

import std;

struct W(T) {
T value;
static auto hook(handlers...)(auto ref typeof(this) self) {
return handlers[0](self.value);
}
}

template f(handlers...) {
auto ref f(T)(auto ref T value) {
return value.hook!handlers(value);
}
}

@nogc void main() {
auto a = W!int(3);
auto b = a.f!((_) => "yes");
}


Re: Any way to move in @disabled this(this) type in to a wrapping template?

2019-07-25 Thread aliak via Digitalmars-d-learn

On Thursday, 25 July 2019 at 21:23:33 UTC, Paul Backus wrote:

On Thursday, 25 July 2019 at 20:38:59 UTC, aliak wrote:

On Thursday, 25 July 2019 at 19:35:36 UTC, aliak wrote:
Basically, can template W be made to handle an S that can't 
be copied?


import std;

static struct S {
int i;
@disable this(this);
this(int i) { this.i = i; }
}

[...]


So this works - are there any problems with it?

struct W(T) {
T value;
this(T value) {
static if (isMutable!T)
this.value = value.move;
else
this.value = value;
}
}

auto wrap(T)(T value) {
static if (isMutable!T)
return W!T(value.move);
else
return W!T(value);
}

Shouldn't this be happening by default? When would you not 
want that to happen?


The way I handle this is with `auto ref` and 
`core.lifetime.forward`:


import core.lifetime: forward;

struct W(T)
{
T value;
this()(auto ref T value)
{
this.value = forward!value;
}
}

auto wrap(T)(auto ref T value)
{
return W!T(forward!value);
}

@safe unittest
{
static struct NoCopy { @disable this(this); }
assert(__traits(compiles, {
auto test = wrap(NoCopy());
}));
assert(!__traits(compiles, {
auto lval = NoCopy(); auto test = lval;
}));
}

Interactive: https://run.dlang.io/is/kDJyYC

It's not very well documented, but `forward` does essentially 
the same thing as your `static if` + `move` combination.


Note that with both your version and mine, you will run into 
the same problem I did of `move` making it impossible to use 
instances of `W` in static initializers and CTFE. [1] The best 
compromise I was able to come up with was to only call move if 
`isCopyable!T == false`, which doesn't really solve the 
problem, but at least contains it.


[1] https://github.com/pbackus/sumtype/issues/22


Haha. Ironic. Thanks, again :)

Though, if you use auto ref, and you check if it's mutable and 
not copyable and then move, then that means you could potentially 
be applying move to an object on behalf of the clients


auto a = MyUnmovableType()
auto b = LibraryType(a);
writeln(a); // ??

If this is a problem, I guess a __traits(isRef, parameter) check 
along with mutable and copyable could help. Then if client want 
it moved they could call move explicitly.


Re: Any way to move in @disabled this(this) type in to a wrapping template?

2019-07-25 Thread aliak via Digitalmars-d-learn

On Thursday, 25 July 2019 at 19:35:36 UTC, aliak wrote:
Basically, can template W be made to handle an S that can't be 
copied?


import std;

static struct S {
int i;
@disable this(this);
this(int i) { this.i = i; }
}

struct W(T) {
T value;
this(T value) {
this.value = value;
}
}

auto wrap(T)(T value) {
return W!T(value);
}

void main() {
auto a = wrap(S(3));
}

I tried doing something like:

W!T construct(Args...)(auto ref Args args) {
  import std.algorithm: move;
  auto value = T(args);
  W!T w;
  w.value = move(value);
  return move(opt);
}


So this works - are there any problems with it?

struct W(T) {
T value;
this(T value) {
static if (isMutable!T)
this.value = value.move;
else
this.value = value;
}
}

auto wrap(T)(T value) {
static if (isMutable!T)
return W!T(value.move);
else
return W!T(value);
}

Shouldn't this be happening by default? When would you not want 
that to happen?


Any way to move in @disabled this(this) type in to a wrapping template?

2019-07-25 Thread aliak via Digitalmars-d-learn
Basically, can template W be made to handle an S that can't be 
copied?


import std;

static struct S {
int i;
@disable this(this);
this(int i) { this.i = i; }
}

struct W(T) {
T value;
this(T value) {
this.value = value;
}
}

auto wrap(T)(T value) {
return W!T(value);
}

void main() {
auto a = wrap(S(3));
}

I tried doing something like:

W!T construct(Args...)(auto ref Args args) {
  import std.algorithm: move;
  auto value = T(args);
  W!T w;
  w.value = move(value);
  return move(opt);
}


Re: dip1000, perhaps annotate with return, and vibe-d

2019-07-25 Thread aliak via Digitalmars-d-learn

On Wednesday, 24 July 2019 at 16:23:48 UTC, Paul Backus wrote:

On Wednesday, 24 July 2019 at 12:54:51 UTC, aliak wrote:

[...]


It should go on the constructor's parameter; i.e.,

this(auto return ref T value) { /* ... */ }

Under the hood, a constructor actually returns the constructed 
value by reference, so the actual signature of the above 
constructor seen by the lifetime checker is:


ref Optional!T __ctor(auto return ref T value)

You can see this for yourself with something like `pragma(msg, 
typeof(Optional!T.__ctor))`.


Thanks! The under the hood stuff was good to know!

I was putting it in the right place but it seems to still have 
been complaining. Ah well. I guess an auto ref on a constructor 
doesn't really make sense anyway.


dip1000, perhaps annotate with return, and vibe-d

2019-07-24 Thread aliak via Digitalmars-d-learn

Trying to get dip1000 flag in use. I have this error:

Error: returning Optional(null, false).this(value) escapes a 
reference to parameter value, perhaps annotate with return


in this function:

public auto some(T)(auto ref T value) {
return Optional!T(value); // <-- error on this line
}

And it's instantiated from here:

static Optional!T fromRepresentation(Json value) {
  if (value == Json.undefined) {
return no!T;
  }
  return some(deserializeJson!T(value)); // <-- instantiated from 
here

}

I put the qualifier "return" on the parameter to some, but did 
nothing. And I put it on Optional.this() as well, but I'm not 
sure where I'm supposed to put it.


The constructor for Optional takes an auto ref T ... I'm not sure 
that makes sense. Does it make sense to take a constructor 
parameter that is copied in to the struct by auto ref if you're 
not calling .move on it explicitly?


And as for vibe-d, I get this when compiling with dip1000:

Also, vibe-d gives me this: 
../../../.dub/packages/vibe-core-1.6.2/vibe-core/source/vibe/internal/traits.d(391,2): Error: static assert:  "FileStream does not implement method "read" of type @safe ulong(scope ubyte[] dst, IOMode mode)"


Has anyone seen that or used vibed with dip1000?


Re: segfault in ldc release only - looks like some kind of optimization bug?

2019-07-22 Thread aliak via Digitalmars-d-learn

On Tuesday, 23 July 2019 at 00:36:49 UTC, Exil wrote:

auto ref get(T)(W!T value) {
return value.front;
}

You're returning a reference to a temporary that gets deleted 
at the end of the function's scope. The "auto ref" here will be 
a "ref".


. oh ... shit you're right.

Ok so this was minimized from this:

const config = Config.ghApp(ghDomain)
.orElseThrow!(() => new Exception(
"could not find config for domain 
'%s'".format(ghDomain)

));

Where Config.ghApp return an Optional!GhApp, and orElseThrow 
checks if a range has is not empty and returns front. The front 
in Optional is defined as the front above...


So is that an incorrect idiom to use when writing a library then? 
I pretty sure I've seen it in phobos too.


Slapping return on the function also fixes it. Is that the 
correct way to write a .front?


Thanks!


segfault in ldc release only - looks like some kind of optimization bug?

2019-07-22 Thread aliak via Digitalmars-d-learn

Hi,

so I had this weird bug that was driving me crazy and only 
segfaulted with ldc in release build - (I'm using ldc 1.16.0).


This is the code that segfaults. All parts seem to be necessary 
for it to happen, or at least I think so. I've gone in circles 
minimizing so I've probably missed something. But this seems to 
be it:


import std;

struct W(T) {
T value;
ref inout(T) front() inout { return value; }
}

auto ref get(T)(W!T value) {
return value.front;
}

struct S {
string a;
}

void main() {
S[string] aa;
aa = ["one" : S("a")];
auto b = W!S(aa["one"]).get;
writeln(b);
}

Running with ldc and -O3 crashes: "ldc2 -O3 -run source.d"

Some things I've noticed:
- if you remove the call to .get and use .value directly, the 
crash goes

- if you remove the inout specifier on front(), the crash goes
- if you remove the ref specifier on front(), the crash goes
- if you don't call writeln(b), the crash goes
- if you don't use the s returned by the aa, the crash goes
- if you *add* a return qualifier on the "front" function, the 
crash goes away


(what is that return thing btw and when do you use it?)

Any ideas?



Re: can not find the error: Error: TypeInfo cannot be used with -betterC

2019-07-17 Thread aliak via Digitalmars-d-learn

On Wednesday, 17 July 2019 at 15:52:39 UTC, Newbie2019 wrote:

when build my project with -betterC, it throw this error:

Error: TypeInfo cannot be used with -betterC

There is no location information about it,  how can I find what 
code cause this ?


You usually get that *extrememly* unhelpful error message when 
you use anything that uses TypeInfo. So it can be quite hard to 
figure out.


Did it start happening after you added a class or did something 
with exceptions? At least those would cause that error.


Re: Trying to alias this a grapheme range + making it a forward range

2019-07-09 Thread aliak via Digitalmars-d-learn

On Monday, 8 July 2019 at 23:01:49 UTC, ag0aep6g wrote:

On 08.07.19 23:55, aliak wrote:

[...]


`source.front` is a temporary `Grapheme` and you're calling 
`opSlice` on it. The documentation for `Grapheme.opSlice` 
warns: "Invalidates when this Grapheme leaves the scope, 
attempts to use it then would lead to memory corruption." [1]


Ah. Right. Thanks!



[...]


hah yes, I realized this as well.



[...]


No you're right. It was indeed just making things more 
complicated and was just a bad idea.




[...]


Cheers,
- Ali


Trying to alias this a grapheme range + making it a forward range

2019-07-08 Thread aliak via Digitalmars-d-learn

Problem 1:

I'm trying to get a string to behave as a .byGrapheme range by 
default, but I can't figure out Grapheme. I'm trying to replicate 
this behavior:


foreach (g; "hello".byGrapheme) {
write(g[]);
}

In a custom type:

struct ustring {
string data;
this(string data) {
this.data = data;
}
auto get() {
static struct Range {
typeof(string.init.byGrapheme) source;
bool empty() { return source.empty; }
void popFront() { source.popFront; }
auto front() { return source.front[]; }
auto save() { return this; };
}
return Range(this.data.byGrapheme);
}
alias get this;
}

But I keep on ending up with a UTFException: "Encoding an invalid 
code point in UTF-8" with code like:


writeln("hello".ustring);

Problem 2:

How can I get the aliased ustring type to behave as a 
ForwardRange? If I add the save method to the voldermort range 
type, the isForwardRange!ustring fails because the requirement on 
isForwardRange checks to see if save returns the same type it's 
called on. Which is not the case here since typeof(ustring.save) 
== ustring.get.Range). But nontheless does have a save method.


Cheers,
- Ali



Re: Anyway to compare function aliases? Or any ideas?

2019-07-04 Thread aliak via Digitalmars-d-learn

On Thursday, 4 July 2019 at 15:22:08 UTC, Marco de Wild wrote:

On Thursday, 4 July 2019 at 15:10:05 UTC, aliak wrote:

[...]


I don't know if it will solve your whole problem, but have you 
tried __traits(isSame, W0.fun, fun)?


Reduced example:

struct Foo(alias fun){
alias bar = fun;
}

void stuff(alias fun, T)(T t)
{
static if(__traits(isSame, fun, T.bar)) {
pragma(msg, "Yes");
} else {
pragma(msg, "No");
}
}

void a(){}
void b(){}

void main()
{
stuff!a(Foo!a()); // Yes
stuff!a(Foo!b()); // No
}


Of course! That helps a lot yes. Thank you :)

The case in the gist I pasted above works like a charm now. 
isSame seems like a decent enough powerhouse to get most of the 
practical cases it seems as well.


Anyway to compare function aliases? Or any ideas?

2019-07-04 Thread aliak via Digitalmars-d-learn

Any ideas on how to be able to do something like this?

struct S(alias _fun) {
  alias Fun = _fun;
}

void algorithm(alias f, T)(T s) {
  static if ( == ) {
// trivial return
  } else {
// must perform work, then return
  }
}

Can you use function addresses in some way? I've seen that some 
of them are resolved to __lambda0 and other times to a function 
type, i.e.


Error: incompatible types for (& f) is (& __lambda1): void 
function(A!(function () => 3) t) and int function() pure nothrow 
@nogc @safe


That comes from doing doing this:

alias g = () => 3;
algorithm!g(S!g());

I've thought of something along the lines of a function alias 
wrapper. But I'm not sure how to make that work either. Something 
like:


struct Fun(alias _fun, string _id) {
  alias Fun = _fun;
  enum ID = _id;
}

Then maybe something like:

alias g = () => 3;
Fun!(g, "myid") gfun;
algorithm!gfun(S!gfun());

Then inside algorithm the check becomes:

static if ( == )

But then I'd like to generate the ID at instantiation point. So 
is using __LINE__, __FILE__ and applying some hash function a 
good idea here?


Any other ideas?

Cheers,
- Ali

PS: If you're curious of a semi working sample, to see what I'm 
actually trying to do, I've put up this gist that does not 
compile right now:


https://gist.github.com/aliak00/fcdd4fa7512035405bb7015cf6d8016f


Re: What is iota function full name

2019-06-21 Thread aliak via Digitalmars-d-learn

On Friday, 21 June 2019 at 09:01:17 UTC, lili wrote:

Hi Guys:
What is range.iota function full name


That is the full name. Or what do you mean?

Found on the internet somewhere:

"The function is named after the integer function ⍳ from the 
programming language APL."





Re: Range violation error when reading from a file

2019-06-18 Thread aliak via Digitalmars-d-learn

On Tuesday, 18 June 2019 at 01:15:54 UTC, Samir wrote:

On Monday, 17 June 2019 at 03:46:11 UTC, Norm wrote:

On Monday, 17 June 2019 at 00:22:23 UTC, Samir wrote:



Any suggestions on how to rectify?


You could change the IF to

`if(line.length > 0 && line[0] == '>')`


Thanks, Norm.  That seemed to do the trick and fixed the error.

On Monday, 17 June 2019 at 11:25:01 UTC, aliak wrote:

On Monday, 17 June 2019 at 00:22:23 UTC, Samir wrote:


HOWEVER, the output is interesting.  There IS a blank line 
between the last line and the prompt:


That's because you're using write*ln*. So even though line is 
empty, you still output a new line.


Curious.  I am going to have to think about that for a bit as I 
don't quite understand.


I mean this:

$ dmd -run readfile.d
1)
file.eof() == false
line = "> line 1"
writeln("lines 1" + \n);
2)
file.eof() == false
line = line 2
writeln("line 2" + \n);
3)
file.eof() == false
line = line 3
writeln("line 3" + \n);
4)
file.eof() == false
line = > line 4
writeln("> line 4" + \n);
5)
file.eof() == false
line = line 5
writeln("line 5" + \n);
6)
file.eof() == false
line = "" // empty since there're no lines left in file
writeln("" + \n); <-- this is your blank line
7)
file.eof() == true


Re: How does this template work?

2019-06-17 Thread aliak via Digitalmars-d-learn

On Monday, 17 June 2019 at 18:25:24 UTC, Robert M. Münch wrote:

On 2019-06-16 15:14:37 +, rikki cattermole said:


observerObject is an eponymous template.

What this means (in essence) is the symbol inside the template 
block == template block.


Hmm... ok. Is there any reason to have these "eponymous 
templates"? I don't see any benefit...


Less typing for one. Otherwise you'd have to write:

auto observer = observerObject!int.observerObject(TestObserver());




Re: Range violation error when reading from a file

2019-06-17 Thread aliak via Digitalmars-d-learn

On Monday, 17 June 2019 at 00:22:23 UTC, Samir wrote:


Also, if I run the program below with the same file, I don't 
get any range violation errors:


Ya, writeln will not access individual elements of a range if 
there aren't any. So no violations occur.


HOWEVER, the output is interesting.  There IS a blank line 
between the last line and the prompt:


That's because you're using write*ln*. So even though line is 
empty, you still output a new line.




Any suggestions on how to rectify?



You can do:

if (!line.length) {
continue;
}

Inside your while loop after the call to strip.



Re: Range violation error when reading from a file

2019-06-16 Thread aliak via Digitalmars-d-learn

On Sunday, 16 June 2019 at 23:44:49 UTC, Samir wrote:

On Sunday, 16 June 2019 at 23:03:04 UTC, aliak wrote:

stripping the last line could result in an empty line if it 
just has strippable characters?


The last line of the file is just text but without a newline 
(\n) character or any other whitespace character at the end.  I 
get the same error when I remove the strip function from the 
readln line.


http://www.cplusplus.com/reference/ios/ios/eof/

The fail bit is only set after reading fails. So after you read 
the last line, your eof will still return true, and hence your 
range violation.


Re: Range violation error when reading from a file

2019-06-16 Thread aliak via Digitalmars-d-learn

On Sunday, 16 June 2019 at 22:47:14 UTC, Samir wrote:

I am trying to read from a text file using the following code:

import std.stdio;
import std.string;

void main() {
File file = File("test.txt");
string line;

while (!file.eof()) {
line = strip(file.readln());
if (line[0] == '>') { // line 10
writeln(line[1..$]);
}
else {
writeln(line);
}
}
}

and I get the following error AFTER the last line is processed:

core.exception.RangeError@readfile.d(10): Range violation

??:? _d_arrayboundsp [0x448efa]
??:? _Dmain [0x4459f7]

Any idea what I am doing wrong?  When processing the if 
statement or writing the slice, am I inadvertently trying to 
read a non-existent line in the file?


Thanks in advance
Samir


stripping the last line could result in an empty line if it just 
has strippable characters?


Re: Is there a way to disable copying of an alias this'd member? - trying to make a NotNull type

2019-05-24 Thread aliak via Digitalmars-d-learn

On Friday, 24 May 2019 at 12:03:08 UTC, Simen Kjærås wrote:

On Friday, 24 May 2019 at 11:40:20 UTC, aliak wrote:

It's ref so that you can do this for e.g.

class C { int i; }
auto a = notNull!C;
a.i = 3;


That's a valid concern for a struct, but classes are already 
reference types, so you're only adding a new layer of ref-ness. 
The above will work great with a non-ref alias this.



--
  Simen


Ah true. Yes I guess I can do this for ref types indeed. And 
maybe I can just constrain it to classes, interfaces and pointers 
樂


Cheers,
- Ali


Re: Is there a way to disable copying of an alias this'd member? - trying to make a NotNull type

2019-05-24 Thread aliak via Digitalmars-d-learn

On Friday, 24 May 2019 at 10:40:01 UTC, Simen Kjærås wrote:

On Friday, 24 May 2019 at 10:16:50 UTC, aliak wrote:

Basically, I want this to fail:

auto notNull(T, Args...)(Args args) {
return NotNull!T(new T(args));
}

struct NotNull(T) {
  private T _value;
  @property ref inout(T) value() inout { return this._value; }
  alias value this;
  //disable opAssign to null as well
}

class C {}
void func(ref C t) {
  t = null;
}

auto a = notNull!C;
func(a); // i want a compile error here

Any ideas that don't involve disabling copying or making the 
property non-ref?


Pretty sure that can't be done. On the other hand, why is the 
property ref if you're explicitly not going to use its 
ref-ness? Alternatively, can you show me how you use its 
ref-ness?


It's ref so that you can do this for e.g.

class C { int i; }
auto a = notNull!C;
a.i = 3;

I guess maybe there's a way to go about supporting that kinda 
thing with opDispatch. But I've tried doing that in the optional 
type [0] and it's rather painful to get right, and trickier to 
make @safe as well.




And just for completeness, you are aware that alias this takes 
an overload set, so that this works?


   struct NotNull(T) {
   private T _value;
   @property inout(T) value() inout { return _value; }
   @property void value(T val) { _value = val; } // new
   alias value this;
   // disable opAssign to null as well
   }

   class C {}
   void func(ref C t) { t = null; }

   unittest {
   NotNull n;
   n = new C(); // Look ma, I'm assigning without ref!
   func(n); // Does not compile - value() doesn't return by 
ref

   }

--
  Simen


Si si. I is aware. I've disabled opAssign to T actually (i think 
i have at least). And I only allow assigning to another NotNull 
else there's no way to guarantee that the NotNull stays non null.


It looks like I'm going to have to sacrifice being able to 
manipulate member variables of the type the NotNull is wrapping, 
or give up on the guarantee of the inner value not being null.


[0] https://code.dlang.org/packages/optional



Is there a way to disable copying of an alias this'd member? - trying to make a NotNull type

2019-05-24 Thread aliak via Digitalmars-d-learn

Basically, I want this to fail:

auto notNull(T, Args...)(Args args) {
return NotNull!T(new T(args));
}

struct NotNull(T) {
  private T _value;
  @property ref inout(T) value() inout { return this._value; }
  alias value this;
  //disable opAssign to null as well
}

class C {}
void func(ref C t) {
  t = null;
}

auto a = notNull!C;
func(a); // i want a compile error here

Any ideas that don't involve disabling copying or making the 
property non-ref?


Full example here: https://run.dlang.io/is/ubOwkd

Thanks!



Re: alias this and struct allocation

2019-05-06 Thread aliak via Digitalmars-d-learn

On Monday, 6 May 2019 at 14:48:56 UTC, faissaloo wrote:
I've been having some memory issues (referenced objects turning 
to nulls for no apparent reason) and I was wondering if I've 
misunderstood how allocation works when instantiating a struct 
that uses alias this:


import std.stdio;

struct Parent {
int a;
}
struct Child {
Parent base;
alias base this;
int y;
}
auto myStructMaker() {
return new Child(Parent(10),20);
}

void main()
{
writeln(*myStructMaker());
}

In this example is the data in base guaranteed to exist? Or is 
base definitely part of the allocation of Child on the heap?


Base exists as a value type inside Child so if Child exists, then 
base is definitely there. If base was a class or a pointer to a 
struct, then it may or may not exist.


Here's an excellent post from HS Teoh that explains a lot of 
this: 
https://forum.dlang.org/post/mailman.2535.1417413189.9932.digitalmars-d-le...@puremagic.com


Do you have an example of a referenced object turning to null? We 
may be able to spot something


Re: alias fails to compile

2019-04-22 Thread aliak via Digitalmars-d-learn
On Monday, 22 April 2019 at 08:02:06 UTC, Arun Chandrasekaran 
wrote:

What am I doing wrong here?

struct A
{
union B
{
int bb;
}
B b;
alias aa = B.bb;
}

void main()
{
A a = A();
// a.b.bb = 4; // works
a.aa = 4; // fails
}


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


You can get the behaviour you want with opDispatch, and 
generalize it with a mixin template:


mixin template AliasMember(string aliasName, string memberName) {
ref opDispatch(string name)() if (name == aliasName) {
return mixin(memberName);
}
}

struct A {
union B {
int bb;
}
B b;
mixin AliasMember!("aa", "b.bb");
}

void main() {
A a = A();
a.aa = 4;
}


Re: alias sequences of sequences

2019-04-07 Thread aliak via Digitalmars-d-learn

On Sunday, 7 April 2019 at 04:58:13 UTC, Alex wrote:

Is there any way to get sequences of sequences?

Using RT, I have to use strings

[[`string`, `0`], ...]

when it would be much better to use

[[string, 0], ...]

Ideally it wouldn't add so much overhead that it defeats the 
purpose.


https://aliak00.github.io/bolts/bolts/meta/AliasPack.html


Re: Why this eponymous template does not compile?

2019-03-25 Thread aliak via Digitalmars-d-learn

On Monday, 25 March 2019 at 09:27:03 UTC, Victor Porton wrote:

///
template sychronizedMemoize(alias fun) {
void sychronizedMemoize() { }
}

void f() { }

void main()
{
synchronizedMemoize!f();
}
///

/tmp/temp_7F3C101460D0.d(9,5): Error: template instance 
`synchronizedMemoize!f` template `synchronizedMemoize` is not 
defined, did you mean sychronizedMemoize(alias fun)()?


Why the error? Is it compiler bug? DMD v2.084.1


Typo in eponymous template. syc vs sync.


Re: Can't make inout work.

2019-03-18 Thread aliak via Digitalmars-d-learn

On Sunday, 17 March 2019 at 20:23:44 UTC, Paul Backus wrote:

On Sunday, 17 March 2019 at 10:49:03 UTC, aliak wrote:

[...]


For some reason, when you call `make("hello")`, the template 
argument T is being inferred as char[] instead of string. (You 
can see this by putting `pragma(msg, T)` in the body of make.) 
It works if you instantiate make explicitly with 
`make!string("hello")`.


This seems like a bug to me. If you remove inout from the code, 
T is correctly deduced as string.


https://issues.dlang.org/show_bug.cgi?id=19749


Re: Can't make inout work.

2019-03-17 Thread aliak via Digitalmars-d-learn

On Sunday, 17 March 2019 at 17:22:13 UTC, Kagamin wrote:

struct S(T) {
T value;
bool opEquals(U:S!V,V)(in U r) const
{ return value==r.value; }
}


Hmm, that actually works for opEquals. But now you just hit the 
same problem with some other construct, unfortunately:


auto x = [make("hello"), S!string("hi")];

same error.



Re: Can't make inout work.

2019-03-17 Thread aliak via Digitalmars-d-learn

On Saturday, 16 March 2019 at 03:49:26 UTC, Paul Backus wrote:

On Friday, 15 March 2019 at 23:57:15 UTC, aliak wrote:

Anyone knows how to make this work?


You need an explicit `inout` on the return value of `make`:

auto ref make(T)(inout auto ref T value) {
return inout(S!T)(value);
}


Ah! Thanks! So next problem with that:

import std.stdio;

struct S(T) {
T value;
}

auto make(T)(inout auto ref T val) {
return inout(S!T)(val);
}

void main() {
writeln(make("hello") == S!string("hello"));
}

Error: Error: incompatible types for (make("hello")) == 
(S("hello")): immutable(S!(char[])) and S!string


I think that's just this bug (which is marked as a diagnostic for 
some reason): https://issues.dlang.org/show_bug.cgi?id=19126


Thoughts on any workarounds?


Can't make inout work.

2019-03-15 Thread aliak via Digitalmars-d-learn
This is the set up I have, and I'm not sure how to get the main 
function at the bottom to compile. The error in the code below is 
that it cannot implicitly convert an inout(C) to a C in the 
constructor of S(T).


If you remove the constructor that takes an inout then you get a 
"cannot deduce function from argument types !()(inout(C))" 
because there's no constructor that can take in inout.


If you remove the inout form the function "f", then "a.f" cannot 
be deduced because there's no f that takes an inout(C).


If you remove the inout from the "make" function, then you get: 
"only parameters or stack based variables can be inout."


Anyone knows how to make this work?

struct S(T) {
T value = T.init;
}

auto ref make(T)(inout auto ref T value) {
return S!T(value);
}

auto ref f(T)(inout auto ref S!T s) {
return make(s.value);
}

void main() {
class C {}
const a = S!C();
a.f;
}

Cheers,
- Ali


Re: inout auto ref escaping a reference to parameter, only errors with vibe Json type, or if inout is there.

2019-03-12 Thread aliak via Digitalmars-d-learn

On Monday, 11 March 2019 at 22:29:05 UTC, aliak wrote:

[...]


Here's a much reduces test case:

struct W(T) {}

struct S {
int* data;
}

template match1(alias handler) {
auto ref match1(T)(inout auto ref W!T w) {
return handler();
}
}

template match2(alias handler) {
auto match2(T)(auto ref W!T w) {
return match1!handler(w);
}
}

void main() {
W!int()
.match2!(() => S());
}




Re: inout auto ref escaping a reference to parameter, only errors with vibe Json type, or if inout is there.

2019-03-12 Thread aliak via Digitalmars-d-learn

On Monday, 11 March 2019 at 22:29:05 UTC, aliak wrote:

Hi,

I have an error that says "Error: returning `match1(opt)` 
escapes a reference to parameter `opt`, perhaps annotate with 
`return`".


[...]


Ok, I've found out something else. It only happens when you're 
returning a type that has an indirection. So instead of the Json 
type if we returned an S type where S was:


struct S {
  void[2] data;
}

We get the same error.



inout auto ref escaping a reference to parameter, only errors with vibe Json type, or if inout is there.

2019-03-11 Thread aliak via Digitalmars-d-learn

Hi,

I have an error that says "Error: returning `match1(opt)` escapes 
a reference to parameter `opt`, perhaps annotate with `return`".


The code is here: https://run.dlang.io/is/ESZDW4 (It's copied at 
the end of this post as well)


1) If you remove the inout from line 11. It works.
2) If you *do not* call match2 and call match1 instead, it also 
works.
3) If you return something other than vibe's Json type, it works 
(afaict)


Am I using inout wrong? Why is it only happen with Json type so 
far. If I return any other random struct it works fine. And why 
does it work if I don't go through the "match2" template? Any 
help would be much appreciated.


---

template match1(handlers...) {
auto ref match1(T)(inout auto ref Optional!T opt) { // remove 
inout, it works

if (opt.empty) {
return  handlers[1]();
} else {
return  handlers[0](opt.front);
}
}
}

template match2(handlers...) {
auto match2(T)(auto ref Optional!T opt) {
return match1!handlers(opt);
}
}

void main() {
some(1)
.match2!( // use match1, it works
(int i) {return Json(1);}, // return anything else, 
it works

() {return Json(1);}
)
.writeln;
}

Cheers,
- Ali


Re: Setting immutable static data inside a struct in a module constructor?

2019-03-03 Thread aliak via Digitalmars-d-learn

On Sunday, 3 March 2019 at 20:41:36 UTC, Alex wrote:

On Sunday, 3 March 2019 at 20:10:14 UTC, aliak wrote:
Is it possible to initialize static immutable members of a 
struct like you could do for a global immutable one?


immutable string a;
struct Test {
  static immutable string b;
}

shared static this() {
  a = "foo";
  Test.b = "bar";
}

Error: cannot modify immutable expression b


Hmm... should work, I think...
But this works in any case:

immutable string a;
struct Test {
  static immutable string b;
  shared static this() {
b = "bar";
  }
}


Ah, did not know that. Thank you!


Setting immutable static data inside a struct in a module constructor?

2019-03-03 Thread aliak via Digitalmars-d-learn
Is it possible to initialize static immutable members of a struct 
like you could do for a global immutable one?


immutable string a;
struct Test {
  static immutable string b;
}

shared static this() {
  a = "foo";
  Test.b = "bar";
}

Error: cannot modify immutable expression b


Re: Concatenating compile time sequences

2019-03-03 Thread aliak via Digitalmars-d-learn

On Saturday, 2 March 2019 at 02:38:09 UTC, H. S. Teoh wrote:
On Sat, Mar 02, 2019 at 02:16:22AM +, Victor Porton via 
Digitalmars-d-learn wrote:

[...]


Keep in mind that sequences produced by AliasSeq are 
auto-expanding, meaning the above construct will automatically 
flatten into a flat AliasSeq!(int, "x", float, "y", double, 
"z").  If that's not what you want, you need to wrap your 
subsequences in a separate, non-eponymous template.




[...]


I'm not sure what "alias enum" is supposed to mean; is that a 
typo? Surely you mean just "alias"?




[...]


This line doesn't do what you think it does, because of 
auto-expansion. It's essentially exactly the same thing as:


private alias processFields(T, name, Fields...) =
AliasSeq!(T, name, processFields!(Fields));

i.e., the nested AliasSeq has no effect.



[...]


If you want anything that retains a nested structure, you 
cannot use AliasSeq because of auto-expansion.  You need to 
define your own, non-eponymous template container, e.g.:


template MySeq(T...) {
alias data = T;
}

alias processFields(T, name, Fields...) =
AliasSeq!(MySeq!(T, name), MySeq!(processFields!(Fields)));

The MySeq!(...) "protect" their contents from flattening into 
the outer list, while the outer AliasSeq causes individual 
MySeq!(...)'s to be promoted to the top level sequence rather 
than producing a tree-like structure.


Note that to access the data inside a MySeq, you'll have to use 
.data, for example:


alias fields = processFields!(int, "x", float, "y");

alias type0 = fields[0].data[0]; // int
string name0 = fields[0].data[1]; // "x"
alias type1 = fields[1].data[0]; // float
string name1 = fields[1].data[1]; // "y"

Hope this helps.


T


There's a package called bolts that has an AliasPack defined that 
could allow you to do something like:


template split(seq...) if (seq.length % 2 == 0) {
static if (seq.length >= 2) {
alias Pair = AliasPack!(seq[0], seq[1]);
alias split = AliasSeq!(Pair, .split!(seq[2..$]));  
} else {
alias split = AliasSeq!();
}
}

Running code: https://run.dlang.io/is/lfTOBz

Cheers,
- Ali


Re: Why is SwitchError an error and how is it unsafe to continue after catching it?

2019-02-25 Thread aliak via Digitalmars-d-learn

On Sunday, 24 February 2019 at 11:05:31 UTC, Alex wrote:

On Sunday, 24 February 2019 at 10:53:09 UTC, aliak wrote:

[...]


There is a semantic difference between a switch and a final 
switch statement, defined here:

https://dlang.org/spec/statement.html#final-switch-statement

By this difference, the writer of the final switch declares, 
that it is unrecoverable to pass something unexpected to the 
switch statement. The catch of an error as you demonstrated is, 
therefore, a contradiction to the finality of the switch.


Hmm ok. Yes that makes sense to see it that way. Thanks!



I mean, if you know, that something beyond the enum can be 
passed, use a normal switch and handle the case in the default 
section. If you are able to ensure, this case is unreachable, 
you express this knowledge/ability by the final switch and 
don't need the try-catch clause at all.


Aye, agreed.



Why is SwitchError an error and how is it unsafe to continue after catching it?

2019-02-24 Thread aliak via Digitalmars-d-learn
Because from what I understand, an Error is something you should 
not be catching and represents something unrecoverable. And it 
the docs say that it's unsafe to continue execution. But the 
following code is very recoverable and I don't see how it's 
unsafe to continue executing:


import optional;
import core.exception: SwitchError;

enum Enum : string {
  one = "one", two = "two"
}

Optional!Enum makeEnum(string value) {
  try {
final switch (value) {
case Enum.one: return some(Enum.one);
case Enum.two: return some(Enum.two);
}
  } catch (SwitchError) {
return no!Enum;
  }
}

unittest {
assert(makeEnum("one") == some(Enum.one));
assert(makeEnum("huh") == no!Enum);
}

Cheers,
- Ali


Re: Temporary @trusted scope

2018-12-18 Thread aliak via Digitalmars-d-learn
On Tuesday, 18 December 2018 at 13:52:29 UTC, Steven 
Schveighoffer wrote:

On 12/18/18 6:29 AM, Simen Kjærås wrote:
On Tuesday, 18 December 2018 at 10:14:50 UTC, Per Nordlöw 
wrote:
What's the preferred way of creating a temporary @trusted 
scope without writing a separate  function?


Jonathan's idea might also be encapsulated in a function, just 
like assumeUnique in Phobos:


import std.stdio;

template unsafe(alias fn) {
     @trusted auto unsafe(T...)(T args) {
     return fn(args);
     }
}

@system void fun(int n) {
     writeln("foo!");
}

@safe unittest {
     unsafe!({
     fun(2);
     });

     unsafe!fun(2);
}


Wow, I really like this. The only real problem is that one 
generally searches for @trusted when looking for unsafe code, 
but unsafe is pretty obvious too. Also, args should be auto ref.


Only thing better I can think of (for the second example) is to 
define a prototype with the correct information, only with 
@trusted (and specify the mangle). But any decent compiler 
should get rid of any overhead there.


-Steve


I've been gathering assume related stuff like this in a lib under 
an "assume" template. You can generalize further with multiple 
attributes inside a non-eponymous thing and use them like:


assume!fun.safe_(2);
assume!fun.nogc_(2);

I guess it's no very idiomatic D though, but I feel it reads 
better ... ok well maybe 路‍♂️: 
https://aliak00.github.io/bolts/bolts/assume/assume.html


Easier to be more specific with searches for "assumeSafe" instead 
of just "assume!" though.


Cheers,
- Ali




Re: Tricky DMD bug, but I have no idea how to report

2018-12-17 Thread Aliak via Digitalmars-d-learn

On Monday, 17 December 2018 at 21:59:59 UTC, JN wrote:

Hey guys,

while working on my game engine project, I encountered a DMD 
codegen bug. It occurs only when compiling in release mode, 
debug works. Unfortunately I am unable to minimize the code, 
since it's quite a bit of code, and changing the code changes 
the bug occurrence. Basically my faulty piece of code looks 
like this


[...]


I remember a couple of months ago someone complaining about 
similar issues when switching to a newer dmd. I tried looking for 
the thread but can’t find it. Think it was on the general list.


Have you tried previous compiler versions yet?


Re: Can you move a disabled this(this) struct in to a container type if it's an rvalue?

2018-12-15 Thread aliak via Digitalmars-d-learn
On Thursday, 13 December 2018 at 23:33:39 UTC, Stanislav Blinov 
wrote:

On Thursday, 13 December 2018 at 13:17:05 UTC, aliak wrote:


[...]


Hypothetically, yes, e.g. an object that contains references to 
itself. However, D operates on the assumption that you don't 
have such objects. And even though it can't be statically 
checked, move and swap do actually perform this check at 
runtime in debug builds.
Operating under that rule, it should be legal to move any 
values that are passed to you. In fact, I postulate that it 
*must* be done instead of making copies. Unfortunately, Phobos 
doesn't agree.


[...]


Oh cool! An isRef trait. TIL!

And I see, thank you all for the tips!


Re: Can you move a disabled this(this) struct in to a container type if it's an rvalue?

2018-12-13 Thread aliak via Digitalmars-d-learn
On Thursday, 13 December 2018 at 12:08:22 UTC, Boris-Barboris 
wrote:

On Thursday, 13 December 2018 at 09:51:42 UTC, aliak wrote:

[...]



You can just move in container constructor:


struct S {
@disable this(this);
this(int i) {}
}

struct Container(T) {
T value;
this(T value) {
import std.algorithm: move;
this.value = value.move;
}
}

void main() {
auto a = Container!S(S(3));
}


Ah. Is there any case where you would not want to do that when 
you have a T value as parameter?


And, what if it's "this()(auto ref T value)"? Then moving could 
be dangerous if the parameter was passed as a ref. Or maybe it 
just wouldn't compile?


Re: Can you move a disabled this struct in to a container type if it's an rvalue?

2018-12-13 Thread aliak via Digitalmars-d-learn

On Wednesday, 12 December 2018 at 21:11:38 UTC, Paul Backus wrote:

On Wednesday, 12 December 2018 at 20:05:18 UTC, aliak wrote:

Ie:

struct S {
@disable this();
this(int i) {}
}

struct Container(T) {
T value;
this(auto ref T value) {
this.value = value;
}
}

void main() {
auto a = Container!S(S(3)); // can't do this.
}


The only error I get when I compile this has to do with 
incorrect use of `auto ref`. If I change the constructor's 
signature to `this()(auto ref T value)`, it works fine.


Crap! So sorry, this was supposed to be this(this) and that auto 
ref is not supposed to be there :(


Posted new (and correct) message: 
https://forum.dlang.org/thread/sasdsmxmikxqfxhtb...@forum.dlang.org


Can you move a disabled this(this) struct in to a container type if it's an rvalue?

2018-12-13 Thread aliak via Digitalmars-d-learn

Ie:

struct S {
@disable this(this);
this(int i) {}
}

struct Container(T) {
T value;
this(T value) {
this.value = value;
}
}

void main() {
auto a = Container!S(S(3)); // can't do this.
}

I can build a custom constructor for Container that makes this 
work:


static auto construct(Args...)(auto ref Args args) {
import std.algorithm: move;
auto value = T(args);
auto opt = Container!T.init;
opt.value = move(value);
return move(opt);
}

And then "auto a = Container!T.construct(3);" works.

But is there a way to do it without adding a custom constructor 
type?


Cheers,
- Ali


Can you move a disabled this struct in to a container type if it's an rvalue?

2018-12-12 Thread aliak via Digitalmars-d-learn

Ie:

struct S {
@disable this();
this(int i) {}
}

struct Container(T) {
T value;
this(auto ref T value) {
this.value = value;
}
}

void main() {
auto a = Container!S(S(3)); // can't do this.
}

I can build a custom constructor for Container that makes this 
work:


static auto construct(Args...)(auto ref Args args) {
import std.algorithm: move;
auto value = T(args);
auto opt = Container!T.init;
opt.value = move(value);
return move(opt);
}

But is there a way to do it without adding a custom constructor 
type?


Cheers,
- Ali



Re: Calling function explicitly from mixin template results in recursive call instead

2018-12-10 Thread aliak via Digitalmars-d-learn

On Sunday, 9 December 2018 at 18:36:50 UTC, Dennis wrote:
I'm using Adam's workaround from 
https://issues.dlang.org/show_bug.cgi?id=19365, but now I have 
endless recursion. Reduced code:


```
mixin template operators() {
S opBinary(string op: "+")(S rhs) {
return rhs;
}

// (A)
auto opBinary(string op, T)(T rhs) if (false) {
return rhs;
}
}

struct S {
mixin operators ops;
S opBinary(string op, T)(T a) {
return ops.opBinary!op(a);
}
}

void main() {
S.init.opBinary!"+"(S.init);
}
```

Believe it or not, `ops.opBinary!op(a);` doesn't call anything 
from the mixin template ops, but it calls itself and it results 
in a stack overflow. I think this is a bug, but last time I was 
wrong, so maybe someone can explain what's going on here.


I think the docs [0] are not as specific as they can be, but 
there's this part: "If the name of a declaration in a mixin is 
the same as a declaration in the surrounding scope, the 
surrounding declaration overrides the mixin one". Later on 
there's a section on disambiguating between conflicting symbols, 
but that sections feels wanting. Furthremore, this seems to work 
as expected:


mixin template Foo() {
void f() {
writeln("Foo.f");
}
}

mixin Foo foo;
void f() {
writeln("f");
foo.f;
}

void main() {
f;
}

I think I'd file this and see if someone complains.




Does anyone know how to get this working?


Does this fix your issue?

struct S {
mixin operators ops;
S opBinary(string op, T)(T a) {
alias opBinary = ops.opBinary; // explicitly alias 
opBinary in this scope

return opBinary!op(a);
}
}

Cheers,
- Ali

[0] https://dlang.org/spec/template-mixin.html#mixin_scope


Re: How to set constant value to environment variable at compile time?

2018-12-10 Thread aliak via Digitalmars-d-learn

On Monday, 10 December 2018 at 11:08:23 UTC, Narxa wrote:

Hello, people!

I would like to have a constant with the value of some 
environment variable that is defined at compile time.


In FreePascal, it can be done by defining it in source as:

VALUE_OF_SOMETHING = {$I %SOMETHING%};

And I can call the compiler with (bash):

SOMETHING='Anything' export SOMETHING;  

And it will automatically assign VALUE_OF_SOMETHING to 
'Anything'.



In GCC C compiler, the solution I found was more complicated 
but it worked.


I had to explicitly define the environment variable when 
calling the compiler with:


gcc  -DSOMETHING=\""Anything"\" -o  


Now, I would like to do that with the 'dmd' compiler.

I know I could possibly use 'gdc' to achieve that but I want to 
use the 'dmd' compiler.


Is it possible to do that such a thing or through source or any 
other means?



Thank you!


I don't know if it's possible but one way to do it would be to 
use the -J switch and give it a config file that has contents:


VAR1=Value1
VAR2=Value2

And then in source code:

immutable config = import("config");
mixin(parseConfig);

string parseConfig(string str) {
  string ret;
  foreach (line; str.split("\n")) {
auto parts = line.split("=");
ret ~= `string ` ~ parts[0] ~ ` = "` parts[2] `";`;
  }
  return ret;
}

You can also echo out the config file with bash or something

Cheers,
- Ali



Re: cannot use local f as parameter to non-global template

2018-12-10 Thread aliak via Digitalmars-d-learn

On Saturday, 8 December 2018 at 14:21:01 UTC, Paul Backus wrote:

On Saturday, 8 December 2018 at 09:57:29 UTC, aliak wrote:

This compiles fine. However, if I change the match template to:

template match(handlers...) {
auto match(alias f)(Holder!f holder) {
return handlers[0](holder);
}
}

Notice the template parameter of the eponymous match is an 
alias now, and the function parameter is typed as a Holder.


The "de-sugared" version of your second `match` function looks 
like this:


template match(handlers...) {
template match(alias f) {
auto match(Holder!f holder) {
return handlers[0](holder);
}
}
}

Notice the second template nested inside the first. That's the 
"non-gloal template" the error is complaining about.


Ah, that's a good way of breaking it down. But ok, so then the 
other version would be lowered to:


template match(handlers...) {
template match(T) {
auto match(T holder) {
return handlers[0](holder);
}
}
}

So now the second template is accessing a T, which is actually a 
Holder!f right? But doing that makes it "work". Even though the 
number of "contexts" needed to execute "handlers[0](holder)" is 
the same, right?


cannot use local f as parameter to non-global template

2018-12-08 Thread aliak via Digitalmars-d-learn
Hi, I'm wondering about why this happens in a certain situation 
and not another. I have the following code:


struct Holder(alias fun) {
alias T = typeof(fun());
T get() { return fun(); }
alias get this;
}

template match(handlers...) {
auto match(T)(T holder) {
return handlers[0](holder);
}
}

void main() {
int f() { return i7 }
auto value = Holder!f().match!(
(int a) => f()
);
}

This compiles fine. However, if I change the match template to:

template match(handlers...) {
auto match(alias f)(Holder!f holder) {
return handlers[0](holder);
}
}

Notice the template parameter of the eponymous match is an alias 
now, and the function parameter is typed as a Holder.


The error you get is basically because of bug 5710 [0] I guess. 
But I'm confused as to why the same thing doesn't then happen 
when using match(T) as opposed to match(alias f)?


I can work around it by have a template constraint on match of 
course. But still curious why one version works and the other 
not, they both have to access the same frame+context data at the 
end of the day.



[0]: https://issues.dlang.org/show_bug.cgi?id=5710


Re: Why does nobody seem to think that `null` is a serious problem in D?

2018-12-02 Thread aliak via Digitalmars-d-learn

On Saturday, 1 December 2018 at 19:02:54 UTC, H. S. Teoh wrote:


In the above contrived example, Artin's conjecture is implied 
by the Riemann hypothesis, so the second if statement would 
only run if p is initialized. But there is no way the compiler 
is going to be able to deduce this, especially not during 
compile time. So it is not possible to correctly flag p as 
being initialized or not when it is dereferenced.


Therefore, leaving it up to the compiler to detect 
uninitialized variables is unreliable, and therefore any code 
that depends on this cannot be trusted. Code like the above 
could be exploited by a sufficiently sophisticated hack to make 
the uninitialized value of p coincide with something that will 
open a security hole, and the compiler would not be able to 
reliably warn the programmer of this problem.


Uninitialized variables are *not* a good thing, contrary to 
what the author of the article might wish to believe.



T


If a compiler were to issue warnings/error for uninitialized 
variables. Then that example would be a compiler error. The logic 
would just be that not all code paths lead to an initialized 
variable, therefor *p++ is not guaranteed to be initialized - 
i.e. error. Swift takes this approach.


Cheers,
- Ali


Re: D is supposed to compile fast.

2018-11-26 Thread aliak via Digitalmars-d-learn

On Monday, 26 November 2018 at 03:09:03 UTC, Mike Parker wrote:
I mean, can you think of any module in the 
Python/Javascript/C# standard library that simply including it 
will swell your program to the point it can't compile? I'm not 
an omnipotent master programmer, but as a professional, I 
can't recall ever having this situation in another library or 
language.


Have you reached the point in D where you can't compile?


I thought people had reached that point already: 
https://forum.dlang.org/post/mailman.3134.1517944133.9493.digitalmar...@puremagic.com


I remember reading about a never ending for loop as well. Because 
of the way ctfe has to be handled "purely" without mutations, 
every change is a new allocation (but i could be remembering 
wrong). So just a large enough for loop because "uncompliable". 
And this is just time, the memory consumption is also quite large 
no?


I think there are some caveats which are not mentioned when it 
comes to the fastness of the compiler. I remember last year's 
advent of code, I wanted to do everything at compile time, but at 
some point I thought, no, this small piece of code is taking way 
too long. Not worth it. And me mate's Go code was "consistently" 
fast.


Re: Why does nobody seem to think that `null` is a serious problem in D?

2018-11-22 Thread aliak via Digitalmars-d-learn

On Wednesday, 21 November 2018 at 23:27:25 UTC, Alex wrote:
Nice! Didn't know that... But the language is a foreign one for 
me.


Nevertheless, from what I saw:
Shouldn't it be
var x: C?
as an optional kind, because otherwise, I can't assign a nil to 
the instance, which I can do to a class instance in D...
and if it is, it works in the same manner as C#, (tried this 
out! :) )


This is true. But then the difference is that you can't* call a 
method on an optional variable without first unwrapping it (which 
is enforced at compile time as well).


* You can force unwrap it and then you'd get a segfault if it 
there was nothing inside the optional. But most times if you see 
someone force unwrapping an optional it's a code smell in swift.




Comparing non-optional types from swift with classes in D is... 
yeah... hmm... evil ;)


Hehe, maybe in a way. Was just trying to show that compilers can 
fix the null reference "problem" at compile time. And that flow 
analysis can detect initialization.




And if you assume a kind which cannot be nil, then you are 
again with structs here...


But I wondered about something different:
Even if the compiler would check the existence of an 
assignment, the runtime information cannot be deduced, if I 
understand this correctly. And if so, it cannot be checked at 
compile time, if something is or is not null. Right?


Aye. But depending on how a language is designed this problem - 
if you think it is one - can be dealt with. It's why swift has 
optionals built in to the language.





Re: Why does nobody seem to think that `null` is a serious problem in D?

2018-11-21 Thread aliak via Digitalmars-d-learn

On Wednesday, 21 November 2018 at 17:46:29 UTC, Alex wrote:

compiled against 4.6.1 Framework.

However, of course, there is a NullReferenceException, if c 
happens to be null, when calling baz.


So the difference is not the compiler behavior, but just the 
runtime behavior...


How could the compiler know the state of Random anyway, before 
the program run.


The compiler would not be able to prove that something was 
initialized and hence could give an error. Maybe c# doesn't do it 
but swift certainly does:


class C {
func baz() {}
}

func f() {
var x: C
if Int.random(in: 0 ..< 10) < 5 {
x = C()
}
x.baz()
}

error: variable 'x' used before being initialized



Re: Why does nobody seem to think that `null` is a serious problem in D?

2018-11-20 Thread Aliak via Digitalmars-d-learn

On Tuesday, 20 November 2018 at 15:29:50 UTC, Kagamin wrote:

On Tuesday, 20 November 2018 at 11:11:43 UTC, aliak wrote:

This only applies to little scripts and unittests maybe.

Not when you're writing any kind of relatively larger 
application that involves being run for longer or if there's 
more possible permutations of your state variables.


Umm... if you write a larger application not knowing what is a 
reference type, you're into lots and lots of problems.


I’m not sure I understood your point? I was saying that you don’t 
necessarily hit your null dereference within a couple of seconds.


Re: Why does nobody seem to think that `null` is a serious problem in D?

2018-11-20 Thread aliak via Digitalmars-d-learn

On Monday, 19 November 2018 at 21:39:22 UTC, Adam D. Ruppe wrote:
On Monday, 19 November 2018 at 21:23:31 UTC, Jordi Gutiérrez 
Hermoso wrote:

What's the reasoning for allowing this?


The mistake is immediately obvious when you run the program, so 
I just don't see it as a big deal. You lose a matter of 
seconds, realize the mistake, and fix it.


This only applies to little scripts and unittests maybe.

Not when you're writing any kind of relatively larger application 
that involves being run for longer or if there's more possible 
permutations of your state variables.





Re: Why does nobody seem to think that `null` is a serious problem in D?

2018-11-19 Thread aliak via Digitalmars-d-learn
On Tuesday, 20 November 2018 at 03:24:56 UTC, Neia Neutuladh 
wrote:
On Tue, 20 Nov 2018 00:30:44 +, Jordi Gutiérrez Hermoso 
wrote:
On Monday, 19 November 2018 at 21:57:11 UTC, Neia Neutuladh 
wrote:


Programmers coming from nearly any language other than C++ 
would find it expected and intuitive that declaring a class 
instance variable leaves it null.


What do you think about making the syntax slightly more 
explicit and warn or possibly error out if you don't do it 
that way?


The prevailing idea is that warnings are either non-problems, 
in which case they shouldn't be emitted, or things you really 
need to fix, in which case they should be errors.


Things that are sometimes errors can be left to lint tools.


Either

   SomeClass c = null;

or

   SomeClass c = new SomeClass();

and nothing else.


That would work, though it would be mildly tedious.

However, the general philosophy with D is that things should be 
implicitly initialized to a default state equal to the `.init` 
property of the type. That default state can be user-defined 
with structs, but with other types, it is generally an 'empty' 
state that has well-defined semantics. For floating point 
values, that is NaN. For integers, it's 0. For arrays, it's a 
null array with length 0. For objects and pointers, it's null.


Nulls/Nones are always a big gap in a language's type system. 
A common alternative is to have some Option/Maybe type like 
Rust or Haskell or D's Variant.


Variant is about storing arbitrary values in the same variable. 
Nullable is the D2 equivalent of Option or Maybe.



How about making that required to plug the null gap?


That's extremely unlikely to make it into D2 and rather 
unlikely to make it into a putative D3. However, if you feel 
strongly enough about it, you can write a DIP.


I've used Kotlin with its null safety, and I honestly haven't 
seen benefits from it. I have seen some NullPointerExceptions 
in slightly different places and some NullPointerExceptions 
instead of empty strings in log messages, but that's it.


Think this would highly depend on your usecase. Having crashing 
mobile apps mostly leads to bad reviews because it's a UX 
nightmare for e.g. And with webservices it's a pain a lot of the 
times when it just crashes as well (analytics workers for e.g.).


Kotlin's null safety stops you from this quite well as long as 
you don't interface with java libraries - then it's near useless 
because your compiler guarantees go out the window. But Swift... 
so far  ... 


It's also a code review blessing. You just know for sure that 
this code won't crash and the object is "valid" because they've 
properly unwrapped a nullable. I can't even count the number of 
times (and I'd wager there're millions of similar commits) where 
I've put up a commit (during my c++ days) that says "fix crash" 
and the code is just "if(!ptr) { return; }" or a variant of that.


Ok, sorry, I rambled a bit :p

Cheers,
- Ali


Re: Why does nobody seem to think that `null` is a serious problem in D?

2018-11-19 Thread aliak via Digitalmars-d-learn
On Tuesday, 20 November 2018 at 00:30:44 UTC, Jordi Gutiérrez 
Hermoso wrote:
On Monday, 19 November 2018 at 21:57:11 UTC, Neia Neutuladh 
wrote:



[...]


What do you think about making the syntax slightly more 
explicit and warn or possibly error out if you don't do it that 
way? Either


  SomeClass c = null;

or

  SomeClass c = new SomeClass();

and nothing else.


[...]


Nulls/Nones are always a big gap in a language's type system. A 
common alternative is to have some Option/Maybe type like Rust 
or Haskell or D's Variant. How about making that required to 
plug the null gap?


You can give optional (https://code.dlang.org/packages/optional) 
a try and see if that works for you.





Re: How do you debug @safe @nogc code? Can't figure out how to print.

2018-11-18 Thread aliak via Digitalmars-d-learn
On Saturday, 17 November 2018 at 21:56:23 UTC, Neia Neutuladh 
wrote:

On Sat, 17 Nov 2018 21:16:13 +, aliak wrote:
Could do. But it's not scalable. I'd have to comment out all 
the unittests that call the template function with a T that 
allocates inside the @nogc template (if I understood you 
correctly that it)


I meant something like:

void debugln(T...)(T args) @nogc
{
  import std.stdio;
  debug(MyProject) writeln(args);
}

You use that function instead of writeln in your 
@nogc-compatible templates:


void callFunc(alias func)()
{
  debugln("about to call function!");
  func();
  debugln("done calling function!");
}

Then I can write:

@nogc:
void foo() { printf("hello world\n"); }
void main() { callFunc!foo(); }


Aha! I misunderstood what you meant. Yes that's actually simpler 
that what I was doing :D Thanks!


Re: How do you debug @safe @nogc code? Can't figure out how to print.

2018-11-17 Thread aliak via Digitalmars-d-learn
On Saturday, 17 November 2018 at 17:48:43 UTC, Neia Neutuladh 
wrote:

On Sat, 17 Nov 2018 13:55:24 +, aliak wrote:
You can use "debug blah" to hide inside functions that are 
attributed, but when you have an attributed function that 
calls a template, attribtues of which are supposed to be 
inferred, it seems to fail.


You can explicitly mark a templated function as @nogc. If you 
want your function's @nogc-ness inferred, you can pull out the 
debug logging into a separate function and explicitly mark it 
@nogc.


Could do. But it's not scalable. I'd have to comment out all the 
unittests that call the template function with a T that allocates 
inside the @nogc template (if I understood you correctly that it)


Re: How do you debug @safe @nogc code? Can't figure out how to print.

2018-11-17 Thread aliak via Digitalmars-d-learn
On Saturday, 17 November 2018 at 13:46:00 UTC, Nicholas Wilson 
wrote:

On Saturday, 17 November 2018 at 13:13:36 UTC, aliak wrote:
On Friday, 16 November 2018 at 13:21:39 UTC, Stanislav Blinov 
wrote:

auto assumeNoGC(T)(return scope T t) @trusted { /* ... */ }


Sawweet! Thanks, that made the printing possible!

"scope" is const from what I understand right? It works 
without scope as well. So just "return T".


No, `in` used to mean const scope.

scope means roughly "this thing does not escape this function" 
e.g. assigning to global variables.


Righto! Thanks!


Re: How do you debug @safe @nogc code? Can't figure out how to print.

2018-11-17 Thread aliak via Digitalmars-d-learn
On Saturday, 17 November 2018 at 13:43:20 UTC, Stanislav Blinov 
wrote:

On Saturday, 17 November 2018 at 13:13:36 UTC, aliak wrote:


Sawweet! Thanks, that made the printing possible!


You're welcome ;) Still, try a more recent compiler. This works 
fine:


void foo() @nogc {
debug {
import std.stdio;
writefln("%d", 42);
}
}


Yeah that does, but not the code I posted -> 
https://run.dlang.io/is/vH3cFa


You can use "debug blah" to hide inside functions that are 
attributed, but when you have an attributed function that calls a 
template, attribtues of which are supposed to be inferred, it 
seems to fail.


Maybe a bug if it's supposed to work?



"scope" is const from what I understand right? It works 
without scope as well. So just "return T".


No, "scope" means "does not escape scope", i.e. you can't 
assign that argument to some global. The only exception is 
through a return, in which case "return" also needed. Whether 
or not just "return" is sufficient, is a bit out there still 
(AFAIK), between DIP25, DIP1000 and current state of the 
language.
"scope" was implemented for delegates for ages now, exactly to 
allow passing lambdas around without allocating their context 
on the GC heap.


Aha, cool. Thanks!



Re: How do you debug @safe @nogc code? Can't figure out how to print.

2018-11-17 Thread aliak via Digitalmars-d-learn

On Friday, 16 November 2018 at 13:03:40 UTC, Zoadian wrote:

debug {
import std.stdio;
writeln(args);
}


As mentioned in the original post, that does not work.


  1   2   3   >