Re: Getting a safe path for a temporary file

2017-10-27 Thread Jonathan M Davis via Digitalmars-d-learn
On Friday, October 27, 2017 21:38:55 Jonathan M Davis via Digitalmars-d-
learn wrote:
> Also, toStringz specifically returns an immutable(char)* - though looking
> it over right now, I'd say that that's a bug for the overload that takes
> const(char)[] instead of string. It really should return const(char)* in
> that case.

Actually, looking it over again, the return type is fine. That's the
overload that always allocates a new string (since it assumes that the array
could not have been from a string literal, since that would be a string and
would go to the other overload), so even though the argument could have been
const or mutable, what's returned is a pointer to a string, so
immutable(char)* is correct.

But https://issues.dlang.org/show_bug.cgi?id=15136 is still a problem for
the other overload.

- Jonathan M Davis



Re: Getting a safe path for a temporary file

2017-10-27 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, October 28, 2017 02:46:00 Shriramana Sharma via Digitalmars-d-
learn wrote:
> On Wednesday, 25 October 2017 at 00:35:29 UTC, Ali Çehreli wrote:
> > > char[] name = "/tmp/XX".dup;
> >
> > remain valid. The actual issue is the missing '\0'. So,
> >
> > consider toStringz in this case:
> >   https://dlang.org/library/std/string/to_stringz.html
>
> Thanks for your reply, but can you clarify exactly I should use
> this?
>
> char[] name = "/tmp/XX".toStringz;
>
> gives
>
> (13): Error: cannot implicitly convert expression
> `toStringz("/tmp/XX")` of type `immutable(char)*` to `char[]`
>
> So I tried:
>
> char[] name = "/tmp/XX".toStringz.dup;
>
> which gives
>
> (13): Error: template object.dup cannot deduce function from
> argument types !()(immutable(char)*), candidates are:
> /usr/include/dmd/druntime/import/object.d(1943):
> object.dup(T : V[K], K, V)(T aa)
> /usr/include/dmd/druntime/import/object.d(1979):
> object.dup(T : V[K], K, V)(T* aa)
> /usr/include/dmd/druntime/import/object.d(3764):
> object.dup(T)(T[] a) if (!is(const(T) : T))
> /usr/include/dmd/druntime/import/object.d(3780):
> object.dup(T)(const(T)[] a) if (is(const(T) : T))
>
> And:
>
> char[] name = "/tmp/XX".dup.toStringz;
>
> gives the error (13): Error: cannot implicitly convert
> expression `toStringz(dup("/tmp/XX"))` of type
> `immutable(char)*` to `char[]`
>
> So I'm not sure what to do?!

Well, for starters, toStringz returns a pointer, not a dynamic array. If you
want a dynamic array that's null-terminated, then you'll need to explicitly
put a null character on the end unless you're just going to use a string
literal (which would mean a string, not a char[], so that won't work here).

Also, toStringz specifically returns an immutable(char)* - though looking it
over right now, I'd say that that's a bug for the overload that takes
const(char)[] instead of string. It really should return const(char)* in
that case.

But regardless, that means that even changing char[] to char* wouldn't cut
it if you're using toStringz, since you're starting with a string. If you
want a specific constness, then you can use the more general function,
std.utf.toUTFz, which works with multiple character types and differing
constness rather than being designed specifically for string like toStringz
is.

However, something to take into account is that toStringz and toUTFz don't
always return the same string (and in fact, they probably never should,
because the trick they use to check for the null character one past the end
of the string doesn't always work correctly). So, if you're passing a string
to a C function that's then going to mutate it, you don't want toStringz or
toUTFZ. In that case, it's better to just manually put the null terminator
at the end of the string. So, you probably would end up with something like

char[] name = "/tmp/XX\0".dup;
auto fd = mkstemp(name.ptr);

Then when you return the name, you do something like

name[0 .. $ - 1].idup;

Alternatively, you could use a static array, but either way, you'd want to
put the null terminator in there manually. And fromStringz really isn't
necessary, since mkstemp is just going to fill in the array that you gave
it, and you know exactly where the null terminator is going to be, since
it's just filling in the X's rather than doing something that could end up
putting a null terminator anywhere in the array. You can just slice the
array to chop off the null terminator, and then dup it or idup if it's a
static array (so that you don't return a slice of a local variable), or if
it's a dynamic array, then either return it as-is or idup it if you want a
string; you could even use std.exception.assumeUnique to just cast it to
string if you know that no other references to that data exists (which they
wouldn't if you allocated the string inside of the function).

Also, you _really_ wouldn't want to use fromStringz if you used a static
array, since fromStringz always returns a slice of the original input:

inout(char)[] fromStringz(inout(char)* cString) @nogc @system pure nothrow {
import core.stdc.string : strlen;
return cString ? cString[0 .. strlen(cString)] : null;
}

But if I were you, I'd just create a char[] with an explicit null
terminator, and then afterwards, slice off the null character, and pass it
to assumeUnique to get a string, since then you allocate only once and don't
have to copy the contents of the array.

- Jonathan M Davis




Re: Why is length being tested on an int?

2017-10-27 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, October 28, 2017 02:38:43 Shriramana Sharma via Digitalmars-d-
learn wrote:
> Hello. I want a function to be able to take any arguments like
> write() and print them out but quoting string arguments of length
> more than 1. So I write the following quote:
>
> import std.stdio;
> string myFunc(string arg) { return '\"' ~ arg ~ '\"'; }
> void myWrite(T ...)(T args)
> {
>  foreach (arg; args)
>  if (is(typeof(arg) == string) && arg.length > 1)
>  write(myFunc(arg));
>  else
>  write(arg);
> }
> void main() { myWrite("Hello", 1, "c"); }
>
> However I am getting the error even when compiling:
>
> (6): Error: no property 'length' for type 'int'
> (7): Error: function .myFunc (string arg) is not
> callable using argument types (int)
> (11): Error: template instance .myWrite!(string, int,
> string) error instantiating
>
> I am not sure why, given short circuit evaluation, it is testing
> the length of the int argument? Or is it that the problem is at
> compile time itself so short circuit doesn't come into play?
>
> How to rewrite the function so I don't get the error?
>
> Thanks!

Okay. is(typeof(arg) == string) will be evaluated at compile time, because
is expressions are compile time constructs. However, an if statement is a
runtime construct, so it's going to be evaluated at runtime (which does look
like it's probably what you want for arg.length > 1). So, what you're
getting is essentially either

if(true && arg.length > 1)
write(myFunc(arg))
else
write(arg);

or

if(false && arg.length > 1)
write(myFunc(arg))
else
write(arg);

depending on the type of arg. In either case, arg.length has to compile. The
evaluation of whether it's true or not may be shortcutted, but that doesn't
mean that its semantics don't have to be valid. You're going to need to
break up what you're doing. e.g.

static if(is(typeof(arg) == string))
{
if(arg.length > 1)
write(myFunc(arg));
else
write(arg);
}
else
write(arg);

The other thing is that even with a static if and all of the conditions
being compile-time (which they need to be for a static if), && and || don't
shortcut the semantic check any more than that gets shortcutted with a
runtime if statement. So, even if arg were completely a compile-time thing,

static if(is(typeof(arg) == string) && arg.length > 1)
{
}

would only be valid code if typeof(arg) has length (though the second
condition would only be evaluated if arg were a string). There are times
where it would be nice if && and || shortcutted the semantic check with
static if, but for better or worse, they don't.

- Jonathan M Davis



Re: Why is length being tested on an int?

2017-10-27 Thread Adam D. Ruppe via Digitalmars-d-learn
On Saturday, 28 October 2017 at 02:38:43 UTC, Shriramana Sharma 
wrote:

if (is(typeof(arg) == string) && arg.length > 1)
I am not sure why, given short circuit evaluation, it is 
testing the length of the int argument?


That's a runtime check and therefore the code must run to be 
short circuited at all... which means it must compile the whole 
thing first.


Break the is() part into a separate static if, then put the 
runtime length check inside that. More like


static if(is(typeof(arg) == string)) {
if(arg.length > 1)
 // handle
else
 // string of short length
} else {
 // not a string
}


Re: Getting a safe path for a temporary file

2017-10-27 Thread Shriramana Sharma via Digitalmars-d-learn

On Wednesday, 25 October 2017 at 00:35:29 UTC, Ali Çehreli wrote:

> char[] name = "/tmp/XX".dup;

remain valid. The actual issue is the missing '\0'. So, 
consider toStringz in this case:


  https://dlang.org/library/std/string/to_stringz.html


Thanks for your reply, but can you clarify exactly I should use 
this?


char[] name = "/tmp/XX".toStringz;

gives

(13): Error: cannot implicitly convert expression 
`toStringz("/tmp/XX")` of type `immutable(char)*` to `char[]`


So I tried:

char[] name = "/tmp/XX".toStringz.dup;

which gives

(13): Error: template object.dup cannot deduce function from 
argument types !()(immutable(char)*), candidates are:
/usr/include/dmd/druntime/import/object.d(1943):
object.dup(T : V[K], K, V)(T aa)
/usr/include/dmd/druntime/import/object.d(1979):
object.dup(T : V[K], K, V)(T* aa)
/usr/include/dmd/druntime/import/object.d(3764):
object.dup(T)(T[] a) if (!is(const(T) : T))
/usr/include/dmd/druntime/import/object.d(3780):
object.dup(T)(const(T)[] a) if (is(const(T) : T))


And:

char[] name = "/tmp/XX".dup.toStringz;

gives the error (13): Error: cannot implicitly convert 
expression `toStringz(dup("/tmp/XX"))` of type 
`immutable(char)*` to `char[]`


So I'm not sure what to do?!


Why is length being tested on an int?

2017-10-27 Thread Shriramana Sharma via Digitalmars-d-learn
Hello. I want a function to be able to take any arguments like 
write() and print them out but quoting string arguments of length 
more than 1. So I write the following quote:


import std.stdio;
string myFunc(string arg) { return '\"' ~ arg ~ '\"'; }
void myWrite(T ...)(T args)
{
foreach (arg; args)
if (is(typeof(arg) == string) && arg.length > 1)
write(myFunc(arg));
else
write(arg);
}
void main() { myWrite("Hello", 1, "c"); }

However I am getting the error even when compiling:

(6): Error: no property 'length' for type 'int'
(7): Error: function .myFunc (string arg) is not 
callable using argument types (int)
(11): Error: template instance .myWrite!(string, int, 
string) error instantiating


I am not sure why, given short circuit evaluation, it is testing 
the length of the int argument? Or is it that the problem is at 
compile time itself so short circuit doesn't come into play?


How to rewrite the function so I don't get the error?

Thanks!



Re: Just starting with D (linking with C++)

2017-10-27 Thread codephantom via Digitalmars-d-learn

On Friday, 27 October 2017 at 17:14:20 UTC, sivakon wrote:
I want to use C++ libraries for machine learning and deep 
learning. How do I add C++ libraries to my d code.


on FreeBSD, I use:

for C static binding:
--
clang -c sample.c

dmd -L-lc foo.d sample.o
or
ldc -L-lc foo.d sample.o


for c++ static binding:
---
clang++ -c sample.cpp

dmd -L-lc++ foo.d sample.o
or
ldc -L-lc++ foo.d sample.o


There is nice article here that was pretty interesting too:
https://www.gamedev.net/blogs/entry/2254003-binding-d-to-c/



Re: Why 2 ^^ 1 ^^ 2 = 2?

2017-10-27 Thread Ivan Kazmenko via Digitalmars-d-learn

On Thursday, 26 October 2017 at 10:02:54 UTC, Kagamin wrote:

On Sunday, 22 October 2017 at 22:28:48 UTC, Ivan Kazmenko wrote:

Yeah, and a height-3 tower $a^{b^c}$ (TEX notation)


Is $a^{b^c}$ the same as ${a^b}^c$ ? They are drawn slightly 
differently, so I suppose it's ambiguous indeed.


Surely not the same.

"3 to the power of (3 to the power of 3)" is "3 to the power of 
27", or 7,625,597,484,987.
"(3 to the power of 3) to the power of 3" is "27 to the power of 
3", or 2187.


For an argument, the TEX command "^" accepts either a single 
character or a bracket-enclosed string of arbitrary length.  So 
$3^3^3$ indeed transforms to ${3^3}^3$, but not for some deeper 
reason this time.


Ivan Kazmenko.



Re: Just starting with D (linking with C++)

2017-10-27 Thread Joakim via Digitalmars-d-learn

On Friday, 27 October 2017 at 17:43:08 UTC, sivakon wrote:

On Friday, 27 October 2017 at 17:21:39 UTC, Joakim wrote:


This should work:

dmd foo.d Sample.o

Just like the C examples from the D blog:

https://dlang.org/blog/2017/10/25/dmd-windows-and-c/


Just used this! Got this error!

sample.o: In function `foo(int, int, int)':
sample.cpp:(.text+0x17): undefined reference to `std::cout'


Sorry, just responded quickly from my tablet, didn't try it out 
first.  There's actually a variant of this sample that is run as 
a test from the dmd compiler testsuite, so it is checked hundreds 
of times a day for pending pull requests, on all officially 
supported platforms by the auto-tester:


https://auto-tester.puremagic.com/pulls.ghtml?projectid=1
https://github.com/dlang/dmd/blob/master/test/runnable/extra-files/cppb.cpp#L41
https://github.com/dlang/dmd/blob/master/test/runnable/cppa.d#L25

Looking at the D script that runs each compiler test, it adds the 
following flag for all C++ objects:


https://github.com/dlang/dmd/blob/master/test/d_do_test.d#L499

So adding that flag got your example to work for me:

dmd -L-lstdc++ foo.d Sample.o


Re: Just starting with D (linking with C++)

2017-10-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/27/17 1:43 PM, sivakon wrote:

On Friday, 27 October 2017 at 17:21:39 UTC, Joakim wrote:


This should work:

dmd foo.d Sample.o

Just like the C examples from the D blog:

https://dlang.org/blog/2017/10/25/dmd-windows-and-c/


Just used this! Got this error!

sample.o: In function `foo(int, int, int)':
sample.cpp:(.text+0x17): undefined reference to `std::cout'


You need to link against the C++ standard library. On my system, it 
appears to be -lc++.


So in order to pass this value to the linker, use the dmd parameter -L-lc++

In order to find out what the name of the c++ library is, you need to 
compile a C++ program with the -v option. The linker step will show the 
library parameters you need to send to dmd.


-Steve


Re: Just starting with D (linking with C++)

2017-10-27 Thread sivakon via Digitalmars-d-learn

On Friday, 27 October 2017 at 17:21:39 UTC, Joakim wrote:


This should work:

dmd foo.d Sample.o

Just like the C examples from the D blog:

https://dlang.org/blog/2017/10/25/dmd-windows-and-c/


Just used this! Got this error!

sample.o: In function `foo(int, int, int)':
sample.cpp:(.text+0x17): undefined reference to `std::cout'


Re: Just starting with D (linking with C++)

2017-10-27 Thread Joakim via Digitalmars-d-learn

On Friday, 27 October 2017 at 17:14:20 UTC, sivakon wrote:

Hi,

Just started to work with D. Great language.

I want to use C++ libraries for machine learning and deep 
learning. How do I add C++ libraries to my d code.


For example,

//sample.cpp
#include 

using namespace std;

int foo(int i, int j, int k)
{
cout << "i = " << i << endl;
cout << "j = " << j << endl;
cout << "k = " << k << endl;

return 7;
}


//foo.d
extern (C++) int foo(int i, int j, int k);

void main()
{
foo(1,2,3);
}


How do I compile and link each of them to produce the result?
dmd -c foo.d
gcc -c Sample.cpp

Both of them get me .o files. Where do I go from there?

Thanks,
Siv


This should work:

dmd foo.d Sample.o

Just like the C examples from the D blog:

https://dlang.org/blog/2017/10/25/dmd-windows-and-c/


Just starting with D (linking with C++)

2017-10-27 Thread sivakon via Digitalmars-d-learn

Hi,

Just started to work with D. Great language.

I want to use C++ libraries for machine learning and deep 
learning. How do I add C++ libraries to my d code.


For example,

//sample.cpp
#include 

using namespace std;

int foo(int i, int j, int k)
{
cout << "i = " << i << endl;
cout << "j = " << j << endl;
cout << "k = " << k << endl;

return 7;
}


//foo.d
extern (C++) int foo(int i, int j, int k);

void main()
{
foo(1,2,3);
}


How do I compile and link each of them to produce the result?
dmd -c foo.d
gcc -c Sample.cpp

Both of them get me .o files. Where do I go from there?

Thanks,
Siv





Re: Role of third argument to GC.addRange

2017-10-27 Thread Steven Schveighoffer via Digitalmars-d-learn

On 10/27/17 10:18 AM, Nordlöw wrote:

The docs for the third argument to

https://dlang.org/library/core/memory/gc.add_range.html

says:

"The GC might use this information to improve scanning for pointers or 
to call finalizers."


Can somebody elaborate a bit on what "improve scanning" means here?


Currently, the TypeInfo is needed if you want to call the destructor of 
a struct.


Eventually, if we ever have precise scanning, the TypeInfo may provide a 
way to only scan reference types within the block, eliminating sources 
of false pointers.


-Steve


Re: Role of third argument to GC.addRange

2017-10-27 Thread Adam D. Ruppe via Digitalmars-d-learn

On Friday, 27 October 2017 at 14:18:02 UTC, Nordlöw wrote:
Can somebody elaborate a bit on what "improve scanning" means 
here?


I believe it is so it can skip scanning stuff like ubyte[] for 
pointers and in the future might be used for precise scanning on 
structs with pointers and data combined.


Role of third argument to GC.addRange

2017-10-27 Thread Nordlöw via Digitalmars-d-learn

The docs for the third argument to

https://dlang.org/library/core/memory/gc.add_range.html

says:

"The GC might use this information to improve scanning for 
pointers or to call finalizers."


Can somebody elaborate a bit on what "improve scanning" means 
here?


Re: Empty UDA for classes not allowed?

2017-10-27 Thread Nicholas Wilson via Digitalmars-d-learn

On Thursday, 26 October 2017 at 15:09:48 UTC, bauss wrote:

Why is it not allowed to have empty UDAs for classes?

Let's say we have an UDA like this:
struct Exclude { }

Then we want to put it on a class like:

@Exclude class Foo
{
...
}

This will fail with the following error:
Error: type Exclude has no value

But on everything else we can place an empty UDA like that ex. 
on a function:


This is okay:

@Exclude void foo()
{
...
}

Can someone explain to me why it's not possible with classes?


FWIW all parameterless UDA in LDC use a struct literal e.g.
https://github.com/ldc-developers/druntime/blob/ldc/src/ldc/attributes.d#L237