Re: sumtype 1.0.0

2020-11-17 Thread aliak via Digitalmars-d-announce

On Sunday, 15 November 2020 at 20:05:16 UTC, Paul Backus wrote:
SumType is a generic discriminated union type for modern D. It 
is designed to

be an improved alternative to `std.variant.Algebraic`.

[...]


Alright!!  A 1.0.0 release! Awesome work here!


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: Article: the feature that makes D my favorite programming language

2020-07-27 Thread Aliak via Digitalmars-d-announce

On Saturday, 25 July 2020 at 16:22:52 UTC, H. S. Teoh wrote:
On Sat, Jul 25, 2020 at 01:28:34PM +, Adam D. Ruppe via 
Digitalmars-d-announce wrote:

On Saturday, 25 July 2020 at 11:12:16 UTC, aberba wrote:
> Oop! Chaining the writeln too could have increased the wow 
> factor. I didn't see that.


oh I hate it when people do that though, it just looks off to 
me at that point.


Me too.  It gives me the same creepie-feelies as when people 
write

writeln(x) as:

writeln = x;

Actually, D's lax syntax surrounding the = operator gives rise 
to the following reverse-UFCS nastiness:


	// Cover your eyes (unless you're reverse-Polish :-P)! and 
don't

// do this at home, it will corrupt your sense of good coding
// style!
import std;
void main() {
writeln = filter!(x => x % 3 == 1)
= map!(x => x*2)
= [ 1, 2, 3, 4, 5, 6 ];
}

// Output: [4, 10]


T


Oh my god ... it’s like haskells $ 樂

Why is this allowed?

I mean, ok, it was probably done to allow property syntax. But 
how did this end up being applied to every function?


Can this be fixed?




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: DIP1028 - Rationale for accepting as is

2020-05-27 Thread Aliak via Digitalmars-d-announce

On Wednesday, 27 May 2020 at 02:42:24 UTC, Walter Bright wrote:

On 5/24/2020 6:04 PM, Timon Gehr wrote:
Implicit greenwashing by the compiler is a nuisance that makes 
it harder to do the job correctly and easier to do the wrong 
thing.


You and I are just going to disagree about that.


Unfortunately science and research Doesn't agree with you. 
https://en.m.wikipedia.org/wiki/Default_effect


Re: DIP1028 - Rationale for accepting as is

2020-05-24 Thread aliak via Digitalmars-d-announce

On Sunday, 24 May 2020 at 11:30:53 UTC, Johannes Loher wrote:

On Sunday, 24 May 2020 at 11:25:06 UTC, aliak wrote:

On Sunday, 24 May 2020 at 10:40:11 UTC, Johannes Loher wrote:
does not work). But I admit that it is still a bit weird to 
have 2 different defaults.


Is that any more or less weirder than having functions 
inferred with different attributes based on context?


What exactly are you referring to?


Attribute inference by D, specifically template functions. The 
attributes are inferred based on context (I don't know the exact 
algorithm). So a function f(T)(T) when called can maybe be pure, 
maybe safe, maybe not?


Re: DIP1028 - Rationale for accepting as is

2020-05-24 Thread aliak via Digitalmars-d-announce

On Sunday, 24 May 2020 at 10:40:11 UTC, Johannes Loher wrote:
does not work). But I admit that it is still a bit weird to 
have 2 different defaults.


Is that any more or less weirder than having functions inferred 
with different attributes based on context?




Re: DIP1028 - Rationale for accepting as is

2020-05-22 Thread aliak via Digitalmars-d-announce
First, thank you for the explanation! I have a few observations 
though, mainly that the exception analogy feels like more an 
argument against the DIP than for it. And I also have an 
alternative proposal that might be considered?


On Friday, 22 May 2020 at 01:22:19 UTC, Walter Bright wrote:
This, of course, was incredibly tedious and annoying. So what 
happened?


1. Functions would just do a try-catch(Throwable) and ignore 
the exceptions.

Oops.

2. The Exception Specifications became simply `throws 
Throwable`. Oops.


This is what happens in swift these days:

func g() /*throws*/ {
  do {
try f()
  } catch {}
}

But, it's very rare. And passing something like that in code 
review is very difficult and, almost always, the reviewer will 
ask for comments so other people will know why the laziness (if 
it even really was laziness, sometimes it's the right thing to 
do).


Of course the one big difference between exception specifications 
and @safe is the implied importance; @safe is compiler-enforced 
and has the user's trust, exception specifications are human 
guess work of what are the important exceptions and how varied 
they need to be - it's API design - very hard to get right.


The exception specification becoming "throws Exception", while 
highlights the failure of exception specifications, does so with 
a non-dangerous resolution. I.e. you still need to mark your 
function as throwing, and you still need to at least "try" to 
catch the exception. Even a forced "catch(Exception)" is better 
than nothing and shows where problems can be and encourages 
scrutiny.



How does this relate to safe by default?


That people will use the most convenient solution to get their 
work to compile if the juice is not worth the squeeze?




1. Go through...

2. Annotate...safe by default to be lost.

3. Wrap the call...

4. Edit clibrary.d and make the first line:

@safe:


5. Edit clibrary.d and make the first line @trusted: ?

Which brings me to the proposal of making @safe illegal on 
function prototypes. Reason being that @safe stays compiler 
checked. @trusted maintains it's path and value in hunting down 
memory corruption. extern(Anything) functions cannot lie anymore 
about being compiler-checked.




I submit that, just like with Java, Option 4 is what people 
will reach for,
nearly every time. I've had some private conversations where 
people admitted
this was what they'd do. People who knew it was wrong to do 
that.


If it's @safe by default, and then someone chooses to annotate 
it with @system


Which is the rare case in this scenario right? And 1) there's no 
way to tell if someone made an effort in the case where none are 
marked @system. 2) this is also only for the case of C library 
bindings (reason being that most of my code, and also others' 
code I've seen, has extern(C) functions splattered around various 
D files and not in a dedicated clibrary.d file - is this just me?)


here and there, I'd feel a lot more confident about the 
accuracy of the code
annotations than if it just had @safe: at the top. At least 
they tried.


What is actually accomplished with this amendment if it was 
implemented?


1. Adds a funky, special case rule. It's better to have simple, 
easily
understood rules than ones with special cases offering little 
improvement.


2. Existing, working code breaks.

3. The most likely code fixes are to just make it compile, 
absolutely
nothing safety-wise is improved. The added annotations will be 
a fraud.


D should not encourage "greenwashing" practices like the Java
exception specification engendered. The compiler cannot vet the 
accuracy
of bodyless C functions, and we'll just have to live with that. 
The proposed

amendment does not fix that.

And so, I did not incorporate the proposed amendment to the 
Safe by Default

DIP.


I think there's a failure to understand why explicit greenwashing 
via a deliberate (possibly code reviewed) addition of @safe: at 
the top is worse than a global implicit greenwashing by the 
compiler, ignoring the rare "feel-good-but-can't-be-sure" 
scenario above where some functions are marked as @system, and 
especially given the premise that programmers are lazy.


Also ... error on @safe prototypes?




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: DLS deprecation

2020-04-08 Thread aliak via Digitalmars-d-announce

On Tuesday, 7 April 2020 at 22:20:40 UTC, Laurent Tréguier wrote:

On Tuesday, 7 April 2020 at 20:03:21 UTC, Aliak wrote:
Is what you’re working on shareable information (just out of 
curiosity)?


It's shareable (it's on Github just like DLS); it's a mobile 
app, the Android version is in Kotlin, and the iOS version in 
Swift. I think it's hard to beat native languages for these 
platforms, as they both have tailored APIs and development 
environments (and they are backed by giant companies putting 
lots of resources into them)


Yeah, no doubt, it's always that last 10-20 percent of the way 
you have to go with the non-native languages on those platforms 
that gets you. The downside is the manpower required to maintain 
two platforms.


I've been meaning to give flutter a try though... it seems to be 
catching steam. Only problem is google is "known" for just 
dropping things. But who knows, let's see.


And WildFyre looks very interesting! Good luck with your future 
endeavours!




Re: DLS deprecation

2020-04-07 Thread Aliak via Digitalmars-d-announce

On Tuesday, 7 April 2020 at 19:12:49 UTC, Laurent Tréguier wrote:
I started working on this project to make it more comfortable 
to write D back in 2017, published a VSCode extension a couple 
months later, and continued working on it throughout 2018. In 
2019 however, I slowed down, and eventually, stopped working on 
it.


It was fun, and kept me well occupied for quite some time; but 
I have been working on something else since April of last year, 
and since I don't have any use for D in it, I am not taking 
time to do anything with DLS.


So today, I am deprecating DLS, along with its editor 
extensions. If anyone was using them, be advised that they will 
not have any update or support from now on.


Webfreak is still working on code-d/serve-d from what I gather, 
so hopefully, the handful of people who could be using DLS on 
VSCode can use it instead.


No

DLS was so fast and smooth :(

But ah well. Thanks for all the work and for the heads up!

Is what you’re working on shareable information (just out of 
curiosity)?


Cheers and good luck with the other stuff!


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: DIP 1027---String Interpolation---Format Assessment

2020-03-01 Thread aliak via Digitalmars-d-announce
On Saturday, 29 February 2020 at 14:41:16 UTC, Steven 
Schveighoffer wrote:

On 2/28/20 7:57 PM, aliak wrote:


I actually didn't realize it was a video, thought it was just 
an article! - But anyway, it was just to point out that swift 
lowers to specialized types when it comes to interpolation 
(which is what you and adam are trying to get through). And 
therefor you can detect interpolations being given to you and 
deal with them the way you want and you can do a lot when you 
know you're getting an interpolation. You can create types like


let example: SQLStatment = "select * from blah where a=\(a), 
b=\(b) ... "


I didn't get to this part of the video, but that is indeed 
pretty cool. I'm assuming that this generates placeholders for 
the SQL statement and attaches a and b as parameters?


I'm not sure if it's in the video (I haven't seen the video). But 
it was just an example, implementations would vary I'd assume. 
Here's one from a quick search for e.g.: 
https://github.com/groue/GRDB.swift/blob/4c8574aa4c08ff715ce0e63b38502ac1e8529069/GRDB/Core/SQLInterpolation.swift




However, D cannot do something like this exactly, because 
expressions define the tuple, not how they are used.


Yep, and similarly expressions define the interpolation pattern 
in swift, not how they are used as well. So the tuple thing is 
also pretty sweet! I'd imaging you'd be able to do something like:


auto sql = SQLStatment(i"select * from blah where a=$a, b=$b");

where

struct SQLStatement {
  string formatted;
  // What template magic is needed here? This is where I get a 
little worried.
  this(S : _interpolated_object!Specs, Specs, Args...)(S s, Args 
args) {

// build formatted...?
  }
  alias formatter this;
}



But this is possible (with the proposed DIP or ours):

alias sql = "select * from blah where a=$a, b=$b"; // aliased 
to the tuple


connection.query(sql);
a = 5;
connection.query(sql); // another query with `a` set to 5 now.


Yeah, and that's pretty sweet too!



Swift can do some pretty cool things due to the type resolver, 
but it comes at a cost (some expressions that are trivial in D 
make the compiler complain about them taking too long to 
resolve).


Yeah, swift ha a few problems with its type solver during 
semantic I think.


let a: Double = -(1 + 2) + -(3 + 4) + -(5)

Will fail to compile on my machine, and you need to break it up.

But, on the other hand, swift's constraint solver avoids 
backwards situations like:


void f(bool) { "bool".writeln; }
void f(int) { "int".writeln; }
enum A { one }
void main() {
f(0);
f(A.one);
}

And:

void main() {
struct B {
B opBinary(string op : "+")(int b) { return this; }
}
static if (is(typeof(B.init + size_t.init))) {
size_t x = 1;
B b1, b2;
b1 = b2 + x; // fails here
}
}




I also didn't realize the takeaway would be that swift does 
appending - which by the way, is not completely accurate. And 
it does not generate temporaries (unless you mean passing in 
parameters? There's no way around that if you want to end up 
with a string based on runtime values - it'll have to be 
processed in to a string somewhere).


For example, the part where they change the date formatting, 
they use a date formatter to generate a string for the date, 
which then is appended to the string interpolation.


Yes, you need to allocate a string. But you should only 
allocate one.


Generating temporaries is not a constraint that the interpolation 
system puts on you.




You can also get an interpolated string directly in to "print 
processing" if you wanted to: 
https://swift.godbolt.org/z/muAzgm


Hm... I'm not too impressed with this when compared to 
writefln(i"hello $("hello"), $x"); which works without such 
extra mechanics or strange call syntax.


Indeed.



Re: DIP 1027---String Interpolation---Format Assessment

2020-02-28 Thread aliak via Digitalmars-d-announce
On Friday, 28 February 2020 at 19:16:08 UTC, Steven Schveighoffer 
wrote:

On 2/28/20 5:17 AM, Jacob Carlborg wrote:
On Friday, 28 February 2020 at 03:10:48 UTC, Walter Bright 
wrote:


I don't know Swift, but this looks like the "generate strings 
and concatenate them" approach.


No, it basically lowers to bunch of method calls. Here's an 
example of how it could look like with D syntax:


auto a = 3;
auto b = i"foo $a bar";

Could be lowered to:

auto _temp = StringInterpolation(8 /* literal capacity */, 1 
/* interpolation count */);

_temp.appendLiteral("foo ");
_temp.appendInterpolation(a);
_temp.appendLiteral(" bar");
auto b = _temp.toString();


I think Walter's point is that swift is still appending strings 
and then returning that. This requires allocations, and is not 
as preferable as directly processing the data. Not only that, 
but it's generating temporary strings just to add them to the 
larger thing that will be printed (I'm assuming this is not 
just a big string but an array/list, due to the beginning of 
the video and s1+s2+s3+s4).


I'd much prefer for example, printing using DIP1027 than 
constructing a string (even if the memory is reasonably fast, 
like malloc) just to throw it away.


I watched a lot of that video, it didn't impress me much. I use 
swift interpolation strings quite a bit, and they are useful. 
But I think D's will be much more performant and more 
straightforward for hooking (if they ever get in).


-Steve


I actually didn't realize it was a video, thought it was just an 
article! - But anyway, it was just to point out that swift lowers 
to specialized types when it comes to interpolation (which is 
what you and adam are trying to get through). And therefor you 
can detect interpolations being given to you and deal with them 
the way you want and you can do a lot when you know you're 
getting an interpolation. You can create types like


let example: SQLStatment = "select * from blah where a=\(a), 
b=\(b) ... "


I also didn't realize the takeaway would be that swift does 
appending - which by the way, is not completely accurate. And it 
does not generate temporaries (unless you mean passing in 
parameters? There's no way around that if you want to end up with 
a string based on runtime values - it'll have to be processed in 
to a string somewhere).


You can also get an interpolated string directly in to "print 
processing" if you wanted to: https://swift.godbolt.org/z/muAzgm


And for the record I think the tuple generation is great as well. 
I highly doubt it'll be easier to use than swift (case in point: 
no need to call idup or whatever to convert to a string, since a 
string in swift is a type that is "interpolation aware"). Hook in 
to maybe, it depends on the APIs provided to hook in to them. An 
opaque type will not be easier to hook in to and a "concrete" 
named interface (aka protocol in swift).


When it comes to printing it really doesn't matter if you 
construct a string on the stack and pass it along. You're IO 
bound anyway.


By the by: if you or anyone is interested in swift's string 
interpolation design decisions (for inspiration or whatever) then 
here's the full discussion: 
https://forums.swift.org/t/string-interpolation-revamp-design-decisions/12624


One very interesting thing of note is the way they combine named 
arguments with string interpolations.


Also another note, this tuple expansion should really not be 
called string interpolation, since it does not result in a string 
:/ It's more string expansion really.


Re: DIP 1027---String Interpolation---Format Assessment

2020-02-27 Thread Aliak via Digitalmars-d-announce
On Thursday, 27 February 2020 at 18:19:03 UTC, Adam D. Ruppe 
wrote:
On Thursday, 27 February 2020 at 17:41:12 UTC, Petar Kirov 
[ZombineDev] wrote:

[...]


Right, that actually is what my old proposal was (and I fought 
for it on the first few pages of the last thread), and this is 
very close to what C# does successfully, but I decided to leave 
it behind because:


[...]


Should this maybe be called tuple interpolation instead of string 
interpolation? It is unique to D it seems, this feature that is. 
And then it might help with the “wait why can I not assign an 
interpolated string to a string”?? And on top maybe change the 
prefix to t instead of i?


Re: DIP 1027---String Interpolation---Format Assessment

2020-02-27 Thread aliak via Digitalmars-d-announce
On Thursday, 27 February 2020 at 09:34:23 UTC, Walter Bright 
wrote:

On 2/26/2020 7:41 AM, Arine wrote:

Yah, what's unwanted about that?


1. unwanted extra string allocation
2. poor performance
3. doesn't work with printf
4. doesn't work with writef
5. non-default formats require extra temp strings to be 
generated


Pretty sure he meant that this call:

int a;
CreateWindow(i"Title $a");

Would call CreateWindow like:

CreateWindow("Title %s", a);

Which is what is unwanted.

Btw: with the adam-steve-twist you fix everything that is 
unwanted, including enforcing explicitness when someone wants it 
to act as a string, without the danger of mistakenly calling the 
wrong overloads of functions because of switching to string 
interpolation.


And it seems to me there's precedent in typeid

i.e. typeid is an construct in D that lowers to a TypeInfo type, 
which is defined somewhere (is that object.d?) Anyway. The same 
would happen with the interpolated string.


Btw: Swift does this for string interpolation and it works very 
well -> 
https://www.hackingwithswift.com/articles/178/super-powered-string-interpolation-in-swift-5-0


Re: DIP 1027---String Interpolation---Format Assessment

2020-02-26 Thread aliak via Digitalmars-d-announce

On Tuesday, 25 February 2020 at 16:04:59 UTC, Arine wrote:
``How to distinguish a different type? Use a different type. 
No, is there another simpler way to do that instead?``


Is this really the line of thinking going on here? It seems 
Walter has these arbitrary rules he's following which led up to 
the impractical and buggy solution that was DIP1027. Rules 
aren't meant to be followed blindly.


Calm down. I didn't ask how to distinguish a type. I asked how to 
prevent a behaviour. There's a slight difference. If you 
misunderstood that then maybe I just didn't communicate that 
properly.


Re: DIP 1027---String Interpolation---Format Assessment

2020-02-26 Thread aliak via Digitalmars-d-announce
On Wednesday, 26 February 2020 at 09:45:55 UTC, Walter Bright 
wrote:

On 2/25/2020 1:36 AM, aliak wrote:
This may have already been answered in the other threads, but 
I was just wondering if anyone managed to propose a way to 
avoid this scenario with DIP1027?


void f(string s, int i = 0);
f(i"hello $a"); // silent unwanted bahviour.

?


It is lowered to:

  f("hello %s", a);

as designed. I don't know what's unwanted about it.


It's unwanted because the lowering calls a function that was not 
intended with values that were unintended. You can take this 
article: https://dlang.org/articles/hijack.html and replace it 
with that lowering behaviour, and have the exact same story.


Also unwanted because of what string interpolation means (ref 
wikipedia and all other languages).




Re: DIP 1027---String Interpolation---Format Assessment

2020-02-25 Thread Aliak via Digitalmars-d-announce

On Tuesday, 25 February 2020 at 13:04:41 UTC, Adam D. Ruppe wrote:

On Tuesday, 25 February 2020 at 09:36:25 UTC, aliak wrote:

[...]


Yes, that is the key impetus of our amendment, which I also 
wrote up on a gist weeks ago and it is now on github too! 
https://github.com/dlang/DIPs/pull/186


[...]


I should’ve been more specific  I was wondering if the same 
could be achieved without a introducing a new aggregate type!


Re: DIP 1027---String Interpolation---Format Assessment

2020-02-25 Thread aliak via Digitalmars-d-announce

On Tuesday, 25 February 2020 at 07:07:50 UTC, Walter Bright wrote:
All DIP1027 did was turn an istring into a tuple. That's it. 
The user can then do whatever they want with the tuple, 
including overloading a custom function based on the tuple 
arguments. DIP1027 did not actually do ANY formatting at all.


This may have already been answered in the other threads, but I 
was just wondering if anyone managed to propose a way to avoid 
this scenario with DIP1027?


void f(string s, int i = 0);
f(i"hello $a"); // silent unwanted bahviour.

?


Re: DIP 1027---String Interpolation---Format Assessment

2020-02-24 Thread aliak via Digitalmars-d-announce

On Monday, 24 February 2020 at 21:23:43 UTC, Adam D. Ruppe wrote:
On Monday, 24 February 2020 at 20:55:16 UTC, Walter Bright 
wrote:

and proposed a lowering to:

> i"your hex data is ${%02x}someByte"
>
> (_d_interpolated_string!("your hex data is ",
> _d_interpolated_format_spec("%02x"))(), someByte)


Do you understand that `_d_interpolated_string` and 
`_d_interpolated_format_spec` are to be defined EXCLUSIVELY 
inside druntime?


There's nothing user-defined about this.


Does that mean no betterC support if it's in druntime?

Actually, was it different with the pure tuple approach in 
DIP1027?


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: Bolts 1.4 - added experimental signatures for D

2020-02-19 Thread aliak via Digitalmars-d-announce

On Friday, 14 February 2020 at 21:33:01 UTC, aliak wrote:

Hi,
[...]

Cheers,
- ali


Ok, you can now model an actual input range with most of it's 
caveats:


interface InputRange(T) {
@property bool empty();
@property T front();
@ignoreAttributes void popFront();
}

struct MyRange {
mixin Models!(InputRange!int);
}

source/bolts/experimental/signatures.d(341,5): Error: static 
assert:  "Type MyRange does not comply to signature 
InputRange!(int)

  Missing identifier empty of type bool.
  Missing identifier front of type int.
  Missing identifier popFront of function type void().
  source/bolts/experimental/signatures.d(8): <-- Signature 
InputRange!(int) defined here.

  source/bolts/experimental/signatures.d(15): <-- Checked here."

To fix the errors you'd need a name called empty that returns a 
bool (i.e. is a member variable or a property function). Same 
with front. And for popFront it can be a function with whichever 
attributes attached to it.


Not sure what to do with a range model that has "ref T front". 
Maybe an @ignoreRefness attribute?


Cheers


Bolts 1.4 - added experimental signatures for D

2020-02-14 Thread aliak via Digitalmars-d-announce

Hi,

I've released an experimental implementation of the concept of 
traits/signatures/protocols-ish. The basics seems to work 
decently well, with very decent error messages e.g.:


source/bolts/experimental/signature.d(111,17): Error: static 
assert:  "Type Y is missing the following members of enum X: 
["three"]
  source/bolts/experimental/signature.d(156): <-- Signature Sig 
defined here.

  source/bolts/experimental/signature.d(166): <-- Mixed in here."

Package: https://code.dlang.org/packages/bolts
Implementation PR: https://github.com/aliak00/bolts/pull/6/files

I'm not sure about a few things thought and wouldn't mind some 
feedback.


1. Malleable properties. Take input ranges for example:

struct InputRange(T) {
  bool empty() { return true; }
  // other members...
}

This works:

struct SomeRange(T) {
  mixin ModelsSignature!(InputRange!T));
  bool empty() { return true; }
  // other members...
}

But for variations such as infinite ranges, this will not work

struct SomeRange(T) {
  mixin ModelsSignature!(InputRange!T));
  enum empty = false;
  // other members...
}

The way I'm thinking of handling it right now is by using UDAs?

struct InputRange(T) {
  @onlyAssign
  bool empty;
  // other members...
}

So then the mixin template Models will check if a name has the 
UDA onlyAssign attached to it, and if so it will be more lenient 
with the SomeRange struct.


Does anyone have any other suggestions?

2. Naming. Not very happy with onlyAssign, and also 
ModelsSignature. Any bikesheds? :p


3. Having to implement functions. Like in the InputRange 
signature above, I had to implement function empty. So for that 
I'm thinking templates? Something like:


struct Signature {
  mixin Function!("f", int(int, int));
}

Or the like? And the mixin would put in a stubbed function named 
"f" that returns int.init


Opinions?

Cheers,
- ali


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: release of code-d 0.21.0 + serve-d 0.5.1

2019-11-14 Thread Aliak via Digitalmars-d-announce

On Wednesday, 13 November 2019 at 23:17:21 UTC, WebFreak001 wrote:

hi everyone,

after a long time there is finally a new update for my Visual 
Studio Code extension "code-d"


[...]


Wow! Well done on the effort!!


Re: D for microservices: ldc, rdmd, dub now available on Alpine x86_64

2019-11-05 Thread aliak via Digitalmars-d-announce

On Tuesday, 5 November 2019 at 02:16:28 UTC, Mathias Lang wrote:

Hi all,
Recently there have been inquiries about support for D on 
Alpine Linux, a distribution mostly used in combination with 
Docker to create lightweight container images for microservices.


[...]


This is great! Much thanks to all for all the work towards this!


Re: When will you announce DConf 2020?

2019-11-03 Thread Aliak via Digitalmars-d-announce

On Sunday, 3 November 2019 at 00:51:38 UTC, Murilo wrote:
Hi guys. I'm eager to attend the next DConf, which is why I'm 
already planning everything about how I will travel from Brazil 
to the UK(or maybe Germany). When will you announce the place 
and date of the next DConf?


Hey! That’s awesome! The conferences are usually around May. And 
the announcements and finalization don’t really have a specific 
date but usually around Jan/feb ish (just did a quick search for 
the different years).


Cheers
Ali




Re: Átila's Vision of D's Future

2019-10-16 Thread Aliak via Digitalmars-d-announce

On Wednesday, 16 October 2019 at 12:11:23 UTC, bachmeier wrote:

On Wednesday, 16 October 2019 at 09:46:49 UTC, aliak wrote:
On Tuesday, 15 October 2019 at 20:33:32 UTC, Walter Bright 
wrote:

On 10/15/2019 6:11 AM, Mike Parker wrote:

Reddit:
https://www.reddit.com/r/d_language/comments/di7gwl/%C3%A1tilas_vision_of_ds_future/


It's also on the front page of hacker news:

https://news.ycombinator.com/news


It's better to link straight to an item on hackernews as links 
on the front page disappear very fast.


https://news.ycombinator.com/item?id=21257943

Cheers,
- Ali


You can do that once it's no longer on the front page, but if 
you do that while it's on the front page the post will be 
deleted.


So linking to this item on the front page will have it deleted?

https://news.ycombinator.com/item?id=21274511

I’d be surprised!



Re: Átila's Vision of D's Future

2019-10-16 Thread Aliak via Digitalmars-d-announce

On Wednesday, 16 October 2019 at 17:55:24 UTC, Meta wrote:

On Wednesday, 16 October 2019 at 09:46:49 UTC, aliak wrote:
It's better to link straight to an item on hackernews as links 
on the front page disappear very fast.


https://news.ycombinator.com/item?id=21257943

Cheers,
- Ali


HN has this (IMO) ridiculous policy of going to great lengths 
to prevent upvotes from people following a direct link to the 
post.


Hmm. Are you sure? I just went to that link I put up there and 
upvoted. Is this documented somewhere?


Re: Átila's Vision of D's Future

2019-10-16 Thread aliak via Digitalmars-d-announce

On Tuesday, 15 October 2019 at 20:33:32 UTC, Walter Bright wrote:

On 10/15/2019 6:11 AM, Mike Parker wrote:

Reddit:
https://www.reddit.com/r/d_language/comments/di7gwl/%C3%A1tilas_vision_of_ds_future/


It's also on the front page of hacker news:

https://news.ycombinator.com/news


It's better to link straight to an item on hackernews as links on 
the front page disappear very fast.


https://news.ycombinator.com/item?id=21257943

Cheers,
- Ali


Re: CodinGame adds support for 2 new programming languages

2019-10-02 Thread Aliak via Digitalmars-d-announce

On Thursday, 26 September 2019 at 15:58:46 UTC, Andre Pany wrote:

Hi,

Based on the voting results 
(https://www.codingame.com/forum/t/poll-what-programming-language-would-you-like-codingame-to-support-next) Codingame is currently adding 2 new programming languages, Type Script and D!


Thanks for your votes, they made it happen!

Kind regards
Andre


That is fantastic! And great job for being on top of it! :D


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


Re: LDC 1.17.0-beta1

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

On Saturday, 10 August 2019 at 15:51:28 UTC, kinke wrote:

Glad to announce the first beta for LDC 1.17:


Nice!



* Based on D 2.087.1+ (stable from some days ago).
  * The DMD fix wrt. 'local templates can now receive local


Are there plans to port this or is it just too unworkable as is? 
And if it is too unworkable is there anything that can be done to 
get it in?



symbols' hasn't been ported yet.
* LLVM upgraded to v8.0.1.
* Fix for v1.16.0 regression when returning void expressions.
* Don't ignore some options like `-lowmem` in response files.
* Proper Unicode support for LDC/LDMD itself on Windows.
* More fixes...

Full release log and downloads: 
https://github.com/ldc-developers/ldc/releases/tag/v1.17.0-beta1


Please help test, and thanks to all contributors!





Re: optional 1.0.0 beta with "or/frontOr/Throw" range utilities

2019-07-30 Thread aliak via Digitalmars-d-announce

On Tuesday, 30 July 2019 at 12:58:08 UTC, Jesse Phillips wrote:

On Monday, 29 July 2019 at 22:17:20 UTC, aliak wrote:

* NotNull has been removed


Why was it removed. It seems like this would be nice to have 
for class and pointers.


I personally didn't find use for it, too much friction to use. I 
have not gotten the impression that it's useful form others 
either? If people were using it I'll gladly put it back in as a 
subpackage or something (or just make another package).




Re: optional 1.0.0 beta with "or/frontOr/Throw" range utilities

2019-07-30 Thread aliak via Digitalmars-d-announce

On Tuesday, 30 July 2019 at 04:18:28 UTC, Les De Ridder wrote:

On Monday, 29 July 2019 at 22:17:20 UTC, aliak wrote:

[...]

* dispatch() has been renamed to oc(); "optional chain"


Why not 'chain()' or 'optionalChain()'?


Only because chain is in range and optionalChain is too long 路‍♂️.


Re: optional 1.0.0 beta with "or/frontOr/Throw" range utilities

2019-07-29 Thread Aliak via Digitalmars-d-announce

On Monday, 29 July 2019 at 22:17:20 UTC, aliak wrote:

Hi




Link: https://code.dlang.org/packages/optional


optional 1.0.0 beta with "or/frontOr/Throw" range utilities

2019-07-29 Thread aliak via Digitalmars-d-announce

Hi,

After some feedback from the community [0], I'm happy to finally 
get the optional package to a 1.0.0 version. There is one 
breaking change with how pointer semantics behave, in that the 
previous version treated some!(int*)(null) as a non-empty 
optional, and some!Class(null) as an empty optional. These are 
both now treated as empty optionals.


Compilation changes include:
* orElse has been split in to "or" and "frontOr"
* dispatch() has been renamed to oc(); "optional chain"
* NotNull has been removed
* unwrap has been removed

Additions include:
* frontOrThrow: if there's no front of range then it will throw.
* or/frontOr work with any range, and Nullable!T.
* match will resolve to void if any of the handlers return void.

Added a whole bunch of "safety" checks, so CI runs with dip1000 
and dip25 enabled, and uses LLVM's address sanitizer. I still 
don't know how to deal with auto ref return values [1] so if 
anyone has any tips...


I'll remove the beta status after a few weeks if there're no 
issues.


Cheers,
- ali

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

[1] https://issues.dlang.org/show_bug.cgi?id=20084


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.


Re: Redis client hunt-redis RC1 released

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

On Tuesday, 23 July 2019 at 07:57:06 UTC, zoujiaqing wrote:

A Powerfull Redis client library for D Programming Language.

Porting from java Jedis, support redis 3.x / 4.x all features 
and 5.x

 some features.

[...]


Awesome! Huntlabs seem to really be putting in a lot of work on 
backend d-dev! Are there any websites/services you know of that 
are using the entire framework?


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: bolts meta programming library version 1.0.0 - including the from idiom

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

On Wednesday, 17 July 2019 at 16:29:34 UTC, victoroak wrote:

On Monday, 15 July 2019 at 11:13:10 UTC, aliak wrote:
I've been using a set of meta tools for a while now, so 
decided to release it as 1.0.0 with a few enhancements chucked 
on.


[...]


Looks nice. Though, I see it has some problems that stuck me 
before. The traits isFunctionOver and isUnaryOver can't handle 
lambdas that receive arguments by ref like:


struct S {}
static assert(isFunctionOver!((ref s) => s, S));

I wish ref was part of the type in D, so we could pass ref S as 
template parameters. I could pass as string but it's error 
prone and not really elegant.


Ooh! Thanks!

Fixed and released v1.0.1


Re: bolts meta programming library version 1.0.0 - including the from idiom

2019-07-15 Thread Aliak via Digitalmars-d-announce

On Monday, 15 July 2019 at 21:20:16 UTC, Atila Neves wrote:

On Monday, 15 July 2019 at 11:13:10 UTC, aliak wrote:
I've been using a set of meta tools for a while now, so 
decided to release it as 1.0.0 with a few enhancements chucked 
on.


[...]


Nice! I'm working on something similar but with a different 
goal.


Thanks! How’s the thing similar and what’s the goal (if you don’t 
mind me asking)?


bolts meta programming library version 1.0.0 - including the from idiom

2019-07-15 Thread aliak via Digitalmars-d-announce
I've been using a set of meta tools for a while now, so decided 
to release it as 1.0.0 with a few enhancements chucked on.


Two of the highlights are the non-eponymous "member" and "iz" 
templates, which are shown below with some code. The library also 
includes the "from" template because I tend to use that 
everywhere.


Docs: https://aliak00.github.io/bolts/bolts.html
Github: https://github.com/aliak00/bolts
Package: https://code.dlang.org/packages/bolts

Current issues include:

1) that I'm not completely sure about the behaviour of the 
copy-constructor traits - I've decided to pretend post blots 
don't exist and marked the library as requiring dmd frontend 
2.086 and above.


2) It's an ongoing battle with D to normalize parameters because 
traits return tuples, or string, or tuples of strings, or alias 
tuples, etc. And some traits take symbols, while others take 
strings, etc. One of the goals is to make this library a little 
more consistent and try and keep it that way. I will break things 
to make things consistent (is my intention).


3) Naming - e.g. why are some things in std.meta capitalized 
(i.e. Filter) and others camel-cased with a static prefix - i.e. 
staticMap? What would be the consistent thing to do? I currently 
have a staticZip in there, should it just be Zip?


Some sample code:

unittest {
import bolts;

int i;
class C { void f0() {} int f1(int) { return 0; } }
static struct S { void f0() {} int f1(int) { return 0; } 
@property void set(int) {} }


pragma(msg, from.std.allSatisfy!(iz!int.of, 3, 4, int, i)); 
// true
pragma(msg, from.std.Filter!(isNullable, int*, C, S)); // 
(int*, C)


// Member functions
pragma(msg, memberFunctionsOf!S.asStrings); // tuple("f0", 
"f1")
pragma(msg, memberFunctionsOf!C.asAliases); // tuple(f0, f1, 
toString, toHash, opCmp, opEquals, factory)


// member template
pragma(msg, member!(S, "f0").exists); // true
pragma(msg, member!(S, "f0").protection); // public
pragma(msg, member!(S, "f0").isProperty); // false
pragma(msg, member!(S, "set").propertySemantics); // 
PropertySemantics.w


// iz template
static struct OldS {
this(this) {}
}
static struct NewS {
this(ref NewS s) {}
}
pragma(msg, iz!S.triviallyCopyConstructable); // yes
pragma(msg, iz!OldS.triviallyCopyConstructable); // no 
because post-blit
pragma(msg, iz!OldS.copyConstructable); // no because post 
blit


pragma(msg, iz!NewS.copyConstructable); // yes
pragma(msg, iz!NewS.nonTriviallyCopyConstructable); // yes

// meta fun with packs and zip
{
alias a = AliasPack!(1, 2, 3);
alias b = AliasPack!(4, 5, 6);
alias c = AliasPack!(7, 8, 9);

alias d = staticZip!(a, b, c);

static assert(d.length == 3);

static assert(d.Unpack[0].equals!(1, 4, 7));
static assert(d.Unpack[1].equals!(2, 5, 8));
static assert(d.Unpack[2].equals!(3, 6, 9));

static assert(AliasPack!(d.UnpackDeep).equals!(1, 4, 7, 
2, 5, 8, 3, 6, 9));

}
}

Cheers,
- Ali



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: Cushion the state transition table library released

2019-06-27 Thread aliak via Digitalmars-d-announce

On Wednesday, 26 June 2019 at 15:20:45 UTC, ag0aep6g wrote:

On 26.06.19 16:01, SHOO wrote:

[...]


You've got bad `@trusted`s.

Quoting from there:

[...]


No.


[...]

[...]

[...]


Noo.


[...]

[...]

[...]

[...]

[...]

[...]

[...]


Nooo.


[...]

[...]

[...]

[...]

[...]

[...]

[...]


N.


[...]

[...]

[...]

[...]>   EventContainer   _events;
[...]

[...]

[...]

[...]

[...]

[...]

[...]

[...]


No.


I really love that you go in to the code and find things like 
this, especially when it comes to abuse of @trusted, but maybe a 
little explanation as to why would be more helpful to the OP ;)


Re: LDC 1.16.0

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

On Thursday, 20 June 2019 at 17:36:45 UTC, kinke wrote:

Glad to announce LDC 1.16:

* Based on D 2.086.1.
* Non-Windows x86: Faster `real` versions of 
std.math.{tan,expi}.

* Windows: Fix linking DLLs with MinGW-based libs.
* WebAssembly: No need for an explicit `-L--export-dynamic` 
anymore.


Full release log and downloads: 
https://github.com/ldc-developers/ldc/releases/tag/v1.16.0


Thanks to all contributors!


Cool! Thanks kinke! <3


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: Beta 2.087.0

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

On Sunday, 16 June 2019 at 22:47:57 UTC, Martin Nowak wrote:
Glad to announce the first beta for the 2.087.0 release, ♥ to 
the 66 contributors.


http://dlang.org/download.html#dmd_beta 
http://dlang.org/changelog/2.087.0.html


As usual please report any bugs at
https://issues.dlang.org

-Martin


Wow! Very good stuff in this one!
Bug 5710, a dip 1000 phobos, and alias templates parameters match 
types!


Thanks!


Optional 0.15.0 now compatible with vibe-d, @safe, @nogc, betterC.

2019-06-04 Thread aliak via Digitalmars-d-announce

Hey,

I've recently released optional 0.15.0 [0] that includes support 
for vibe-d serialization/deserialization. So you can use it 
instead of Nullable for types that may or may not be there (I got 
bit by Nullable again so felt this had to be added [1])


Also of note is that it can be used in nogc and safe code, and is 
compatible with betterC.


Extract from readme:

* Use pattern matching, orElse
  fun.match!(
(int value) => writeln("it returns an int"),
() => writeln("did not return anything"),
  );
  fun.orElse(3); // returns some(fun()) or some(3)

* Safely call functions on classes that are null or structs that 
don't exist

  class C { int fun() { return 3; } }
  Optional!C a = null;
  a.dispatch.fun; // no crash, returns no!int

* Forwards any operator calls to the wrapped typed only if it 
exists, else just returns a none

  Optional!int a = 3;
  Optional!int b = none;
  a + a; // evaluates to some(6);
  a + b; // evaluates to no!int;

* Compatible with std.algorithm and std.range
  fun.each!(value => writeln("I got the value"));
  fun.filter!"a % 2 == 0".each!(value => writeln("got even 
value"));


Cheers,
- Ali

[0] https://code.dlang.org/packages/optional
[1] 
https://forum.dlang.org/thread/thtjhrvlgetaahcam...@forum.dlang.org


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: LDC 1.16.0-beta1

2019-05-09 Thread aliak via Digitalmars-d-announce

On Thursday, 9 May 2019 at 21:14:02 UTC, kinke wrote:
Glad to announce the first beta for LDC 1.16; mainly just an 
upgrade to D 2.086.0.


Full release log and downloads: 
https://github.com/ldc-developers/ldc/releases/tag/v1.16.0-beta1


Please help test, and thanks to all contributors!


Yay!! :D Thanks kinke


  1   2   3   4   5   >