Re: Implicit conversions through purity

2014-04-16 Thread Steve Teale

On Tuesday, 15 April 2014 at 18:02:00 UTC, bearophile wrote:

Steve Teale:

Since this is D-Learn, I can be indignant, and say that D 
needs to get its act together, and have a clean definition of 
'pure'. What you describe is not only undocumented, but also 
far too complicated - pure weak nothrow dontpiss kissmyass 
@never, and so on if the direction continues.


There is a nice article on D purity that I suggest you to read. 
Unfortunately I don't remember the link.


To design a system language as complex as C++/D you need lot of 
mathematics and theory. Andrei is good in computer science 
theory and in complex programming too, but Walter is less 
mathematically-minded and this could be visible in the design 
of some parts of D. Anyway, everyone is doing their best, 
Walter is very good and he has all my respect. And in a 
real-world system language a clean definition of pure (like the 
original pure implementation of D) is not very useful. The 
current definition of pure of D is good enough and it's a part 
very near to be completely implemented (unlike many other parts 
of D like synchronized, scope, SIMD, vector operations, 
operator overloading, dynamic libraries, GC, and more). So 
please don't be too much indignant, we don't have the research 
laboratories of Microsoft :-)



Nontheless, thank you for your assiduous efforets to make D 
internally consistent.


In the end I am not doing much. At best I can only hope to spot 
some sharp corners of the language, and ask for them to be 
smoothed. But it's very hard to make progress. And lately 
Andrei (perhaps rightfully) has raised the bar regarding the 
acceptable breaking changes. And people like Kenji have a mind 
better than mine (able to think about tens of corner cases, 
able to keep in mind many complex interactions, etc) even when 
they are sleeping :-)


Bye,
bearophile


Like I said, I allowed myself the luxury of being indignant 
because we were hidden away on D Learn. I have total respect for 
Walter. For one thing he is a self-taught programmer like me, 
though much more advanced, and I've known him on and off since 
the Zortech days in 1988. I don't much about Andrei and Kenji, 
except that they are out of my league.


I guess that rather than complain that the compiler does not 
appear to conform to the definition, I should help by trying to 
improve the documentation.


Anyway my view on the original subject is that the implicit 
conversion should be allowed for the out case, but not the ref.


Steve


Re: Implicit conversions through purity

2014-04-15 Thread Steve Teale

On Monday, 14 April 2014 at 15:16:07 UTC, bearophile wrote:

Steven Schveighoffer:

For that reason, I would disallow out parameters from casting 
implicitly.


A number of things perplex me here.

1) If I attempt to compile foo2() more or less as presented with 
2.065, the compiler tells me:


Error: '_adDupT' is not nothrow
Error: function 'mu.foo2' is nothrow yet may throw

What version is the discussion about?

2) If I have a simple program as follows, the compiler does not 
complain about me altering the value of global a.


import std.stdio;
string a = aaa;

void foo2(in string s, ref string sOut) pure {
auto s2 = s.dup;
s2[0] = 'a';
sOut = cast(string) s2; // Error: cannot implicitly convert
}

void main() {
{
   foo2(xyz, a);
   writeln(a);
}

3) Using a ref parameter for a pure function seems to me to be a 
clear indication of intended side effect. Wikipedia on pure 
functions says it's not allowed. Out does seem somehow different 
to me, since it's initial value is by definition throw-away.


Steve


Re: Implicit conversions through purity

2014-04-15 Thread Steve Teale

On Tuesday, 15 April 2014 at 09:41:57 UTC, bearophile wrote:
Yes, foo2 is weakly pure, but main is not tagged as pure, so 
main is free to use a global reference. If you mark main pure, 
your code will not compile even if you comment out the writeln. 
D is working as designed here.



3) Using a ref parameter for a pure function seems to me to be 
a clear indication of intended side effect.


In D you can also have const ref. A mutable ref makes the 
function weakly pure at best.




Wikipedia on pure functions says it's not allowed.


D has both strongly pure and weakly pure functions (and later 
the compiler has added const-ly pure and another category, 
all invisible.




Out does seem somehow different to me, since it's initial
value is by definition throw-away.


Yes, this is true in theory. I don't know if this is also true 
in D in practice, because D out has some problems.


Bye,
bearophile


Since this is D-Learn, I can be indignant, and say that D needs 
to get its act together, and have a clean definition of 'pure'. 
What you describe is not only undocumented, but also far too 
complicated - pure weak nothrow dontpiss kissmyass @never, and so 
on if the direction continues.


Nontheless, thank you for your assiduous efforets to make D 
internally consistent.


Steve



Re: How to hand in a closure variable

2014-04-07 Thread Steve Teale

On Friday, 4 April 2014 at 15:15:55 UTC, bearophile wrote:

Bienlein:


What I was actually looking for was how to get this to work:

immutable int b = if(1 == 1) { return 123; } else { return 
456; };


immutable b = (1 == 1) ? 123 : 456;

Bye,
bearophile


You said you did not like ternary expressions ;=)

Steve


Check for presence of function

2014-03-23 Thread Steve Teale
What's the cool/idiomatic D way to test at compile time if a 
struct has a member function with a particular signature? Along 
the lines of:


struct Unrelated
{
   ...
}

template isSomething(T)
{
enum bool isSomething = is(typeof(
(inout int = 0)
{
   T???; // has a function void doSomething(Unrelated* up);
   // etc
}));
}

struct Thingie
{
   ...
}

static assert(isSomething!(Thingie));

Thanks
Steve


Re: Check for presence of function

2014-03-23 Thread Steve Teale

On Sunday, 23 March 2014 at 13:23:58 UTC, Dicebot wrote:

On Sunday, 23 March 2014 at 13:03:07 UTC, Adam D. Ruppe wrote:
That won't necessarily work in the presence of overloaded 
functions since getMember only gets one of them.


Yeah, forgot to add this part, will make end result a bit less 
pretty indeed.


Updated version with overloads will be more reliable than 
proposed duck-typing version as it won't false trigger in 
presence of alias this or opDispatch. Though Steve may 
actually want it to trigger, I don't know.


DB,

In my particular question, I would not have wanted, or cared if 
alias this was triggered, but that was a narrow view.


My primary point is that there should be something in the wiki to 
help old-fashioned programmers like me to change from an OOP 
style that is not 100% necessary, to a struct based  style that 
should be quicker, but that allows the compiler to help me, or 
other contributors to the same project, to write add-on 
components that are at least checked at compile time.


So what I'm after really, is how do you do interfaces outside of 
OOP.


Std.range does that sort of thing in what seem to me to be very 
simple cases, but there is a lot of scope for different scenarios.


Thanks for your answer
Steve



Casting an interface to the type that implements it.

2014-03-12 Thread Steve Teale

This might be equivalent to 'How to do multiple inheritance in D'.

I have a class ControlSet, that is just a bunch of widgets. I use 
it in various places to represent the contents of dialogs that 
are associated with some class.


All such classes have to do is define themselves using the 
CSTarget interface thus:


class Base: CSTarget ...
class Whatever: Base ...

The ControlSet class has a data member host, of type CSTarget. 
When I propagate a button-click or whatever, I use


host.csNotify(Widget w, int id);  // Bam!!!

This works fine in my app, and the ControlSet has been a 
wonderfully reliable and useful part of my armoury.


However, when I try to dispatch the same notification across the 
boundary between my app, and a dynamically loaded plugin module, 
the app crashes. I can fix the crash by casting host to the base 
type of the class that contains it:


(cast(Base) host).csNotify(Widget w, int id);   // Fine ;=)

I believe I need some sort of compile-time skullduggery to define 
this cast information at the point where my ControlSet instances 
are declared. Either that, or I need to pass a delegate to the 
constructor that I can somehow use to replace the cast.


What is the D way of doing this?

Thanks Steve


Re: Linux Dynamic Loading of shared libraries

2014-03-10 Thread Steve Teale

On Sunday, 9 March 2014 at 14:09:28 UTC, Tolga Cakiroglu wrote:



For this, you create an Interface that matches to the method 
declaration of your class. But notice that instead of defining 
methods, you will define attributes those types' match to that 
class's methods. I did this before and it works. At least with 
Posix dlsym function's help.


OK, so then what goes wrong here:

module exta;

class ExtA
{
   int n;
   this(int _n) { n = _n; }

   int foo() { return ++n; }
}

ExtA getInstance(int n)
{
   return new ExtA(n);
}

compiled with:
dmd exta.d -c -fPIC -shared
dmd exta.o -shared -defaultlib=libphobos2.so -L-rpath=.

module main;
import core.runtime;
import std.stdio;

extern(C) void* dlsym(void*, const char*);
extern(C) void dlclose(void*);

interface ExtA
{
   int foo();
}

void main() {
   void* lib = Runtime.loadLibrary(exta.so);
   if (lib is null)
   {
  writeln(library not loaded);
  return;
   }
   writeln(loaded);

   void* vp = dlsym(lib, 
_D4exta11getInstanceFiZC4exta4ExtA\0.ptr);

   if (vp is null)
   {
  writeln(symbol not found);
  return;
   }
   writeln(got symbol);
   ExtA function(int) f = cast(ExtA function(int)) vp;
   ExtA x = f(42);
   if (x is null)
   {
  writeln(no class object);
  return;
   }
   int n = x.foo();
   writefln(n = %d, n);
   Runtime.unloadLibrary(lib);
}

compiled with:
dmd -c main.d
dmd main.o -L-ldl -defaultlib=libphobos2.so -L-rpath=.

output:
loaded
got symbol
n = 9
Segmentation fault (core dumped)

The answer should be 43. The segfault happens on the 
Runtime.unloadLibrary(lib); call.


Any ideas?

Steve




Re: Linux Dynamic Loading of shared libraries

2014-03-10 Thread Steve Teale

On Sunday, 9 March 2014 at 12:07:22 UTC, Steve Teale wrote:

Now suppose that my D shared library contains a class, rather 
that just module ctors/dtors, how do I go about creating an 
instance of that class and using its methods?


After wandering down several dead-end paths, and help from other 
contributors, I have finally come up with something that looks 
like the basis of a plugin pattern for Linux DMD using shared 
objects (.so files). This is somewhat long for a forum post. You 
can download this readme and the associated files from 
britseyeview.com/plugin101.tar.bz2


To get started, you need a base class that provides declarations 
for all functions that the plugin will be allowed to use 
externally. Why base class, and not interface? Well I guess 
because interfaces don't provide any information about data. If 
you create a shared library based on an interface, then all the 
shared object methods that reference data in the class that 
implements the interface fail miserably. I'm sure someone will 
explain why - probably some obvious thing I have overlooked.


OK, so my base class is:

module plugin;

class Plugin
{
   int n;
   this(int _n) { n = _n; }

   int foo() { return int.min; }
   void bar() {}
}


The class that implements this base in the shared library is:

module exta;
import plugin;
import std.stdio;
import std.math;

class ExtA: Plugin
{
   double d;
   this(int n) { super(n); d = PI; }

   override int foo() { return ++n; }
   override void bar() { writefln(Done my thing (%f), d); }
}

Plugin getInstance(int n)
{
   return new ExtA(n);
}

shared static this() {
  writeln(exta.so shared static this);
}

shared static ~this() {
  writeln(exta.so shared static ~this);
}

The module ctor/dtor are included because that has become 
conventional in discussions about dynamic loading. Otherwise, the 
so has the class implementation - ExtA, and a shared method to 
create an instance of same. It includes references to methods in 
Phobos.


The test program is as follows:

module main;
import core.runtime;
import std.stdio;
import plugin;

extern(C) void* dlsym(void*, const char*);

alias Plugin function(int) pfi;

Plugin getPlugin(string name)
{
   void* lib = Runtime.loadLibrary(name~.so);
   if (lib is null)
   {
  writeln(failed to load plugin shared object);
  return null;
   }

   void* vp = dlsym(lib, 
_D4exta11getInstanceFiZC6plugin6Plugin\0.ptr);

   if (vp is null)
   {
  writeln(plugin creator function not found);
  return null;
   }
   pfi f = cast(pfi) vp;
   Plugin x = f(42);
   if (x is null)
   {
  writeln(creation of plugin failed);
  return null;
   }
   return x;
}

void main()
{
   Plugin x = getPlugin(exta);
   int n = x.foo();
   writefln(n = %d, n);
   x.bar();
}

The long symbol name used in the dlsym() call is of course from 
the .map file generated when the .so file is created


These can be built using the following primitive makefile, whose 
main purpose is to spell out the required compiler flags:


main :
dmd -c plugin.d
dmd -c -shared -fPIC exta.d
dmd exta.o -shared -defaultlib=libphobos2.so -map
dmd -c main.d
dmd main.o plugin.o -L-ldl -defaultlib=libphobos2.so -L-rpath=.

This assumes that the plugins will be in the same directory as 
the executable (rpath=.).


Note that there is no call to Runtime.unloadLibrary(). The 
assumption her is that once the plugin has been loaded it will be 
there for the duration of the program. If you want to unload it 
you'll probably have to make sure the plugin object is purged 
from memory first, and I have not discovered how to do that yet 
;=(


Steve


Linux Dynamic Loading of shared libraries

2014-03-09 Thread Steve Teale

Martin Nowak's Gihub druntime Page has

module main;
import core.runtime, core.thread;

void main() {
auto lib = Runtime.loadLibrary(./liba.so);
auto thr = new Thread({
auto lib = Runtime.loadLibrary(./liba.so);
Runtime.unloadLibrary(lib);
});
thr.start();
thr.join();
Runtime.unloadLibrary(lib);
}

module liba;
import std.stdio;

shared static this() { writeln(shared static this()); }
shared static ~this() { writeln(shared static ~this()); }
static this() { writeln(static this()); }
static ~this() { writeln(static ~this()); }

Now suppose that my D shared library contains a class, rather 
that just module ctors/dtors, how do I go about creating an 
instance of that class and using its methods?


Steve


Re: Template mixins - why only declarations

2014-03-07 Thread Steve Teale

On Thursday, 6 March 2014 at 18:36:12 UTC, Dejan Lekic wrote:


Template mixins can't contain statements, only declarations, 
because they

(template mixins) are a way to inject code into the context.

Therefore it makes sense to forbid statements, as they can't 
appear in ANY

context.


If I side-step slightly, the compiler does not appear to have 
difficulty coping:


import std.stdio;
import std.conv;

string codeString(string A, string B, int I)()
{
   enum n = I*3;
   return writeln(\~A~\); writeln(\~B~\); 
writefln(\%d\,~to!string(n)~);;

}

void foo()
{
   mixin(codeString!(One, Two, 1)());
   writeln(Hello world);
}

void main()
{
   foo();
}




Re: Compiling D through command line

2014-03-07 Thread Steve Teale

On Friday, 7 March 2014 at 16:59:30 UTC, Bauss wrote:
What arguments would I do to compile a d project through 
command line. Been trying a few things, but can't get it 
working.


I always get Error: cannot read file x

Read around the net and it most says it's an installation error 
and that reinstalling should fix it, but it works when 
compiling through a few IDE's so I assume it's mistake of my 
own.


Tried like this:
-c c:\testproject\main.d -m32 -ofc:\testd\out.exe



Take a step back. Your file is in folder c:\testproject, so do

cd \testproject
dmd main.d

Then look for a file called main.exe in the \testproject folder. 
I may be off the mark, since I have not used dmd under Windows 
for quite a long time, but try it.


Re: Nobody understands templates?

2014-03-02 Thread Steve Teale

On Sunday, 2 March 2014 at 10:05:05 UTC, Dicebot wrote:



There is nothing wrong about not using templates. Almost any 
compile-time design can be moved to run-time and expressed in 
more common OOP form. And using tool you have mastery of is 
usually more beneficial in practice than following the hype.


Yes DB, we can soldier on happily, but it would not do any harm 
to understand templates.


The documentation examples quickly make your eyes glaze over, 
looking at the code in Phobos is doubtless instructive, but you 
can wade through a lot of that without finding what you want. 
Also I discovered an interesting fact today. the word 'mixin' 
does not appear in the language reference Templates section of 
dlang.org.


It should be used in at least one example. I just discovered by 
trial and error that I could use 'mixin' in Templates (as opposed 
to Template Mixins), and when you know that it seems likely that 
you can accomplish lots of stuff you couldn't before.


While I'm here, has anyone discovered a way to fudge a 
constructor super(..) call in a mixin template that's included in 
a class constructor. Since the mixin template is evaluated in the 
scope of the constructor, it seems like it should be OK.


I'm sure I'll get there in time ;=)

Steve



Re: Nobody understands templates?

2014-03-02 Thread Steve Teale

On Sunday, 2 March 2014 at 15:23:03 UTC, H. S. Teoh wrote:

This is a pretty good primer to templates:

https://semitwist.com/articles/article/view/template-primer-in-d



The trouble is with most of these tutorials that they offer 
examples that are things you would probably never want to do. I 
can already add an int to an int, or a double to a double, or an 
int to a double.


Perhaps the examples should pick on something like vector 
operations, but then who would be doing those with int, or some 
class? It would be doubles or pairs of, as in struct Coord.


I believe readers would study documentation and examples much 
more carefully if they were things they might realistically want 
to do. And that won't be type conversion - std.conv already does 
a pretty good job on that. So what?


We could really do with a place where template savvy open source 
contributors could publish interesting examples of template use.


Otherwise, Joe Soap, like me, can spend a great deal of time and 
effort in:


a) Determining when the use of a template might be advantageous,
b) Hacking at test programs to determine what the documentation 
means, and what works, and what doesn't.
c) After that, deciding whether it would be just as effective to 
use two or three separate methods.


Steve


Steve


Re: Nobody understands templates?

2014-03-01 Thread Steve Teale

On Friday, 28 February 2014 at 19:06:26 UTC, Dicebot wrote:

On Friday, 28 February 2014 at 18:42:57 UTC, Steve Teale wrote:
Is this typical - libraries use templates, applications don't, 
or

am I just being unimaginative?

Steve




Also every time you catch yourself doing any sort of 
copy-paste, it is quite possible that it can be replaced by 
mixin / template mixin instead. Application that are built in 
more declarative way benefit more from such tool set than 
traditional imperative ones.


In have a couple of case that always require me to find some 
other instance of it, and then copy/paste, But then I need to 
edit the pasted code anyway because in any particular case it 
needs to deal with different command info, so how can mixins help 
me? I have already dealt with the yada-yada cases by 
old-fashioned OOP.


From the various answers to this question I have concluded that I 
should not worry about it. If there's a need for a template I 
think I am already recognizing it.


Thanks!all()
Steve


Re: Nobody understands templates?

2014-03-01 Thread Steve Teale

On Saturday, 1 March 2014 at 22:16:54 UTC, woh wrote:
 You probably don't have a good understanding of templates if 
you have only used 2 in your entire codebase.  Or you are 
talking about a very tiny codebase.


That's just what us template-blind people want to hear - 
confirmation that we are in fact stupid.


The project I'm talking about is about 3 loc excluding blank 
lines and comments.


What I'd like to see is a tool, or a switch on the compiler that 
emits the code generated by templates. We - the template-blind -  
would have it sussed in a heartbeat then.


Steve


Re: enum abuse

2014-02-28 Thread Steve Teale
On Friday, 28 February 2014 at 11:47:45 UTC, Vladimir Panteleev 
wrote:


A const or immutable declaration would declare a constant 
variable - meaning, unless it is optimized out at a later 
point, it will end up in the data segment and have its own 
address. An enum declares a manifest constant - it exists only 
in the memory of the compiler. Manifest constants make sense 
when doing metaprogramming. Constant/immutable declarations 
make sense for values that will be used in multiple places by 
code at runtime.


I'm with Mike - thanks Vlad, that makes it perfectly clear. I 
just wonder slightly why a language that prides itself so on its 
metaprogramming capabilities does not have a keyword that makes 
it obvious


Think of an abbreviation for compile-time-constant.

But yes, thanks.

BTW, why does an immutable integer type need to have an address?

Steve



Re: @disable this for structs

2014-02-28 Thread Steve Teale

On Friday, 28 February 2014 at 16:02:26 UTC, Dicebot wrote:

...

Mmm, simple question, complicated answer. But the first one was 
enough for me at this point.


Nobody understands templates?

2014-02-28 Thread Steve Teale

All the D aficionados seem to wet their pants over
meta-programming, but I struggle to find a place to use it.

IIRC, I used it in a couple of places when I was trying to write
library stuff for MySQL, but in my current project, I use it only
once. That's when I want to stuff something onto my undo stack.

For that I have two template functions - push(T)(MybaseClass* p,
T t, int ID), and pushC, which is just the same except that it
checks the top of the stack to see if the ID there is the same as
what it is wanting to push.

This has served me very reliably, but I struggle to find other
places in the whole application where I would benefit from
templates.

Is this typical - libraries use templates, applications don't, or
am I just being unimaginative?

Steve


Re: @disable this for structs

2014-02-27 Thread Steve Teale

On Thursday, 27 February 2014 at 18:13:43 UTC, Namespace wrote:
On Thursday, 27 February 2014 at 18:10:38 UTC, Steve Teale 
wrote:
Could someone please explain what you would use this for to an 
old man rooted in C++, but who loves D.


Where does it fit in relative to 42?

;=(

Steve


It's for explicit initialization:

struct Foo { }

Foo f; // no problem

struct Bar {
@disable this();
}

Bar b; // error


So it is just a reminder that you need to initialize Bar in some 
specific way?




@disable this for structs

2014-02-27 Thread Steve Teale
Could someone please explain what you would use this for to an 
old man rooted in C++, but who loves D.


Where does it fit in relative to 42?

;=(

Steve


DUB Error

2014-02-25 Thread Steve Teale

What does the somewhat cryptic DUB error

Trying to append absolute path.

mean.

By a process of elimination, the offending line in the json file 
is


importPaths: [/usr/local/include/d/gtkd-2]

Steve



Re: DUB Error

2014-02-25 Thread Steve Teale
On Wednesday, 26 February 2014 at 03:33:38 UTC, Jesse Phillips 
wrote:

On Tuesday, 25 February 2014 at 14:32:42 UTC, Steve Teale wrote:

What does the somewhat cryptic DUB error

Trying to append absolute path.

mean.

By a process of elimination, the offending line in the json 
file is


importPaths: [/usr/local/include/d/gtkd-2]

Steve


The path you have provide is an absolute path, I suspect that 
somewhere in the code it is doing something like:


buildPath(curDir, importPath);

However, buildPath doesn't have a check for appending absolute 
path, so probably a custom path library which is basically 
saying your ignoring the working directory.


I guess I was misunderstanding 'importPaths'. I got a little 
further along when I used


dflags: [/usr/local/include/d/gtkd-2]

instead.

But you'd think that since it is targeting D, importFlags might 
have that purpose.


Steve


Re: Treat memory as a file with a name.

2014-02-22 Thread Steve Teale
If it's the same librsvg as below, then it looks like it has an 
API function which can also load a SVG from memory:


https://developer.gnome.org/rsvg/2.40/RsvgHandle.html#rsvg-handle-new-from-data

To answer your original question, I think the best way to do 
this is to create a pipe on the filesystem. Once created, you 
can feed data through it without touching the disk.


Thanks Vladimir,

My librsvg is 2.36, but rsvg-handle-new-from-data pre-dates that, 
so it should be good. Thanks for the link - I had clearly been 
looking at some crap documentation.


Thanks for the pipe idea too - it will come in handy one day, and 
I'd completely forgotten about pipes.


Steve


Treat memory as a file with a name.

2014-02-21 Thread Steve Teale

This is probably not exactly a D question.

The library librsvg expects to get an SVG file filename. I have 
the data of such a file in memory.


How do I dress up that memory as a file with a name so that I can 
pass the name to the librsvg open function.


I've looked at std.mmfile, and played with it, giving a name to 
the constructor, along with the address and size of my memory 
block.


import std.mmfile;
import std.stdio;
import std.stream;

void main()
{
   char[] ca;
   ca.length = 10;
   ca[] = 'X';
   MmFile mmf = new MmFile(glob, 0, 10UL, ca.ptr);
   std.stream.File sf = new std.stream.File(glob, FileMode.In);
   char[] b;
   b.length = 20;
   sf.readExact(b.ptr, 20);
   writefln(%s, b);
}

But then I just get 'No such file or directory', which is what 
I'd expect after I'd taken the trouble to read mmfile.d.


I had expected it to create a stub entry in the file system or 
something, and the somehow use fmemopen(), but it just looks for 
an existing file.


At the moment I'm having to write the data to a temporary file, 
and then pass the name of the temp to rsvg.


There must be some elegant way to do this!


Re: 64 bit size_t

2014-02-18 Thread Steve Teale
Rather than change it to int/ulong, just change it to 'size_t 
len = parent.children.length+1' (or auto instead of size_t). 
This way it's proper for both 32-bit and 64-bit and you don't 
need to worry about architecture. If you do need a signed 
version, you can use ptrdiff_t.


Yup, that's what I did when my head returned to its usual postion 
;=)





64 bit size_t

2014-02-16 Thread Steve Teale

Why is it that with 32 bit compilation, int is 32 bits, but
apparently this convention is not followed in 64 bit compilation.

I have not installed the 64 bit compiler yet, but apparently

int len = parent.children.length+1;

provokes the following error

acomp.d(782): Error: cannot implicitly convert expression 
(parent.children.length + 1LU) of type ulong to int


parent is just a straightforward array

What is size_t for 64 bit?

Steve


Re: 64 bit size_t

2014-02-16 Thread Steve Teale

On Monday, 17 February 2014 at 07:15:20 UTC, Steve Teale wrote:

Why is it that with 32 bit compilation, int is 32 bits, but
apparently this convention is not followed in 64 bit 
compilation.


I have not installed the 64 bit compiler yet, but apparently

int len = parent.children.length+1;

provokes the following error

acomp.d(782): Error: cannot implicitly convert expression 
(parent.children.length + 1LU) of type ulong to int


parent is just a straightforward array

What is size_t for 64 bit?

Steve


Sorry parent.children is just a straightforward array


Re: 64 bit size_t

2014-02-16 Thread Steve Teale

On Monday, 17 February 2014 at 07:17:06 UTC, Steve Teale wrote:


What is size_t for 64 bit?

Steve


Sorry parent.children is just a straightforward array


Sorry again - forget about it. I'd forgotten that D actually says 
int is 32 bits, and ulong is 64, and size_t for a 64 bit machine 
is obviously 64.


I'll just go through the code and either change int to ulong or 
use a cast.


;=(


Re: Ranges, constantly frustrating

2014-02-11 Thread Steve Teale
On Tuesday, 11 February 2014 at 10:52:40 UTC, Tobias Pankrath 
wrote:




The second naive solution would be to use readText and 
splitLines.


That's the sort of thing I always do because then I understand 
what's going on, and when there's a bug I can find it easily!


But then I'm not writing libraries.

Steve



Re: App release build crashes

2014-02-07 Thread Steve Teale

On Friday, 7 February 2014 at 07:43:05 UTC, Steve Teale wrote:
I was attempting to to build my app COMPO using a Makefile this 
morning, and at first this worked to some extent, but after 
some fiddling with compiler flags to make a release version 
that then had problems, I reverted to my original makefile as 
of yesterday. That builds and links the app, but when I run it 
I get


Fatal Error while loading 
'/usr/lib/i386-linux-gnu/libphobos2.so.0.64':

The module 'std.regex' is already defined in './compo'.

My Makefile has:

LFLAGS = -L-L/usr/lib/i386-linux-gnu -L-L/usr/local/lib 
-L-L/home/steve/COMPO -L-lusps4cb -L-lgtkd-2 -L-lrsvg 
-L-lphobos2 -L-ldl -L-lpthread -L-lm -L-lrt


compo: $(OBJFILES)
gcc -o compo $(OBJFILES) $(LFLAGS)

If I use static phobos2 -L-l:libphobos2.a, it runs OK. Building 
via CodeBlocks using phobos2 shared library works OK judging by 
the smaller executable size.


What is wrong with my linker flags?


Possibly nothing - I was using binutils-gold, and reverting to 
the Gnu linker fixed that.


However the version built with phobos shared crashes in use, and 
I have to delve into that before I can say where.




App release build crashes

2014-02-06 Thread Steve Teale
I was attempting to to build my app COMPO using a Makefile this 
morning, and at first this worked to some extent, but after some 
fiddling with compiler flags to make a release version that then 
had problems, I reverted to my original makefile as of yesterday. 
That builds and links the app, but when I run it I get


Fatal Error while loading 
'/usr/lib/i386-linux-gnu/libphobos2.so.0.64':

The module 'std.regex' is already defined in './compo'.

My Makefile has:

LFLAGS = -L-L/usr/lib/i386-linux-gnu -L-L/usr/local/lib 
-L-L/home/steve/COMPO -L-lusps4cb -L-lgtkd-2 -L-lrsvg -L-lphobos2 
-L-ldl -L-lpthread -L-lm -L-lrt


compo: $(OBJFILES)
gcc -o compo $(OBJFILES) $(LFLAGS)

If I use static phobos2 -L-l:libphobos2.a, it runs OK. Building 
via CodeBlocks using phobos2 shared library works OK judging by 
the smaller executable size.


What is wrong with my linker flags?


Re: Is this reasonable?

2013-12-06 Thread Steve Teale

On Thursday, 5 December 2013 at 17:15:39 UTC, Steve Teale wrote:

Here I feel like a beginner, but it seems very unfriendly:

import std.stdio;

struct ABC
{
   double a;
   int b;
   bool c;
}

ABC[20] aabc;

void foo(int n)
{
   writefln(n: %d, aabc.length: %d, n, aabc.length);
   if (n  aabc.length)
  writeln(A);
   else
  writeln(B);
}

void main(string[] args)
{
   int n = -1;
   foo(n);
}


Oh my, what a hornet's nest!

I'd settle for an error that said that it's not permissible to 
compare a negative integer with a size_t. But almost any way you 
go is ugly.


Thank you all. I feel less like a beginner now ;=)


Is this reasonable?

2013-12-05 Thread Steve Teale

Here I feel like a beginner, but it seems very unfriendly:

import std.stdio;

struct ABC
{
   double a;
   int b;
   bool c;
}

ABC[20] aabc;

void foo(int n)
{
   writefln(n: %d, aabc.length: %d, n, aabc.length);
   if (n  aabc.length)
  writeln(A);
   else
  writeln(B);
}

void main(string[] args)
{
   int n = -1;
   foo(n);
}

This comes back with B.

If I change the test to (n  cast(int) aabc.length), then all is 
well.


Is this unavoidable, or could the compiler safely make the 
conversion implicitly?


Passing ref through a template chain

2011-10-03 Thread Steve Teale
To bind variables, the MySQL api wants their addresses - in my tiny example
below, these are represented by the void*[].

If I just use something like setTarget in the example, it works fine, but then
when I try to set a bunch of them in one go I'm hosed because I can't get the
right addresses through the chain.

import std.stdio;

void*[2] vpa;

void setTarget(T)(ref T t, int i)
{
   vpa[i] = t;
}

void setSeveral(T...)(ref T args)
{
   foreach (int i, arg; args)
  setTarget(arg, i);
}

//ref.d|19|Error: variable i cannot be read at compile time|
//ref.d|19|Error: variable i cannot be read at compile time|
//ref.d|19|Error: Integer constant expression expected instead of cast(uint)i|
/*
void setSeveral2(T...)(ref T args)
{
   for (int i = 0; i  args.length; i++)
  setTarget(args[i], i);
}
*/

void main()
{
   bool a;
   int b;
   setSeveral(a, b);
   writefln(orig %x %x, set %x %x, a, b, vpa[0], vpa[1]); // addresses 
differ
}

The problem arises I believe in 'foreach (int i, arg; args)' which makes a
copy for 'arg'. Usually in a foreach I can get round that by making it 'ref
arg'. But in the template function that does not work.

I can't use the setSeveral2() form, because that provokes the errors shown in
the comments.

How can I force the real addresses through the chain?

Thanks
Steve


Re: Passing ref through a template chain

2011-10-03 Thread Steve Teale
Works like a charm, and it's so obvious a thing to try that I'm kicking myself.

Thanks
Steve


Re: std.datetime impenetrable

2011-09-15 Thread Steve Teale
Oh, so it is difficult after all!  I thought it was just me.

So I am probably going to have to ask. Then the interesting question will be 
which
way around will offend fewest people.

I have installed it as ISO, then have to ask US users if they would prefer 
Letter
Size, or the other way round then all those Euro and Indian users say 'typical
American programmer!'.

Thanks for the rundown anyway.

Steve


std.array.array extended example to supplement that in std.array

2010-02-07 Thread Steve Teale
import std.array;
import std.range;
import std.stdio;

// A contrived input range
struct Sir
{
string s;
int pos;

bool empty() { return pos = s.length; }
void popFront() { pos++; }
int front() { return s[pos]-'0'; }
}

int[] da = [1,2,3,4,5];
int[5] sa = [1,2,3,4,5];

void main()
{
auto a1 = array(da);   // dynamic array
writefln([%s], a1);
auto a2 = array(sa[]); // slice (all) of static array
writefln([%s], a2);
auto a3 = array([1,2,3,4,5][]);// ditto
writefln([%s], a3);

Sir sir;
sir.s = 12345;
assert(isInputRange!(Sir));
auto a4 = array(sir);
writefln([%s], a4);
}


Template instantiation without (...)

2010-02-07 Thread Steve Teale
Which bit of the spec for template instantiation is it that allows the 
last two lines of the following to compile and work?

import std.stdio;


struct A
{
int a;
}

template Thingie(T)
{
static if (is(T == int))
enum Thingie = 1;
else
enum Thingie = 0;
}

void main()
{
writefln(%d, Thingie!(int));
writefln(%d, Thingie!int);
writefln(%d, Thingie!A);
}


Re: Template instantiation without (...)

2010-02-07 Thread Steve Teale
 I suppose it's the part of the spec you're about to write a patch for.

I guess so. It was discussed on one of the forums back in October 2008. I 
guess it got implemented but never made the documentation.




Re: Template instantiation without (...)

2010-02-07 Thread Steve Teale

 I suppose it's the part of the spec you're about to write a patch for.

Twas at:

http://www.digitalmars.com/d/archives/digitalmars/D/
Template_instantiation_syntax_77507.html#N77507



Re: Creating a logging library and have questions

2010-02-06 Thread Steve Teale
sybrandy Wrote:

 On 02/03/2010 12:03 AM, Rainer Deyke wrote:
  sybrandy wrote:
  1) I use the current core.thread library and put all my messages in a
  buffer that the thread checks periodically, pulls off a new message, and
  then writes it to a file.  There will be some work to make sure nothing
  collides with each other, but I think I can manage it.
 
  Wouldn't this allow logging messages to be lost before a hard crash?  To
  me, that would greatly reduce the utility of the logging system.
 
 If done improperly, yes, it would.  My hope is that if I did go with 
 this method, I would try to find a way to ensure no data was lost. 
 Oddly enough, I'm currently having that problem with the single-threaded 
 version for some reason.  The test program will stop and some of the 
 logging statements never make it to the file.
 
  3) Something else.  I really don't have much experience with threading,
  so I'm being very careful and really want to understand it.  This
  library looks to be a good way to learn, however if it's not the best
  way to do things, then what would be?
 
  Global mutex associated with the logging system.  Lock, output, unlock.
There are scalability issues with that approach, but I don't see why it
  wouldn't work in this situation.  (Plus, if you have a message queue,
  you probably need to protect that queue with a mutex anyway.)
 
 
 
 Understood.  My goal is that if I do put the writing in another thread, 
 I do my best to ensure it will scale.  I have a tendency to put a lot of 
 logging statements in code when I'm trying to debug something, so I 
 don't want to slow things down too much nor do I want to lose anything. 
   In short: I want the log writing to be as out of the way as possible.
 
 Casey

I second Rainer. A logging system should commit (at least) error messages 
immediately, particularly if the application has multiple threads. Otherwise it 
is going to make debugging a crashing system a nightmare.  When I do it I just 
stick 'synchronized' in front of the statement that does the write.




Re: Finding out about D - 102

2009-05-12 Thread Steve Teale
Ary Borenszweig Wrote:

 Steve Teale wrote:
  OK, so structs are a different beast in D than they are in C++. This 
  results in one of my most common pitfalls. I'll find myself writing:
  
  struct A
  {
 int a;
 int b;
  }
  
  A[] nameTooLong = ...;
  
  foreach (whatever; thingie)
  {
 nameTooLong[whatever.whatever].a = whatever.x*3;
 nameTooLong[whatever.whatever].b = whatever.y/3;
 
 with(nameTooLong[whatever.whatever]) {
a = whatever.x*3;
b = whatever.y/3;
 }

Ary,

Yes I use with quite often, it's when I have two of the beasts where I want to 
use with at the same time that I have fallen into this.

Now that I've rubbed my nose in it I'm sure I won't do it again.



Re: Finding out about D - 101

2009-05-11 Thread Steve Teale
Steven Schveighoffer Wrote:

  This tells me that a string in D is a sequence of characters (whatever  
  that might mean) in memory, prefixed by a size_t length. Of  course,  
  that's not to say there is no more to it, but the values for 'xtra'  
  don't give us much clue. If there was some other member of struct S, I'd  
  kind of expect to see bit flags there indicating whether the array of  
  char was invariant, const, or fair game.
 
  So I'm left with the question as to how does 'invariant' have teeth?
 
 invariant is not a runtime flag, but rather a type modifier.  The teeth of  
 invariance only exist during compilation, once you're in runtime, the  
 expectation is that the compiler will have weeded out all your attempts to  
 change the invariant data, so no need to keep track of its invariance.  It  
 is not immune to casting.
 
 And BTW, string is invariant(char)[], not invariant(char[]), which is a  
 distinct difference.  The former is a mutable array of invariant  
 characters, the latter is an invariant array of invariant characters.  You  
 can't change the length or reassign an invariant(char[]), but you can  
 reassign/append to an invariant(char)[].
 
 The xtra flags do not exist.  You are printing out garbage data on the  
 stack (most likely the pointer field of ca).
 
 -Steve

Great, so there are experienced D programmers checking on this newsgroup!

I'd kind of figured out from the test program that the invariant thing was just 
compile time, but  thanks for pointing out my misconception about the string 
alias. I should read things more carefully.

- Also Steve



Finding out about D - 102

2009-05-11 Thread Steve Teale
OK, so structs are a different beast in D than they are in C++. This results in 
one of my most common pitfalls. I'll find myself writing:

struct A
{
   int a;
   int b;
}

A[] nameTooLong = ...;

foreach (whatever; thingie)
{
   nameTooLong[whatever.whatever].a = whatever.x*3;
   nameTooLong[whatever.whatever].b = whatever.y/3;

   // more of the same sort of stuff
}

So I get fed up typing 'nameTooLong[whatever.whatever]', and instead I write

foreach (whatever; thingie)
{
   A ntl = nameTooLong[whatever.whatever];
   ntl.a = whatever.x*3;
   ntl.b = whatever.y/3;

   // more of the same sort of stuff
}

Then I chase a bug in my program, which compiled OK. After some time, I realize 
that

   A ntl = nameTooLong[whatever.whatever];

is doing a copy, which is not what I was thinking about at all - old C++ habits.

ntl = ...;

has no effect whatsoever on nameTooLong[whatever.whatever].

So then - pissed off by that point - I rewrite it as:

foreach (whatever; thingie)
{
   A* ntl = nameTooLong[whatever.whatever];
   // This suggests an ambiguity in the language?
   ntl.a = whatever.x*3;
   ntl.b = whatever.y/3;

   // more of the same sort of stuff
}

This works OK, but it's still not the D way to do things. Try:

foreach (whatever; thingie)
{
   alias nameTooLong[whatever.whatever] ntl;
   ntl.a = whatever.x*3;
   ntl.b = whatever.y/3;

   // more of yer same sort of stuff
}