Re: Why are globals set to tls by default? and why is fast code ugly by default?

2023-03-27 Thread wjoe via Digitalmars-d-learn

On Sunday, 26 March 2023 at 18:07:03 UTC, ryuukk_ wrote:


It should be the opposite

Slow code ugly
Fast code beautiful



What's fast today may not be fast tomorrow but the language might 
still be relevant.


e.g.: It used to be faster to ...

- pre-calculate sin/cos tables, now the memory look up cost more 
cycles than the calculation itself


- use fixed point integer math, now every CPU has what used to be 
a floating point co-processor integrated


- only redraw the parts of the screen that changed, now the 
branching is slower than to  redraw everything
another example is sorting - Alexei wrote a blog post about how a 
stupid and slow sorting algorithm now performs better in multi 
threading. Maybe someone remembers the title/url of the post ?


And finally, beauty is in the eye of the beholder - meaning it's 
purely subjective.


Re: Detect uninitialized class var access

2022-09-26 Thread wjoe via Digitalmars-d-learn
On Monday, 26 September 2022 at 16:51:11 UTC, rikki cattermole 
wrote:
Currently in D you would be forced to create a vtable struct 
manually.


Or I could just use classes.
The cure shouldn't be worse than the disease.


But if we had something like signatures you could do this:

```d
struct Foo {
//...
}

struct Bar {
InputRange input;
}

void doIt() {
Bar bar;
Foo* foo = new Foo;
bar.input = foo;
}
```


This would be nice but since we don't it doesn't really matter. 
unfortunately.


Re: Detect uninitialized class var access

2022-09-26 Thread wjoe via Digitalmars-d-learn

On Sunday, 25 September 2022 at 02:10:00 UTC, Salih Dincer wrote:

On Saturday, 24 September 2022 at 13:17:19 UTC, rassoc wrote:
Recently I refactored some old code of mine, now utilizing 
classes instead structs, and I got hit by an uninitialized 
variable access pattern similar to the simplified example 
below.


I think changing the structure will make things harder (I mean 
in general). I know most people will object;  but classes are 
useless.  Structs are enough for you for the rest of your life 


SDB@79


How would you do this without classes:

``` D
interface ForwardRange
{
  // ...
}

class Foo: ForwardRange
{
   // ...
}

class Bar: ForwardRange
{
  // ...
}

struct Baz
{
   ForwardRange r;

   this(ForwardRange r_)
   {
 r = r_;
   }
}
```


Re: Forked GC explained

2022-09-03 Thread wjoe via Digitalmars-d-learn

On Saturday, 3 September 2022 at 13:35:39 UTC, frame wrote:
I'm not sure I fully understand how it works. I know that the 
OS creates read only memory pages for both and if a memory 
section is about to be written, the OS will issue a copy of the 
pages so any write operation will be done in it's own copy and 
cannot mess up things.


But then is the question, how can memory be marked as free? The 
forked process cannot since it writes into a copy - how it is 
synchronized then?


Is the GC address root somehow shared between the processes? Or 
does the forked process communicate the memory addresses back 
to the parent?


If so, does the GC just rely on this?

Are freeing GC operations just locked while the forked process 
is running?


What happens if a manually `GC.free()` is called while the 
forked process marks the memory as free too but the GC 
immediately uses the memory again and then gets the 
notification to free it from the forked child? Can this happen?


The OS creates a clone of the process. The original process which 
called fork() is called parent and the clone is called child.
The parent resumes normally after the call to fork returns and 
the child starts the mark phase.
The virtual memory map for both processes are identical at this 
point.
If either process writes to a page, the OS copies the page and 
writes the changes to the copy (Copy On Write).
Hence, modifed pages in the parent process can't be considered 
during the current collection cycle in the child.
At the end of the mark phase the child communicates the result to 
the parent, then exits.
The remaining work can then be completed by the parent in 
parallel as the pause is only required for the mark phase.


This works because every chunk of memory which is unreferenced in 
the parent is in the child, too, because it's a clone which 
doesn't mutate state except for the allocation required to hold 
the marked memory.
There is no need to do anything about the GC in the parent, it 
can allocate/free memory at will.
This doesn't interfere because the chunks that have been marked 
by the child are still considered in use by the parent, but 
unreferenced and ready to be collected.
After the child communicated its result to the parent, the GC 
thread in the parent can complete the collection cycle as if it 
had done the mark phase itself.
Anything that happened in the parent after the call to fork() 
will be considered in the next collection cycle.


Re: Code compiles and run fine with LDC but segfault with DMD

2022-08-30 Thread wjoe via Digitalmars-d-learn

On Monday, 29 August 2022 at 21:46:48 UTC, ryuukk_ wrote:

What `-g` does that makes this code compile and work with DMD?


This flag adds symbolic debug info. But I'm confident you knew 
that already.


Re: toString doesn't compile with -dip1000 switch

2022-08-01 Thread wjoe via Digitalmars-d-learn

On Monday, 1 August 2022 at 17:07:43 UTC, wjoe wrote:

On Monday, 1 August 2022 at 13:09:01 UTC, Kagamin wrote:

Bar.toString is typed `@system`.


Even if I'd declare everything @safe: at module scope?


I wrote that on my phone and it got a bit messy...

``` D
module x;
@safe:

struct Foo()
{
  import std.format: FormatSpec;
  const void toString(scope void delegate(const(char)[]) @safe 
sink, FormatSpec!char fmt) {}

}

struct Bar
{
  import std.format: FormatSpec;
  const void toString(scope void delegate(const(char)[]) @safe 
sink, FormatSpec!char fmt) {}

}

unittest {
  import std.conv:to;

  Foo!() foo; foo.to!string;
  Bar bar; bar.to!string; // 25
}
```


Re: toString doesn't compile with -dip1000 switch

2022-08-01 Thread wjoe via Digitalmars-d-learn

On Monday, 1 August 2022 at 13:09:01 UTC, Kagamin wrote:

Bar.toString is typed `@system`.


Even if I'd declare everything @safe: at module scope?


toString doesn't compile with -dip1000 switch

2022-08-01 Thread wjoe via Digitalmars-d-learn

struct Foo()
{
  import std.format: FormatSpec;
  const void toString(
scope void delegate(const(char)[]) @safe sink,
FormatSpec!char fmt)
  {}
}

struct Bar
{
  import std.format: FormatSpec;
  const void toString(
scope void delegate(const(char)[]) @safe sink,
FormatSpec!char fmt)
  {}
}

@safe unittest {
  import std.conv:to;

  Foo!() foo; foo.to!string;
  Bar bar; bar.to!string; // 25
}

# dmd d.d -dip1000 -unittest -main

d.d(25) Error: @safe function d.__unittest_121_C7 cannot call 
@system function std.conv.to!string.to!(Bar).to
/usr/lib/dmd/2.099/import/std/conv.d(221): std.conv.to!string.to! 
(Bar).to is declared here



why is that?



Re: Cannot copy void[] to void[] in @safe code?

2022-07-08 Thread wjoe via Digitalmars-d-learn

On Friday, 8 July 2022 at 12:26:03 UTC, ag0aep6g wrote:
You're allowed to copy from `ubyte[]` to `ubyte[]`. But you're 
not allowed to copy from `ubyte[]` to `int*[]`, because 
reinterpreting a bunch of bytes as pointers is not safe.


The thing about `void[]` is that it can point to memory that 
also has a typed alias. You can have a `void[]` and a `ubyte[]` 
pointing to the same memory. And you can have a `void[]` and an 
`int*[]` pointing to the same memory. So if you were allowed to 
copy from `void[]` to `void[]`, you'd practically be allowed to 
copy from `ubyte[]` to `int*[]`. But that's not safe.



That makes a lot of sense. Thanks!



Re: Unwrap variadic template into vararg of pointers of the same types

2022-07-08 Thread wjoe via Digitalmars-d-learn

Corrections:

On Friday, 8 July 2022 at 12:40:52 UTC, wjoe wrote:

alias Recurse = AliasSeq!(Arg[0]*, Recurse!(Arg[0..$]);


```d
 alias Recurse = AliasSeq!(Arg[0]*, Recurse!(Arg[1..$]);
```

void view_it(Args...)(void function(entity_t, Includes!(Args) )


```d
void view_it(Args...)(void function(entity_t, Includes!(Args) 
cb)) {...}

```



Re: Unwrap variadic template into vararg of pointers of the same types

2022-07-08 Thread wjoe via Digitalmars-d-learn

On Friday, 8 July 2022 at 12:20:13 UTC, ryuukk_ wrote:

I'm not sure how to phrase it so it'll try with code

I have this piece of code that i would like to improve, right 
now i have to create bunch of duplicates


```D
void view_it(A, B)(void function(entity_t, A*, B*) cb)
{
foreach(it, e; view!(Includes!(A, B)))
{
auto a = it.get!(A)(e);
auto b = it.get!(B)(e);
cb(e, a, b);
}
}
```

The problem when i try to introduce variadic template, is i 
can't seem to understand how to unwrap the parameter as pointer 
type T -> T*



```D
struct Includes(Args...) { alias args = Args; }

void view_it(Includes)(void function(entity_t, Includes.args* ) 
cb)

{
// do stuff
}

```

I get the following:

```Error: cannot have pointer to `(EEntityRemoved)```

Anyone got an idea?

Thanks!


I suppose you could do something like this:

```d
template Includes(Args...)
{
   template Recurse(Arg...)
   {
  import std.meta: AliasSeq;
  static if (1 == Arg.length)
alias Recurse = AliasSeq!(Arg[0]*);
  else
alias Recurse = AliasSeq!(Arg[0]*, Recurse!(Arg[0..$]);
   }

   alias Includes = Includes!(Args);
}
void view_it(Args...)(void function(entity_t, Includes!(Args) )
```


Cannot copy void[] to void[] in @safe code?

2022-07-08 Thread wjoe via Digitalmars-d-learn

Why is that ?
My understanding is that a void[] doesn't have a distinct type 
but since the length is bytes and not elements this makes me 
believe that under the hood they are byte arrays - or, rather, 
managed chunks of memory.
How's copying memory without a distinct type different from 
copying, say, an ubyte[] to an ubyte[] ?


The compiler doesn't complain about that in @safe code:

```d
@safe void copy_voidA_to_ubyteA(in void[] s) {
  ubyte[] d;
  d.length = s.length;
  d[0..$] = cast(const ubyte[])s[0..$];
}
copy_voidA_to_ubyteA([1,2,3,4]);
```

But what if I copy pointers into an ubyte[] ?
void[] are scanned by the GC but ubyte[] aren't.


Re: How are delegate attributes in fn signature inferred?

2022-05-23 Thread wjoe via Digitalmars-d-learn

On Monday, 23 May 2022 at 13:53:02 UTC, Adam D Ruppe wrote:

On Monday, 23 May 2022 at 13:44:53 UTC, wjoe wrote:

  [...]


You can actually make this work with `construct!(int[])` rather 
than plain `construct`. This is a (really annoying) deficiency 
in dmd's implementation. (that sdc solved btw proving it can be 
done just dmd never bothered)


[...]


I see. I figured the issue was an attribute mismatch.

Thanks for the explanation. Very much appreciated!


How are delegate attributes in fn signature inferred?

2022-05-23 Thread wjoe via Digitalmars-d-learn

Hello,

Consider this example:
```d
module foo;

import std.stdio;
import std.algorithm;
import std.traits;
import std.range;

void print(R)(R r) {
  static assert(isIterable!R);
  r.each!writeln;
}

auto construct(R)(R r, ElementType!R delegate(ulong i) fn) {
  static assert(isIterable!R && hasAssignableElements!R);
  ulong i = 1;
  r.each!((ref e) => e = fn(i));
  return r;
}

unittest {
  int[] i; i.length = 4;
  i.construct((ulong i) {return cast(int)(i+i);}).print;
}
```

```shell

dmd -unittest -main foo.d


Error: template 'foo.construct' cannot deduce function from 
argument types '!()(int[], int function(ulong i) pure nothrow 
@nogc @safe)', candidates are: 'construct(R)(R r, ElementType!R 
delegate(ulong i) fn)'

```

Where's **pure nothrow @nogc @safe** coming from?
Also, why is *(ulong i) {return cast(int)(i+i);}* passed as a 
function?
The error message for passing a delegate is the same except with 
*function* substituted for *delegate*.


Re: Why do immutable variables need reference counting?

2022-04-18 Thread wjoe via Digitalmars-d-learn

On Sunday, 17 April 2022 at 14:14:37 UTC, H. S. Teoh wrote:

Not entirely true. See paragraph 3 in:

https://dlang.org/spec/unittest.html

and 10.24.11.3 in:

https://dlang.org/spec/expression.html#assert_expressions


T


Thanks. Either I missed that the last time I checked or it wasn't 
there ;)
But the interesting question is: does the compiler go out of its 
way to make that happen or is it just paragraphs written in the 
spec?




Re: Why do immutable variables need reference counting?

2022-04-17 Thread wjoe via Digitalmars-d-learn

On Thursday, 14 April 2022 at 12:10:04 UTC, ag0aep6g wrote:

On 14.04.22 13:42, wjoe wrote:
Undefined behavior yes, but regardless the example proves it 
can be done in @system code.
A few versions ago, possibly due to a bug or regression, the 
compiler didn't complain in @safe code either.


Of course you are correct academically. However, since it's 
possible, I'd wager my last hat that code like this is out in 
the wild.


No, it cannot be done in @system code. The example only proves 
that you can write nonsense code that has no defined meaning.


Note that the nonsense you wrote behaves as you describe only 
in Windows. Elsewhere, you get a segfault.


But it doesn't matter how the executable actually behaves. You 
cannot cite the result of undefined behavior when arguing 
language semantics.


Well I'm not using Windows so I wouldn't know but I compiled an 
ran that program on Linux and it didn't segfault. If it had I 
wouldn't have included that part in my reply.


On the matter of undefined behavior. Technically a program is in 
undefined behavior land after throwing an error, thus every 
unittest that continues after assertThrown is therefore nonsense 
code, is it not ?


Re: Why do immutable variables need reference counting?

2022-04-14 Thread wjoe via Digitalmars-d-learn

On Tuesday, 12 April 2022 at 23:23:59 UTC, Ali Çehreli wrote:

[...]


Looking at this from a technical perspective - everything you say 
is true - and thanks for clearing up some of my confusion in that 
department.


Looking at this from a natural language (English) perspective - 
words prompt ideas and expectations. If these expectations aren't 
met confusion and misunderstanding happens (and that's not just 
true for software development).
Although, perhaps, that's only a problem for (some) non native 
English speakers ? The fact remains that there's confusion and 
misunderstandings regarding const, immutable and const 2.




Re: Why do immutable variables need reference counting?

2022-04-14 Thread wjoe via Digitalmars-d-learn

On Tuesday, 12 April 2022 at 22:23:18 UTC, ag0aep6g wrote:

On Tuesday, 12 April 2022 at 19:54:13 UTC, wjoe wrote:
Especially since it's only a promise and the compiler accepts 
this:


void foo (const(char)[] arr)
{
  cast(char[])arr[0..3] = "baz";
}
string bar = "123";
foo(bar);
assert(bar=="baz");

But I could cast away const and modify the string bar.


No, you could not. You're relying on undefined behavior there. 
Just because the compiler accepts something, doesn't mean it's 
ok.


If you want to be guarded against wandering into undefined 
territory, that's what @safe does. With @safe, the cast doesn't 
compile.


Undefined behavior yes, but regardless the example proves it can 
be done in @system code.
A few versions ago, possibly due to a bug or regression, the 
compiler didn't complain in @safe code either.


Of course you are correct academically. However, since it's 
possible, I'd wager my last hat that code like this is out in the 
wild.


Re: Why do immutable variables need reference counting?

2022-04-12 Thread wjoe via Digitalmars-d-learn

On Monday, 11 April 2022 at 22:10:07 UTC, Ali Çehreli wrote:

On 4/11/22 05:57, wjoe wrote:

> And because the data could be
> in ROM any modification is an error.

Fully agreed. However, how could I initialize such an object 
then? (You may have meant a read-only memory page instead of 
ROM.)




I was thinking during compile time. By initializing a variable 
with immutable data or a pointer that points to an address e.G. 
an EEPROM.


Even 'const' cause confusions because it's used in at least two 
different ways (even e.g. in C++):


1) I will not mutate data through this reference. For example, 
a parameter that is pointer to const achieves that:


  void foo (const(int)[] arr);

2) This variable is const:

  const i = 42;

Well, there is the confusion: There is no "reference" in the 
second case at all!


In general, I guess, it's a bad idea to reuse the same word for 2 
or more distinctly different ideas. Maybe the const keyword in 1) 
should have a better name. Especially since it's only a promise 
and the compiler accepts this:


void foo (const(char)[] arr)
{
  cast(char[])arr[0..3] = "baz";
}
string bar = "123";
foo(bar);
assert(bar=="baz");

But I could cast away const and modify the string bar.

So with that said
I don't agree with you when you say immutability should be 
const's domain because const covers item 1 above as well, where 
there is no immutability of data whatsoever. The data may be 
perfectly mutable or immutable, where my access will be 
readonly.


When I said immutability should be the domain of const I am 
referring only to 2).


I.e. immutable is constant data which is created at compile time 
- like laws of physics,
const as in 2) is constant data which is created at run time - 
like man made laws,

and 1) should get a better name - maybe 'in' and get rid of const.

And to be able to use immutable anywhere other than where 
immutable is explicitly specified, a copy is necessary.


I know it's not as simple as that. But one can dream, right? :)


producer from mutating it further. Example:

import std.stdio;
import std.format;

struct S {
  const(char)[] fileName;

  this(const(char)[] fileName) {
this.fileName = fileName;
report();
  }

  ~this() {
report();
  }

  void report(string func = __FUNCTION__) {
writefln!"%s working with %s."(func, fileName);
  }
}

void main() {
  char[] fileName = "foo.txt".dup;
  auto s = S(fileName);
  fileName[0..3] = "bar";
}


If fileName were immutable, then the owner would not be able to 
mutate anyway, so the struct could get away without copying the 
file name.


Ali


I presume you refer to fileName in main() ? And if yes, if it 
were const, it couldn't be mutated either, so isn't immutable and 
const sort of synonymous in that case or am I missing your point?


Re: Why do immutable variables need reference counting?

2022-04-11 Thread wjoe via Digitalmars-d-learn

On Monday, 11 April 2022 at 03:24:11 UTC, Ali Çehreli wrote:

On 4/10/22 20:05, norm wrote:
> On Sunday, 10 April 2022 at 23:19:47 UTC, rikki cattermole
wrote:

> In my mind immutable data
> means the data will not change and neither will the result of
reading
> that data, ever.

Yes.

> I don't get how you can have thread safety guarantees based
on immutable
> if reading that data in a thread suddenly becomes undefined
behaviour
> and could return anything.

Yes, it would be a bug to attempt to read data that is not live 
anymore.


> That isn't immutable then.

The lifetime of immutable data can start and end.

import std.stdio;

struct S {
  int i;

  this(int i) {
this.i = i;
writeln(i, " is (about to be) alive!");
  }

  ~this() {
writeln(i, " is (already) dead.");
  }
}

void main() {
  foreach (i; 0 .. 3) {
immutable s = S(i);
  }
}

The output:

0 is (about to be) alive!
0 is (already) dead.
1 is (about to be) alive!
1 is (already) dead.
2 is (about to be) alive!
2 is (already) dead.

Module-level immutable and 'static const' would live much 
longer but they have a lifetime as well. However, today, the 
destructor cannot be executed on an immutable object, so I 
remove the qualifiers with cast(), which sohuld be undefined 
behavior (today?).


immutable(S) moduleS;

shared static this() {
  moduleS = S(42);
}

shared static ~this() {
  destroy(cast()moduleS);
}

void main() {
}

> Once instantiated
> immutable data persists for the remainder of the program.

That seems to be the misunderstanding. Again, I think 
module-level 'immutable' and 'static const' data fits that 
description.


> You may not
> have access if the variable goes out of scope, but if you do
it will
> always be there and always return the same value when you
read from memory.

That description fits D's GC-owned data (including immutables). 
The lifetime ends when there is no reference to it.


Another example is immutable messages passed between threads 
with std.concurrency: That kind of data clearly originates at 
run time and the receiving end keeps the data alive as long as 
it needs.


Ali


To my understanding immutable data should reside in a separate 
data segment which itself could reside in ROM.
So when the variable, or 'pointer' to the data, goes out of scope 
just the 'pointer' is gone, the actual data unreachable, but 
still there.
Due to its immutable nature immutable data can't be changed and 
this, to my understanding, includes deallocation. And because the 
data could be in ROM any modification is an error. How would you 
deallocate ROM anyways?
Your foreach could be unrolled at compile time, however it could 
easily be changed to a runtime only loop but this entire concept 
of creating immutable data on the fly doesn't make sense to me - 
that should be const's domain. Strings, I know. But the way 
things are, I hardly see a difference between immutable and const.


Re: Importing version identifiers from another file?

2022-04-11 Thread wjoe via Digitalmars-d-learn

On Monday, 11 April 2022 at 08:57:12 UTC, KytoDragon wrote:

[...]
Sadly this results in an identifier conflict, as the version 
set in config.d does not seem to affect library.d. Is there any 
way to import version specifiers from a separate file? I don't 
want to pollute the users build files (dub.json etc.) with 
dozens of versions they need to pass to the compiler.


No, version identifiers don't escape module scope.
See 24.1.4 https://dlang.org/spec/version.html for reference.


Re: What does dual-context mean?

2022-03-02 Thread wjoe via Digitalmars-d-learn

On Tuesday, 1 March 2022 at 17:58:24 UTC, Paul Backus wrote:

On Tuesday, 1 March 2022 at 14:51:47 UTC, wjoe wrote:

Hello,

what's a dual context as in the deprecation message?


It means you have a struct or class member function that 
accesses its calling context via a template alias parameter.


See this bug report for more information: 
https://issues.dlang.org/show_bug.cgi?id=5710


That makes sense. Reading the bug report was really helpful.

Thanks.


What does dual-context mean?

2022-03-01 Thread wjoe via Digitalmars-d-learn

Hello,

what's a dual context as in the deprecation message?

```d
struct MockFile {
  [...]

  void writef(alias fmt, A...)(A args) { // Deprecation: function 
'writef': function requires a dual-context, which is deprecated

import std.format: format;
write(format!fmt(args));
  }

  [...]
}

unittest {
  auto f = MockFile();
  immutable fmt = "%d";
  f.writef!fmt(0); // instatiated from here
}
```




Code coverage exit code 1 on failure?

2021-09-30 Thread wjoe via Digitalmars-d-learn

What's the reasoning behind picking exit code 1 ?
Makes it pretty much impossible to distinguish between a lack of 
coverage code 1 and a process code 1.


Is there a handler where it can be overridden ?


Re: Why sometimes stacktraces are printed and sometimes not?

2021-09-30 Thread wjoe via Digitalmars-d-learn
On Wednesday, 29 September 2021 at 12:15:30 UTC, Steven 
Schveighoffer wrote:

On 9/29/21 6:57 AM, JN wrote:
What makes the difference on whether a crash stacktrace gets 
printed or not?


Sometimes I get a nice clean stacktrace with line numbers, 
sometimes all I get is "segmentation fault error -1265436346" 
(pseudo example) and I need to run under debugger to get the 
crash location.


segmentation faults are memory access errors. It means you are 
accessing a memory address that is not valid for your 
application. If you are accessing the wrong memory, it means 
something is terribly wrong in your program.


[...]


So on Linux, I don't know the behavior on other OSs, the kernel 
sends SIGSEGV to your process which, if unhandled, simply 
terminates your program.
It's an abnormal termination and thus the D runtime or whatever 
library that in a normal case takes care of printing the traces 
doesn't get a chance to do so anymore.


You also change the signal in your handler to get a core dump, 
look here 
http://www.alexonlinux.com/how-to-handle-sigsegv-but-also-generate-core-dump




Re: toString and code coverage...

2021-09-22 Thread wjoe via Digitalmars-d-learn

On Wednesday, 22 September 2021 at 18:59:11 UTC, user1234 wrote:

[...]
I'd use option 2.


Thanks, I'll do just that :)


toString and code coverage...

2021-09-22 Thread wjoe via Digitalmars-d-learn

Is there a convenient way to exclude it from coverage ?
Because adjusting the -cov=xx percentage is kind of annoying and 
may omit other things as well.


Do you care and if yes how do you handle it ?


Re: MobI? Really?

2021-09-22 Thread wjoe via Digitalmars-d-learn

On Tuesday, 21 September 2021 at 16:14:52 UTC, Chris_D wrote:

Thanks for the replies.

jfondren: Sorry, but I am talking about documentation.  For me, 
online web pages don't qualify; they are in the cloud, unreal, 
with no substance.  Does anyone really read 300 pages online, 
in a web browser?  Of course not.




I do, too.
HTML is a markup language specifically created to present text on 
the screen and it is very portable. There's no online requirement 
for viewing HTML either.
A browser is an excellent tool to read it and is installed on 
every platform and device by default.

But it is easily converted or displayed by other software.
HTML is also what ddoc or any other documentation tools generate.
On windows it can be compiled and has a searchable index.

But I share your distaste for online-only documentation. However, 
since it's conveniently installed into 
/usr/share/doc/dmd-[version]/html/d/index.html on my Linux box, 
it's available offline.


You may want to have a look on your hard drive. I'm quite certain 
you've got a local installation, too.


Re: Nondeterministic unittest debugging problem.

2021-08-16 Thread wjoe via Digitalmars-d-learn

On Sunday, 15 August 2021 at 10:32:27 UTC, Rekel wrote:
Note you might need to open the screenshots externally, as they 
are cut off by the forum.


This looks like your build system fails to detect file changes 
and links outdated .o file(s), or library, which causes a 
mismatch between your debug info and the real location of the 
variables. This leads the debugger to look in the wrong place and 
hence can't read the memory. By inserting the variable int x, Mat 
a is then again on the stack frame where it's supposed to be 
according to the debug info. That's my guess anyways.


When I encounter a problem like this I do a 'clean all' followed 
by a full rebuild of both, the lib and the program using it.


Re: Conditional compilation: Which version identifier for release code ? version(assert) ?

2021-08-06 Thread wjoe via Digitalmars-d-learn

On Thursday, 5 August 2021 at 11:54:38 UTC, Mike Parker wrote:

On Thursday, 5 August 2021 at 10:43:01 UTC, wjoe wrote:




Could you elaborate on ```version(assert)``` a bit more, 
please ? Like I compiled with ```-release, -g``` and without 
the 2 options but the ```assert``` branch was always taken. 
Could it be that ```-unittest``` has something to do with it ?


Yes, -unittest overrides -release and enables asserts. 
-check=assert=off overrides both.




It is sort of embarassing reading this after one night's sleep.
But the lesson learned was well worth it, thanks :)

So in light of all of this what I was looking for is 
```D_NoBoundsChecks``` which you mentioned initially.




Re: Conditional compilation: Which version identifier for release code ? version(assert) ?

2021-08-06 Thread wjoe via Digitalmars-d-learn

On Thursday, 5 August 2021 at 11:01:56 UTC, Adam D Ruppe wrote:

On Thursday, 5 August 2021 at 09:18:08 UTC, wjoe wrote:
If it's to be determined whether or not the code is being 
compiled in debug or release mode, i.e. e.g. the dmd 
```-release```


You should never use the -release flag. It should be renamed to 
"-enable-security-holes" since that's what it actually does.




This is good advice. Actually I had no intention to *use* the 
```-release``` option.
My question was aimed at getting an understanding of the 
different version identifiers and how they are affected by the 
command line options in order to be able to pick one that 
reflects the users expectations.

My wording should have been better. Sorry for the confusion.

Instead you can disable specific things as-needed, but it 
is probably never needed. These are also never supposed to 
actually change the behavior of your program, but in reality, 
like I said they do tend to change it - by enabling security 
holes.


However isn't the point of using version identifiers and these 
options to actually change the behavior of the program ?
I mean if bounds checking is enabled I expect the program to 
behave differently, i.e. to abort if something is out of bounds.




Re: Conditional compilation: Which version identifier for release code ? version(assert) ?

2021-08-05 Thread wjoe via Digitalmars-d-learn

On Thursday, 5 August 2021 at 10:08:12 UTC, Mike Parker wrote:

On Thursday, 5 August 2021 at 09:18:08 UTC, wjoe wrote:
Given that we have `version(assert)` and 
`version(D_NoBoundsChecks)`, it probably makes sense to also 
have equivalents to test if contracts are enabled, or if bounds 
checking is enabled only in safe code. Then you'd be able to 
cover all the bases that -release does. Sounds like a candidate 
for an enhancement request.


Thanks, that helps a lot.

I agree about release and debug modes. It got stuck in my mind 
when I used Visual Studio years ago which, at least at the time, 
created a Debug and Release configuration by default.


Could you elaborate on ```version(assert)``` a bit more, please ? 
Like I compiled with ```-release, -g``` and without the 2 options 
but the ```assert``` branch was always taken. Could it be that 
```-unittest``` has something to do with it ?




Conditional compilation: Which version identifier for release code ? version(assert) ?

2021-08-05 Thread wjoe via Digitalmars-d-learn
If it's to be determined whether or not the code is being 
compiled in debug or release mode, i.e. e.g. the dmd 
```-release``` or ```-g``` options, which version identifier is 
supposed to be used ?


There's no ```release``` identifier and ```-debug``` switch and 
```debug()``` condition are something else.


There's ```assert - Checks are being emitted for 
AssertExpressions```. With the exception for ```assert(0)```, 
those checks are omitted in release mode so this could be used 
for that purpose, right?






Re: Generate docs for generated code?

2021-07-23 Thread wjoe via Digitalmars-d-learn

On Friday, 23 July 2021 at 10:54:33 UTC, Adam D Ruppe wrote:

On Friday, 23 July 2021 at 10:04:55 UTC, wjoe wrote:
Is there a way for the compiler to consider doc comments in 
auto generated, mixed in code?


If you use my adrdox generator (which runs on the dpldocs.info 
website), it handles mixin templates. See


http://dpldocs.info/experimental-docs/std.net.curl.HTTP.html#mixed-in-members

for example.

Mine also actually handles

mixin(q{
/// code
void foo() {}
});

as if it was direct.


But my generator only handles mixin templates and mixin string 
literals, not actually generated code returned from a function.


Cool! I take it.

Thanks for making adrdox :)


Re: Generate docs for generated code?

2021-07-23 Thread wjoe via Digitalmars-d-learn

On Friday, 23 July 2021 at 10:42:22 UTC, user1234 wrote:

On Friday, 23 July 2021 at 10:04:55 UTC, wjoe wrote:
Is there a way for the compiler to consider doc comments in 
auto generated, mixed in code?

E.g.
```D
string fooImpl = q{
   /// Bar does fancy things.
   const void bar() { /*do something fancy*/ }
};

/// This is Foo
struct Foo(A, B, C) {
  mixin(fooImpl);
}
```

So that the documentation for ```struct Foo``` has that of the 
member ```bar()``` ?


unfortunately no and this is considered as a 
[bug](https://issues.dlang.org/show_bug.cgi?id=2420)


bummer but thanks for the link.


Generate docs for generated code?

2021-07-23 Thread wjoe via Digitalmars-d-learn
Is there a way for the compiler to consider doc comments in auto 
generated, mixed in code?

E.g.
```D
string fooImpl = q{
   /// Bar does fancy things.
   const void bar() { /*do something fancy*/ }
};

/// This is Foo
struct Foo(A, B, C) {
  mixin(fooImpl);
}
```

So that the documentation for ```struct Foo``` has that of the 
member ```bar()``` ?


Re: opIndexUnary post in-/decrement how to ?

2021-07-16 Thread wjoe via Digitalmars-d-learn

On Thursday, 15 July 2021 at 15:39:59 UTC, Tejas wrote:

On Thursday, 15 July 2021 at 13:28:19 UTC, wjoe wrote:

On Thursday, 15 July 2021 at 12:09:20 UTC, Tejas wrote:

[...]


The only way, for me, to explain the error message ```opIndex 
isn't an lvalue and can't be modified.``` for ```i[1]++``` is 
that the compiler rewrites to

```D
(auto e = i.opIndex(1), i.opIndex(1).opUnary!"++"()/*1) note: 
not opIndexUnary*/, return e;)

```
If it were using ```opIndexUnary``` at 1) it would work.

[...]


Sucks :(

I really can't spend more time on this, hope things work out 
for you somehow.

Best of luck

Regards
Tejas


No worries. Your time is very much appreciated.


Re: opIndexUnary post in-/decrement how to ?

2021-07-15 Thread wjoe via Digitalmars-d-learn

On Thursday, 15 July 2021 at 12:09:20 UTC, Tejas wrote:

[...]

Oh yes, that is what happens. I was trying to be a little 
concise.
You are correct, this is what the code will look in the gory 
details (I believe) :

```d
auto x = (auto e = i.opIndex(1), i.opIndexUnary("++")(1)/*this 
may or may not expand to what you wrote, not sure what the 
compiler does, although what you say does sound like the 
obvious thing to do*/, return e);

```
I did indeed override opIndex() but since i need to apply a 
bit mask and do some shifting I can't return anything by ref.


As I mentioned, maybe the bit manipulation library could 
help(although they don't seem to be overloading the operators 
in the first place, thus sidestepping the problem you 
encountered).


The only way, for me, to explain the error message ```opIndex 
isn't an lvalue and can't be modified.``` for ```i[1]++``` is 
that the compiler rewrites to

```D
(auto e = i.opIndex(1), i.opIndex(1).opUnary!"++"()/*1) note: not 
opIndexUnary*/, return e;)

```
If it were using ```opIndexUnary``` at 1) it would work.

The gist of it
```D
part_int_t!("alpha", 1, "beta", 4, "gamma", 16) a;

struct part_int_t(ARGS...)
{
   int _int;
   mixin(generatePartInt!ARGS);
}

// auto-generated from ARGS
alias typeof_alpha = bool;
enum ulong offset_alpha = 0;
enum ulong mask_alpha = 0x;
// etc.

//getter
@property const pure nothrow @nogc typeof_alpha alpha() {
   if (_int & signmask_alpha)
  return cast(typeof(return))(((_int & mask_alpha) >> 
offset_alpha) | signpad_alpha);

   else
  return cast(typeof(return))((_int & mask_alpha) >> 
offset_alpha);

}

// setter
// ...

const pure nothrow @nogc auto opIndex(size_t _i) {
  switch (_i) {
default:
  assert (0, "Out of bounds.");

 // cases are auto generated from ARGS and mixed in like this
 case 0:
return alpha;

case 1:
 return beta;

case 2:
 return gamma;
}}

// OpIndexAssign, etc.

pure nothrow @nogc auto opIndexUnary(string op)(size_t _i) {
  switch (_i) {
default:
  assert (0, "Out of bounds.");

 // cases are auto generated from ARGS and mixed in like this
 case 0:
typeof_alpha result;
auto tmp = prepare_for_op!(op, "alpha");
mixin(op ~ "tmp");
result = finalize!(op, "alpha")(tmp);
return result;

// ...

}}

// repeat for beta and gamma

```

I'll revisit the bitfields in std.bitmanip but there were 
shortcomings which prompted me to start ```part_int_t```.




Re: Error with implicit cast of ^^=

2021-07-15 Thread wjoe via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 17:29:04 UTC, Ali Çehreli wrote:

On 7/14/21 2:44 AM, wjoe wrote:

>>   x = (x ^^ y).to!(typeof(x));
>> }
>>
>> For example, run-time error if y == 7.

> I was planning on adding support for over-/underflow bits but
this is
> much better. Thanks!

If so, then there is also std.experimental.checkedint:

  https://dlang.org/phobos/std_experimental_checkedint.html

Andrei Alexandrescu introduced it in this presentation:

  https://dconf.org/2017/talks/alexandrescu.html

Ali


Thanks I'll have a look.


Re: opIndexUnary post in-/decrement how to ?

2021-07-15 Thread wjoe via Digitalmars-d-learn

On Thursday, 15 July 2021 at 04:07:49 UTC, Tejas wrote:

Your code
```d
auto x = i[1]++;
```
Expands to:
```d
auto x = (auto e = i[1]/*notice opIndex*/, ++i[1]/* notice 
opIndexUnary*/, return e;);

```

This doesn't happen with pre increment. No compiler shenanigans.


Interesting to see it spelt out like this (your remarks are very 
enlightening) so I just went one step further and rewrote this 
line like so:

```D
i[1] = 3;
auto x = (){auto e = i[1]; ++i[1]; return e;}();
assert (i[1] == 4 && x == 3);
```
This just works. But I don't think this is what happens. What I 
think happens is that the compiler rewrites ```i[1]++`` to 
something like this:

```D
i.opIndex(1).opUnary!"++"();
```
plus all the other shenanigans.

I did indeed override opIndex() but since i need to apply a bit 
mask and do some shifting I can't return anything by ref.


Re: opIndexUnary post in-/decrement how to ?

2021-07-15 Thread wjoe via Digitalmars-d-learn

On Thursday, 15 July 2021 at 04:01:15 UTC, Tejas wrote:

I'm so sorry all this was basically useless for you.

I can't spend more time on this, so as a last resort I leave 
you this:


https://dlang.org/phobos/std_bitmanip.html

This is the official bit manipulation standard library, maybe 
it will help you in some way; the ```bitfield``` struct looked 
mighty familiar to your ```part_int``` struct, but maybe that's 
my cognitive bias,  you should verify it.


Best of luck!


Oh no it wasn't useless at all. The time and effort you put into 
this is very much appreciated and that of everyone else, too.




Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread wjoe via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 16:13:35 UTC, Tejas wrote:

On Wednesday, 14 July 2021 at 15:08:56 UTC, wjoe wrote:

On Wednesday, 14 July 2021 at 14:50:01 UTC, Mike Parker wrote:

On Wednesday, 14 July 2021 at 12:35:07 UTC, wjoe wrote:

[...]


It's how the contract of post-inc/dec work---pre-inc/dec 
return the modified value, post-inc/dec return the original 
value.


[...]


That makes a lot of sense now, thank you!


**IT WORKS NOW**

Thanks vit for the ```ref``` idea!

```d
import   std.stdio;

struct abc{
int[100] a;
static int temp;
ref/*notice this ref*/ int opIndex(int index)return/*NOTICE 
THE RETURN*/ {

return a[index];
}
int opIndexUnary(string s)(int index)
if(s == "++"){
return ++a[index];
}
int[] opUnary(string s)() if (s == "++"){
return a[] += 1;
}
}

void main (){
abc s;

writeln(s[0]++);// doesn't work for some reason EDIT: IT 
NOW WORKS


writeln(s[0]);
writeln(++s[0]);

   // writeln(s++);//but this works!!

   // writeln(s);
}

```


Congratulations:) Unfortunately I haven't got anything I could 
return by ref so I can't take advantage of a low hanging fruit.
In my book overloading operators is no fun - at all - and always 
a last resort because it requires so much time and testing and 
causes so many headaches.


Workarounds exist like ```i[n] += 1``` or direct call via 
```i.opIndexUnary!"++"(n)``` or simply ```++i[n]```.
But that's beside the point. There's nothing in the spec that 
says something about something needs to be returned by ref.
Rewriting manually compiles and works as intended. So clearly 
something else is going on which makes the compiler select 
```opIndex``` over ```opIndexUnary``` rewriting it post to pre.
In my particular case the compiler can rule out ```opIndex``` so 
why does it abort instead of trying ```opIndexUnary``` ? Or was 
it trying and it didn't work ? If that's the case I'd like to 
know the reason why it discarded ```opIndexUnary```.


Anyways all the answers so far are much appreciated!


Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread wjoe via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 14:50:01 UTC, Mike Parker wrote:

On Wednesday, 14 July 2021 at 12:35:07 UTC, wjoe wrote:

[...]


It's how the contract of post-inc/dec work---pre-inc/dec return 
the modified value, post-inc/dec return the original value.


[...]


That makes a lot of sense now, thank you!


Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread wjoe via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 14:39:03 UTC, vit wrote:

On Wednesday, 14 July 2021 at 13:16:49 UTC, Tejas wrote:

On Wednesday, 14 July 2021 at 13:09:56 UTC, vit wrote:

On Wednesday, 14 July 2021 at 12:49:58 UTC, Tejas wrote:

[...]


From doc: https://dlang.org/spec/operatoroverloading.html
Postincrement e++ and Postdecrement e-- Operators
These are not directly overloadable, but instead are 
rewritten in terms of the ++e and --e prefix operators:


Postfix Operator Rewrites
op  rewrite
e-- (auto t = e, --e, t)
e++ (auto t = e, ++e, t)


Rewriting part doesn't work with operator overloading.


If the rewriting part doesn't work with overloading then why 
aren't we allowed to explicitly overload 
```post-increment/decrement``` operators?


How else will the OP solve their problem?

It must rewrite,  otherwise it's impossible (I think).



This work:

```d
import   std.stdio;

struct abc{
int[100] a;

ref int opIndex(int index)return{
return a[index];
}
}

void main (){
abc s;
s[0]++;
++s[0];
}

```


This does work for that example but I can't return by reference 
because what I'm operating on is a part of an int.

Some context:
```D
struct part_int_t(ARGS...)
{
   int _int;
   mixin(generate_parts!ARGS);
}

alias handle_t = part_int_t!("isAllocated", 1, "gen", 8, "index", 
23);


handle_t handle;

static assert (is(handle.typeof_isAllocated): bool));
static assert (is(handle.typeof_gen): ubyte));
static assert (is(handle.typeof_index): uint));

handle[2] = true;
handle.gen = 1;
handle.index = 1234;

assert (handle.isAllocated);
assert (handle.gen = 1);
assert (handle[0] = 1234);

handle++;
assert (handle.index == 1235);

handle.gen++;
assert (handle.gen == 2);

handle.reset();
assert (!handle.isAllocated);
assert (handle.gen = 3);
assert (handle.index = 0);

```

generate_parts!ARGS produces bit masks, getters, setters, 
opIndex/OpAssign/Unary, etc. and it's impossible to return bits 
0-26 of _int by ref.




Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread wjoe via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 12:49:58 UTC, Tejas wrote:


I think it's a bug, because the following works:

```d

import   std.stdio;

struct abc{
int[100] a;
int opIndex(int index){
return a[index];
}
int opIndexUnary(string s)(int index)
if(s == "++"){
return ++a[index];
}
int[] opUnary(string s)() if (s == "++"){
return a[] += 1;
}
}

void main (){
abc s;
int[100] a;
int temp;
writeln (a[20]++);

writeln(a[20]);

writeln(++s[20]);

writeln(s[20]);

//writeln(s[0]++);// doesn't work for some reason

writeln(s[0]);

writeln(s++);//but this works!!

writeln(s);
}

```


```D
writeln(++s[0]); // should work
writeln(s++); // this calls opUnary if I'm not mistaken
```


Re: opIndexUnary post in-/decrement how to ?

2021-07-14 Thread wjoe via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 11:31:36 UTC, Tejas wrote:


``` {auto a = i[1] , ++i[1] , a} //note the , not the ;```

Sorry I can't provide something even more concrete.


Yes I saw that, and I suppose it would work just fine if it were 
rewritten to just  ```++i[1]```.
What I'm struggling to understand is the ```{auto a = i[1], ... 
,a}``` part. I can't parse that. What's up with the assignment 
and the comma stuff ?


Re: catching segfault using try_ catch

2021-07-14 Thread wjoe via Digitalmars-d-learn

On Wednesday, 14 July 2021 at 00:10:59 UTC, seany wrote:

On Tuesday, 13 July 2021 at 17:49:54 UTC, Adam D Ruppe wrote:

On Tuesday, 13 July 2021 at 16:52:43 UTC, seany wrote:

[...]


true if it succeeded.


[...]


You mean transparently rerun some code? That's better done 
with the lowlevel sigaction handler.


[...]


Thank you.

Is there a tutorial on the low level sigaction handlers you 
speak of? Thank oyu


Try core.sys.posix.signal. kill provides a list of signals via 
kill -L.


basically what you do, if I recall correctly (it's been a few 
years), is something like this:

```D
import core.sys.signal;

enum SIGSEGV = 11;
extern (C) void handler(int sig)
{
   switch(sig){
 case SIGSEGV:
   // handle sigsegv
   break;
   }
}

sigset(SIGSEGV, handler);
```


opIndexUnary post in-/decrement how to ?

2021-07-14 Thread wjoe via Digitalmars-d-learn

I'm want to do something like this
```D
part_int_t!(1,2,3) i;

auto x = -i[0];
--i[1]; // 1
i[1]++; // 2

```
I think the operator I need to overload would be opIndexUnary 
which I did.

(1) compiles.
(2) doesn't - the compiler complains that i.opIndex isn't an 
lvalue and can't be modified.
The language spec says that Post in- and decrement are rewritten 
but something's fishy.

What's going on behind the scene and how can I make it work?



Re: Error with implicit cast of ^^=

2021-07-14 Thread wjoe via Digitalmars-d-learn

On Tuesday, 13 July 2021 at 15:14:26 UTC, Ali Çehreli wrote:

On 7/13/21 4:12 AM, wjoe wrote:
> ```D
> byte x = some_val;
> long y = some_val;
>
> x ^^= y; // Error:  cannot implicitly convert expression
> pow(cast(long)cast(int)x, y) of type long to byte

[...]

> I rewrote it to something like
> ```D
> mixin("x = cast(typeof(x))(x" ~ op[0..$-1] ~ " y);");
> ```
> but I'm curious if there's a less convoluted way.

If it's important, std.conv.to checks the value:

import std.conv;

void main() {
  byte x = 2;
  long y = 6;
  x = (x ^^ y).to!(typeof(x));
}

For example, run-time error if y == 7.

Ali


I was planning on adding support for over-/underflow bits but 
this is much better. Thanks!


Error with implicit cast of ^^=

2021-07-13 Thread wjoe via Digitalmars-d-learn

```D
byte x = some_val;
long y = some_val;

x ^^= y; // Error:  cannot implicitly convert expression 
pow(cast(long)cast(int)x, y) of type long to byte

```

Is there a way to do this via ^^= ?

This is part of a unittest for opIndexOpAssign where the type of 
x is that of i.opIndex(_i). It's generated from a list of 
operators like this:


```D
part_int_t!(1, 8, 10) i;
static assert(is(typeof(i[0]): short));
static assert(is(typeof(i[1]): byte));
static assert(is(typeof(i[2]): bool));
static foreach(op; ["+=", "-=", "^^=", ...])
{{
  typeof(i[1]) x;
  mixin("x" ~ op ~ "y;");
  mixin("i[1]" ~ op ~ "y;");
  assert(i == x);
}}
```

I rewrote it to something like
```D
mixin("x = cast(typeof(x))(x" ~ op[0..$-1] ~ " y);");
```
but I'm curious if there's a less convoluted way.


Re: how to filter associative arrays with foreach ?

2021-06-21 Thread wjoe via Digitalmars-d-learn

On Monday, 21 June 2021 at 03:59:10 UTC, someone wrote:
I often need to iterate through a filtered collection 
(associative array) as following:


```d
string strComputerIDunwanted = "WS2"; /// associative array key 
to exclude


foreach (strComputerID, udtComputer; udtComputers) { /// 
.remove!(a => a == strComputerIDunwanted) ... ?


   if (strComputerID != strComputerIDunwanted) {

  ...

   }

}
```

Is there a way to filter the collection at the foreach-level to 
avoid the inner if ?


something like this ?

``` D
import std.array;
import std.algorithm;

udtComputers.byPair
.filter!(p => p.key != strComputerIDunwanted)
.each!( (p) { /* foreach body */ } );
```


Re: Is it possible to set function attributes conditionally?

2021-06-04 Thread wjoe via Digitalmars-d-learn

On Friday, 4 June 2021 at 11:36:09 UTC, Adam D. Ruppe wrote:

On Friday, 4 June 2021 at 11:33:32 UTC, wjoe wrote:
This is a contrived example. In reality I would use this with 
custom array, hash map and other container implementations so 
I could use them in @nogc territory by just switching out the 
allocator.


If they are templates, just don't specify attributes and the 
compiler will infer them for you.


If they are not templates, you have to do a separate copy under 
version or static if.


That's good to know. Thanks :)
A separate copy is exactly what I wanted to avoid but since they 
are templates it's np.




Is it possible to set function attributes conditionally?

2021-06-04 Thread wjoe via Digitalmars-d-learn

Hi,

Consider Allocators, e.g.:

```d
struct Mallocator
{
   enum usesGC = false;

   /// implement alloc, free, etc. @nogc
}

struct GCAllocator
{
  enum usesGC = true;

   /// implement alloc, free, etc. via the GC
}
```

Now I want to have the function attributes set depending on the 
allocator implementation


```d
template AutoGC(ALLOCATOR) if (isAllocator!ALLOCATOR)
{
   static if (!ALLOCATOR.usesGC)
  AutoGC = pragma(attrib, @nogc);
   else
  AutoGC = pragma(attrib, none);
}

@AutoGC!ALLOCATOR void fun(ALLOCATOR)() if(isAllocator!ALLOCATOR)
{
   void* p = ALLOCATOR.alloc(1024);
   // do something with p
   ALLOCATOR.free(p);
}
```

So fun!Mallocator would be @nogc and fun!GCAllocator wouldn't be 
@nogc.


This is a contrived example. In reality I would use this with 
custom array, hash map and other container implementations so I 
could use them in @nogc territory by just switching out the 
allocator.


Is it possible to do something like this ?



Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread wjoe via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 19:08:47 UTC, data pulverizer 
wrote:

On Wednesday, 23 September 2020 at 18:56:33 UTC, wjoe wrote:

[...]


Didn't think that the compiler didn't know but wasn't aware 
that you could use that information to statically dispatch. My 
mistake, I'll shut up now!


Appologies if you took offense. Your replies are very much 
appreciated.


Re: How can I test at compile time whether T is an instance of an interface ?

2020-09-23 Thread wjoe via Digitalmars-d-learn
On Wednesday, 23 September 2020 at 18:49:28 UTC, data pulverizer 
wrote:

On Wednesday, 23 September 2020 at 18:37:45 UTC, wjoe wrote:

[...]


A class at compile time is it's own static type, OOP 
polymorphism is a runtime feature not compile time. You have to 
write your own traits for specific objects to get them to 
relate to each other using static overloading.


It doesn't occur to me that the compiler doesn't know at compile 
time that


interface IFoo{}
class Foo: IFoo {}

class Foo implements interface IFoo.



Re: How can I test at compile time whether T is an instance of an interface ?

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

On Wednesday, 23 September 2020 at 18:50:28 UTC, H. S. Teoh wrote:

Try this:

interface I {}
class C : I {}
class D {}
struct S {}

pragma(msg, is(C : I)); // true
pragma(msg, is(D : I)); // false
pragma(msg, is(S : I)); // false

So probably what you want is something like this:

void register(C, ARGS...)(ARGS args)
if (behavesLikeFoo!C || is(C : IFoo))
...


T


Yes, that's it. Thanks :)


How can I test at compile time whether T is an instance of an interface ?

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

I have some similar functions:

void register(C: IFoo)()
{
  _insert!C();
}

void register(C)() if (behavesLikeFoo!C)
{
  _insert!C();
}

There are more overloads with parameters so I want to merge them

void register(C, ARGS...)(ARGS args) if (behavesLikeFoo!C || 
isInstanceOf!(C, IFoo))

{
  _insert!C(args);
}

I found a lot of information on how to do this at runtime but not 
at compile time.
std.traits: isInstanceOf doesn't work. Neither did anything I 
tried with typeid etc.


The behavesLikeFoo constraint works as expected but it accepts 
any class no matter whether or not it implements the interface.


Re: vibe.d: How to get the conent of a file upload ?

2020-09-20 Thread wjoe via Digitalmars-d-learn

On Sunday, 20 September 2020 at 00:36:30 UTC, Adam D. Ruppe wrote:

[...]


I browsed in your arsd docs a bit and I'll have a closer look at 
the CGI module a bit later.
Your http2 module piqued my interest as it could come in handy 
some time later :)


Looks like your modules cover everything I need and requiring 
only 2 or 3 modules that cover everything I would use from vibe 
beats fighting with dub and vibe's complexity - and I can use a 
simple makefile :) That alone will save a ton of time.


Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread wjoe via Digitalmars-d-learn

On Sunday, 20 September 2020 at 00:36:30 UTC, Adam D. Ruppe wrote:

[...]
That's it - all the html and javascript are all auto-generated.



Amazing :)
Would even be more awesome if it provided a function which could 
be called from a custom main on top of the FancyMain.
I find e.g. custom parsing of command line arguments incredibly 
useful.


Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread wjoe via Digitalmars-d-learn

On Saturday, 19 September 2020 at 20:17:06 UTC, aberba wrote:
I personally (and many others in the industry... judging by 
popularity of express (node.js) and the plentiful third-party 
libraries,..do prefer the router.get() design. Also having 
everything abstracted in a convenient and consistent way...is 
very desirable. vibe.d's web interface API is something I've 
always praised and thanks to how powerful D is compare to say 
JavaScript. Diet templates is also an example.


I'm not a professional web developer and I don't intend to become 
one.
My intention is to live a long and mentally healthy life and web 
development is a serious threat to that ;)


However that power is not tapped in enough (yet) to favour 
using D conveniently over node (js). And web developers are 
interested in getting things done (at least my kind of web 
devs) rather than getting it our way...or squeezing every bit 
of efficiency out of it. Part of why v8 is fast by default (for 
us).


But joking aside, I'm going to use D over Javascript any day of 
the week no questions asked.
And despite my constant bickering, vibe is a huge accomplishment 
and improvement over what I used in the past. So kudos.




Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread wjoe via Digitalmars-d-learn
On Saturday, 19 September 2020 at 19:27:40 UTC, Steven 
Schveighoffer wrote:

[...]
This used to be the expected way to set up vibe (using module 
constructors). And vibe would provide its own main function.


I *think* the idea was to allow registration of different 
handlers in their respective modules.


A reasonable decision if you assume that's the only thing you 
want to do.
Vibe and dub share this philosophy. The author(s) assumed those 
are the only use cases and nothing else flies.
Like for e.g. you can build a D application that uses a C library 
with D glue code and compile the files together in 1 go with GCC, 
maybe with LDC, too, but I haven't tried.

something like: gcc main.d dglue.d clib.c clib.h
But this doesn't work with dub, or at least it didn't work the 
last time I tried a year or so ago.

I'm not a fan of the "The one true way" philosophy.


[...]
I used Kai's book, and yeah, you have to do things the vibe 
way. But most web frameworks are that way I think.


I recommend getting the book if you plan on doing a lot with 
vibe.d


I forgot that I got it some time ago, never really got around to 
take a look however. Thanks for the reminder :)


Where vibe really shines are the diet templates and the web 
interface stuff. To not have to handle anything from forms, or 
query parameters, and just write normal D functions is really 
great. You can even do a lot of authentication and stuff using 
UDAs. It helps you write consistent web applications.


And I LOVE diet templates. So much less verbose than actual 
HTML. I have a hard time writing actual HTML now.


Those are the only reason why I didn't throw it out, yet. Maybe 
it will make up for some of the initial frustration :)


When you want to do stuff manually, I think it's not as well 
supported.


-Steve





Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread wjoe via Digitalmars-d-learn

On Friday, 18 September 2020 at 22:21:52 UTC, Adam D. Ruppe wrote:

On Friday, 18 September 2020 at 22:02:07 UTC, aberba wrote:

[...]


I actually added *exactly* this to cgi.d in... 2010 if I 
remember right. I even kinda documented it: 
http://dpldocs.info/experimental-docs/arsd.cgi.Cgi.UploadedFile.contentInMemory.html


The threshold where it goes to a file is right now 10 MB and 
not configurable, but I've been meaning to go back and clean up 
this api a little. The max file size it accepts is configurable 
 but the threshold where it goes from memory to file is not.




This looks promising. How could I forget about arsd. You have 
something for anything :)


Though I should note that if vibe is putting it in a temporary 
file it probably realistically stays in memory anyway this 
whole thing might be about nothing since the OS is pretty good 
about optimizing temp files.


But if I wanted that sort of "convenience" I would still be using 
PHP ;)


Just I have bigger things to take care of right now (or should 
I say smaller things?!)


:)


Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread wjoe via Digitalmars-d-learn

On Friday, 18 September 2020 at 22:31:09 UTC, mw wrote:

On Friday, 18 September 2020 at 00:07:12 UTC, wjoe wrote:

Are there other frameworks besides vibe that can do what I 
want?


Just FYI, there is also:

https://code.dlang.org/packages/hunt-framework


I never used myself, you need to investigate.


Thanks for the link, I will have a look.


Re: vibe.d: How to get the conent of a file upload ?

2020-09-19 Thread wjoe via Digitalmars-d-learn

On Friday, 18 September 2020 at 22:02:07 UTC, aberba wrote:

[...]


That's what I was trying to answer. When Steve said meh, he 
probably didn't get what I said. Probably its because of my 
typos.


This sort of convenience and productivity benefit is part of 
why I use Node.Js in the job when I need to get things 
doneand not D yet. There are several pieces and bits you 
can't write yourself when working on projects.


In this case you want to get the file(s) in memory...in the 
form of bytes (or buffer) and probably set a file size limit. 
Its all doable through a library but such a library doesn't 
exist in D yet. At least not that I know of.




Yes it would be convenient and thanks for the links but since I'm 
not familiar with Node.js at all parsing the input myself will be 
better than getting into Node.



Vibe.d still lacks many things I personally need... there's 
simply not enough ecosystem third-party libraries.


My first impression of vibe.d is that the author(s) made a 
presumptions about the one way things should be done(tm) and if 
that's not your use case too bad for you.
That's where most of my displeasure of using vibe.d comes from 
and that those aren't described in the documentation - not so 
much because of the things that aren't implemented (yet).


Handling file uploads is one example, another is command line 
arguments.
The presumption here is there is vibe and there can only be vibe. 
It takes them from Runtime.args. Duh?
This didn't make sense to me until I saw example where the 
initialization of vibe was done in a module constructor.
Looks cool on a cursory look but is incredibly impractical if you 
don't want to do it that way. And that's the gist - vibe.d is 
incredibly impractical if your use case doesn't exactly match the 
author(s) assumptions of the one way to do things(tm).
And there are issues with that, too. E.g. in the example the 
server will be started before command line args are completely 
processed. That means if there are wrong or missing or extra args 
the application aborts and leaks OS resources.
The way I would have implemented it is to take args from 
Runtime.args by default but allow passing an args[] to a vibe 
args-handler. I could then parse whatever args I'm interested in 
in my favorite way and pass the rest to vibe.


But you can handle those with vibe getOption or some such - why 
don't you want to do comandline args processing with vibe you ask 
?

Because 1. there's std.getopt which is awesome, and
2. If I don't depend on vibe to parse them and I have a build 
configuration with version="NO_SERVER" I don't even need to link 
against vibe and its dependencies.


By using vibe I feel like I need to bend myself like a snake and 
jump through the hoops of vibe's one way to do it. You save a lot 
of time here and there and then you lose half a day because of 
some stupid road block like the above.


Re: dub: Is it possible to have a library target and depend on it in the same dub config?

2020-09-18 Thread wjoe via Digitalmars-d-learn
On Friday, 18 September 2020 at 14:15:27 UTC, Steven 
Schveighoffer wrote:

On 9/18/20 7:38 AM, wjoe wrote:

[...]


There are other options.

for instance dub (the project) has a library and an 
application. the config looks like this:


configuration "application" {
targetType "executable"
mainSourceFile "source/app.d"
libs "curl"
versions "DubUseCurl" "DubApplication"
}

configuration "library" {
targetType "library"
excludedSourceFiles "source/app.d"
	copyFiles "bin/libcurl.dll" "bin/libeay32.dll" 
"bin/ssleay32.dll" platform="windows"

versions "DubUseCurl"
}

You can also build a subproject in the same repository. In that 
case, you would probably want the app to be the main project, 
and you then depend on the library project via "foo:lib"


-Steve


A subproject. Interesting. this sounds like what I want to do.


Re: dub: Is it possible to have a library target and depend on it in the same dub config?

2020-09-18 Thread wjoe via Digitalmars-d-learn

On Friday, 18 September 2020 at 14:01:55 UTC, Mike Parker wrote:

On Friday, 18 September 2020 at 12:28:30 UTC, wjoe wrote:


2 issues though.
- It doesn't build the library automatically, and


You'll have to invoke dub once for each config. Just slap both 
commands in a script.



- Linking fails because error: ld: cannot find -llib

Built it manually via dub --config=lib and it lives inside the 
lib directory.
Then added lflags "-Llib" to the "app" configuration but that 
didn't help. ld still can't find the file.

Then I passed the absolute path and ld still complains.

Any ideas as to why ?


It's just a matter of getting the configuration right and 
making the linker happy. I don't think I've ever linked with 
anything other than system libraries on Linux, so I really 
don't know what it expects when linking with a custom shared 
library outside of the system path.


I usually either specify the target as a dependency in meson and 
it just works, or I install the library and provide a pkconfig 
file.
I'm only using dub because of vibe and I hope it would just work 
;)


Make sure that your library foo.so is named `libfoo.so`, when 
you pass the lib path along in dflags via -L, then make sure to 
change `libs "lib/foo"` to `libs "foo"`.


This did the trick.

The initial failure may be because of the path in the library 
name. I remember reading somewhere long ago that if you're 
passing a path in the library name (instead of using the -L 
flag), then you have to specify the full file name, e.g. 
lib/libfoo.so. I don't know if dub will pass that along 
correctly though.


Whatever the case, trying adding -v to your dub command line so 
you can see exactly what's dub is calling the compiler with. 
That may give you a hint.


It links correctly now, thanks a lot :)

The only issue left is that I need to build the library manually.


Re: vibe.d: How to get the conent of a file upload ?

2020-09-18 Thread wjoe via Digitalmars-d-learn
On Friday, 18 September 2020 at 12:58:29 UTC, Steven 
Schveighoffer wrote:

On 9/18/20 8:39 AM, Steven Schveighoffer wrote:
But again, solved with an enhancement that allows you to 
process the data in your code. I'll file the enhancement 
request for you, as I think it's a nice addition.


https://github.com/vibe-d/vibe.d/issues/2478

-Steve


Awesome! Thanks a ton :)


Re: vibe.d: How to get the conent of a file upload ?

2020-09-18 Thread wjoe via Digitalmars-d-learn
On Friday, 18 September 2020 at 12:39:43 UTC, Steven 
Schveighoffer wrote:

On 9/17/20 8:07 PM, wjoe wrote:

[...]


See the code here: 
https://github.com/vibe-d/vibe.d/blob/ebebfa827f568cc9bced4bec2b66edc043a8adf7/inet/vibe/inet/webform.d#L311



[...]


No, not at the moment. Which is why I was saying, it could be 
an enhancement request to vibe.



[...]


All the data is processed before the accessor to the form data 
or the file data. It HAS to be this way, as the data is still 
on the incoming network socket.



[...]


Yes


[...]


Again, enhancement request needed. The code currently is 
hard-coded to write to disk.



[...]


If you had 1000 requests being processed simultaneously, and 
each of those requests provided 10MB files, then you now need 
potentially 10GB of RAM to hold those requests. This doesn't 
scale when the application is unknown to vibe.


But again, solved with an enhancement that allows you to 
process the data in your code. I'll file the enhancement 
request for you, as I think it's a nice addition.



[...]


Agreed. In my case, it was an actual copy, as the location of 
the stored data was on a different filesystem than the 
temporary files.



[...]


Yep, it's a waste in that case.


[...]


Agreed.


[...]


In D, I'm not sure what the other frameworks do. I believe 
there are others if you search on code.dlang.org, you should be 
able to find some.



[...]


web development sucks in general ;) Yet, we all still do it.

-Steve


I was a little tired yesterday when I read the replies. After a 
couple hours of sleep and reading them again it makes a lot more 
sense to me.


Also your suggestion about a direct call to 
vibe.inet.webform.parseFormData with a specific handler for files 
and form data is a lot better than access via byte[].


Thanks for your help. Very much appreciated :)



Re: dub: Is it possible to have a library target and depend on it in the same dub config?

2020-09-18 Thread wjoe via Digitalmars-d-learn

On Friday, 18 September 2020 at 12:03:45 UTC, Mike Parker wrote:

On Friday, 18 September 2020 at 11:38:14 UTC, wjoe wrote:

Something like this:

configuration "lib" {
  targetType "dynamicLibrary"
  sourceDir "source/lib/"
}

configuration "app" {
  targetType "executable"
  sourceFiles "source/app.d"
  linkWith "lib"
}

I found subConfiguration in the docs but that seems to be 
related to external dependencies.


app.d merely provides a CLI to the library as well as an 
option to run as a server. I don't want to have the overhead 
of an entire git repo and such for something that is a single 
file and also closely related to the library.


Yes, this is possible. Should be something like this:

configuration "lib" {
   targetType "dynamicLibrary"
   targetPath "lib"
   sourcePaths "source/lib/"
   excludedSourceFiles "source/app.d"
}

configuration "app" {
   targetType "executable"
   mainSourceFile "source/app.d"
   excludedSourceFiles "source/lib/*.d"
   importPaths "source/lib"
   libs "lib/libName"
}


Awesome. Thanks. And Danny to you, too.

2 issues though.
- It doesn't build the library automatically, and
- Linking fails because error: ld: cannot find -llib

Built it manually via dub --config=lib and it lives inside the 
lib directory.
Then added lflags "-Llib" to the "app" configuration but that 
didn't help. ld still can't find the file.

Then I passed the absolute path and ld still complains.

Any ideas as to why ?


Re: vibe.d: How to get the conent of a file upload ?

2020-09-18 Thread wjoe via Digitalmars-d-learn

On Friday, 18 September 2020 at 11:44:39 UTC, Atwork wrote:

On Friday, 18 September 2020 at 00:07:12 UTC, wjoe wrote:
And if not, how is data processed with a 10mb file upload 
followed by a few number fields ?
It needs to read all of the file data to get to the other data 
fields, doesn't it ?


Yes and no


Consider this:

~$ curl -F "temperature_log=@/var/log/temperatures.log" -F 
"field1=a" -F "field2+foo" 192.168.1.1:20222/temperature_upload



~$ nc -l 127.0.0.1 20222

POST /temperature_upload HTTP/1.1
Host: 192.168.1.1:20222
User-Agent: curl/7.72.0
Accept: */*
Content-Length: 10486005
Content-Type: multipart/form-data; 
boundary=c73c71472ff9e7d5


--c73c71472ff9e7d5
Content-Disposition: form-data; name="temperature_log"; 
filename="/var/log/temperatures.log"

Content-Type: application/octet-stream

temp_1=22;temp_2=28
temp_1=21;temp_2=25

[ ... 10 MB of data ... ]

--c73c71472ff9e7d5
Content-Disposition: form-data; name="field1"

a
--c73c71472ff9e7d5
Content-Disposition: form-data; name="field2"

foo
--c73c71472ff9e7d5--


How is vibe going to extract field1 and field2 without processing 
the temperature_log field ?




dub: Is it possible to extend or specialize configurations ?

2020-09-18 Thread wjoe via Digitalmars-d-learn

configuration "app" {
  versions "CLI"
  target "executable"
  ...
}

configuration "guiapp" : "app" {
  versions "GUI"
  sourceFiles "source/gui.d"
}

The guiapp should basically inherit the "app" configuration and 
extend/override whatever else is needed/different.


dub: Is it possible to have a library target and depend on it in the same dub config?

2020-09-18 Thread wjoe via Digitalmars-d-learn

Something like this:

configuration "lib" {
  targetType "dynamicLibrary"
  sourceDir "source/lib/"
}

configuration "app" {
  targetType "executable"
  sourceFiles "source/app.d"
  linkWith "lib"
}

I found subConfiguration in the docs but that seems to be related 
to external dependencies.


app.d merely provides a CLI to the library as well as an option 
to run as a server. I don't want to have the overhead of an 
entire git repo and such for something that is a single file and 
also closely related to the library.




Re: vibe.d: How to get the conent of a file upload ?

2020-09-17 Thread wjoe via Digitalmars-d-learn
On Thursday, 17 September 2020 at 22:33:46 UTC, Steven 
Schveighoffer wrote:

On 9/17/20 6:13 PM, aberba wrote:
On Thursday, 17 September 2020 at 21:57:37 UTC, Steven 
Schveighoffer wrote:

On 9/17/20 1:08 PM, wjoe wrote:

[...]


the `files` property actually does the processing only when 
you call it.


If you access the `bodyReader` property directly, you can 
process that data yourself. You can even register a web 
interface function with an `InputStream` parameter type, and 
it will be bound to the body data.


I'm not sure I understand how to do this and parser the files 
in memory.


So an HTTP request with form data will come in with the headers 
parsed, but the data is still on the network stream.


The first time you access `files`, it processes the stream 
data, and splits it into form data and file data, saves the 
files, and then gives you back the file dictionary so you can 
use them.


If instead, you access `bodyReader`, YOU get to process the 
form data and file data.




I've done this with my REST interface, though that's not form 
data.


That's not a great API, though. I would love to see vibe.d 
allow a direct call to vibe.inet.webform.parseFormData with a 
specific handler for files and form data.
Can we file an issue for this? Because I'm very interested in 
having this resolved


You can always file an issue! 
https://github.com/vibe-d/vibe.d/issues


There may already be one in there.

There's potential to results in out of memory condition. Its a 
know issues. A complete parser (like multer in nodejs) 
allowance you to limit file size as well for error handling.


Meh, this is D :) we should be able to just process the data 
and do whatever we want with it. What I would like to see is 
vibe provide the parsing of form data, and just give me the 
data as it comes (kind of like a SAX parser). Maybe just a 
property in the HTTPServerRequest that I can set that says "use 
this callback when you get Form File data".


I've done this with my REST interface, though that's not form 
data.


Can you share your code for this?


Heh, this is not form data, it's just file data, raw on the 
stream. So I have a function like:


```
class FileRestImpl
{
@path(":cat/:id/:uuid/upload")
@getAuth
void postUpload(HTTPServerResponse res, string _cat, int 
_id, string _uuid, InputStream stream, Nullable!string md5sum, 
NRMAuthInfo _authInfo)

{
...
}
}
```

You can see, I take an InputStream as a parameter -- the data 
comes in there. I just read it and save it to a file (in the 
correct location) anyway, verifying the md5sum is valid.


-Steve


Not a reply to this post in particular but to all the ones I've 
read so far.


If I understand correctly. Vibe parses the form data and writes 
all files to disk. Where to ?
Can I configure it ? I don't want libraries to just write data to 
my file systems without me setting this up. Nowhere did I find 
this behavior described in the docs.
And if not, how is data processed with a 10mb file upload 
followed by a few number fields ?
It needs to read all of the file data to get to the other data 
fields, doesn't it ?


I'm sorry this is completely counter intuitive. I can understand 
the memory/security risks and all but I have no intention to 
hack, DOS or however else disrupt my private server in my private 
network with garbage data. I just want to get the data in a 
byte[].


Why does the lib not simply reject files that are unreasonably 
(configurable) big ?
Writing files to disk in order to then needing to copy them 
somewhere else or to read them back into memory for further 
processing sounds, above all else, incredibly inefficient.

I might not even want to keep the file and drop it.

I guess it's no problem to parse the data myself, but then what's 
the point in using a framework ?


Are there other frameworks besides vibe that can do what I want ?

I'm sorry for the rant, developing this kind of software is a 
pain in the drain and stresses me out to no end. It sucked hard 
in the past with php and decades later with python, ruby, D, you 
name it it still sucks ;)


Still, thanks a lot for all the replies everybody. Very much 
appreciated :)




Re: Building LDC runtime for a microcontroller

2020-09-17 Thread wjoe via Digitalmars-d-learn
On Thursday, 17 September 2020 at 19:27:41 UTC, Adam D. Ruppe 
wrote:
fyi my baby was just born i'll come back to this but it might 
be a day or two


congratulations! All the best for your family :)


Re: vibe.d: How to get the conent of a file upload ?

2020-09-17 Thread wjoe via Digitalmars-d-learn

On Thursday, 17 September 2020 at 16:32:55 UTC, WebFreak001 wrote:

On Thursday, 17 September 2020 at 16:00:33 UTC, wjoe wrote:
I found this [1] but unfortunately the post this refers to is 
a dead link and the content, unfortunately, didn't tell me 
anything that I didn't already find in the docs.


What I can get from the form is the form fields with content, 
the field name for the file upload and the file name. But the 
file name is useless to me because I need the file content.


Where is it stored ?

[1] https://aberba.com/2017/multiple-file-upload-in-vibe-d/


hi, you can access HTTPServerRequest.files which contains the 
uploaded file.


Example in real code: 
https://github.com/WebFreak001/ImageUploader/blob/master/source/app.d#L141-L159


Documentation: https://vibed.org/api/vibe.inet.webform/FilePart

Note: the file is only downloaded from the client / stored on 
disk once you access the files or the form property, though 
this isn't documented.


Every post or example I found copies the file, like your code 
does, too. Why is that ? The content of the file upload is 
embedded in the form data. There's no need for temporary files or 
copying at all.


On top of that, if I upload a file to a server which is on a 
different PC on a different file system, how am I supposed to 
read the file from disk on a remote file system ?


This makes no sense.

What I want is something like this:


~$ cat /var/log/temperatures.log

temp_1=22;temp_2=28
temp_1=21;temp_2=25



~$ curl -F "temperature_log=@/var/log/temperatures.log" 
192.168.1.1:20222/temperature_upload



~$ nc -l 127.0.0.1 20222

POST /temperature_upload HTTP/1.1
Host: 192.168.1.1:20222
User-Agent: curl/7.72.0
Accept: */*
Content-Length: 245
Content-Type: multipart/form-data; 
boundary=c73c71472ff9e7d5


--c73c71472ff9e7d5
Content-Disposition: form-data; name="temperature_log"; 
filename="/var/log/temperatures.log"

Content-Type: application/octet-stream

temp_1=22;temp_2=28
temp_1=21;temp_2=25

--c73c71472ff9e7d5--



void upload(HttpRequest.. req, blah)
{
   auto file = "temperature_log" in req.files;
   if (file) {
  string temp_data_raw = file.data;
  assert ("temp_1=22;temp_2=28\ntemp_1=21;temp_2=25" == 
temp_data_raw);

   }
}



vibe.d: How to get the conent of a file upload ?

2020-09-17 Thread wjoe via Digitalmars-d-learn
I found this [1] but unfortunately the post this refers to is a 
dead link and the content, unfortunately, didn't tell me anything 
that I didn't already find in the docs.


What I can get from the form is the form fields with content, the 
field name for the file upload and the file name. But the file 
name is useless to me because I need the file content.


Where is it stored ?

[1] https://aberba.com/2017/multiple-file-upload-in-vibe-d/


Re: Why is BOM required to use unicode in tokens?

2020-09-16 Thread wjoe via Digitalmars-d-learn
On Tuesday, 15 September 2020 at 01:49:13 UTC, James Blachly 
wrote:
I wish to write a function including ∂x and ∂y (these are 
trivial to type with appropriate keyboard shortcuts - alt+d on 
Mac), but without a unicode byte order mark at the beginning of 
the file, the lexer rejects the tokens.


It is not apparently easy to insert such marks (AFAICT no 
common tool does this specifically), while other languages work 
fine (i.e., accept unicode in their source) without it.


Is there a downside to at least presuming UTF-8?


As you probably already know BOM means byte order mark so it is 
only relevant for multi byte encodings (UTF-16, UTF-32). A BOM 
for UTF-8 isn't required an in fact it's discouraged.


Your editor should automatically insert a BOM if appropriate when 
you save your file. Probably you need to select the appropriate 
encoding for your file. Typically this is available in the 'Save 
as..' dialog, or the settings.




Re: Why is there no throws, @gc, impure, mutable ?

2020-09-07 Thread wjoe via Digitalmars-d-learn

On Monday, 7 September 2020 at 11:44:40 UTC, Paul Backus wrote:

On Monday, 7 September 2020 at 11:25:15 UTC, wjoe wrote:
It's easy to declare the entire module @safe and functions 
which can't be can be declared @system.
However there is const, immutable, pure, @nogc and nothrow but 
no mutable, impure, @gc and throws.


Why is that ?


Mostly because nobody's bothered to add them (yet). There's an 
accepted proposal to add a "throw" attribute as the opposite of 
nothrow [1], but it looks like it still hasn't been implemented 
in the compiler.


For const and immutable, you can use std.traits.Unconst [2] to 
remove them in most cases.


[1] 
https://github.com/dlang/DIPs/blob/master/DIPs/accepted/DIP1029.md
[2] 
http://dpldocs.info/experimental-docs/std.traits.Unconst.html


Very interesting. Thanks.


Why is there no throws, @gc, impure, mutable ?

2020-09-07 Thread wjoe via Digitalmars-d-learn
It's easy to declare the entire module @safe and functions which 
can't be can be declared @system.
However there is const, immutable, pure, @nogc and nothrow but no 
mutable, impure, @gc and throws.


Why is that ?



Re: Reading from stdin significantly slower than reading file directly?

2020-08-13 Thread wjoe via Digitalmars-d-learn

On Thursday, 13 August 2020 at 07:08:21 UTC, Jon Degenhardt wrote:

Test  Elapsed  System   User
  ---  --   
tsv-select -f 2,3 FILE  10.280.42   9.85
cat FILE | tsv-select -f 2,311.101.45  10.23
cut -f 2,3 FILE 14.640.60  14.03
cat FILE | cut -f 2,3   14.361.03  14.19
wc -l FILE   1.320.39   0.93
cat FILE | wc -l 1.180.96   1.04


The TREE file:

Test  Elapsed  System   User
  ---  --   
tsv-select -f 2,3 FILE   3.770.95   2.81
cat FILE | tsv-select -f 2,3 4.542.65   3.28
cut -f 2,3 FILE 17.781.53  16.24
cat FILE | cut -f 2,3   16.772.64  16.36
wc -l FILE   1.380.91   0.46
cat FILE | wc -l 2.022.63   0.77




Your table shows that when piping the output from one process to 
another, there's a lot more time spent in kernel mode. A switch 
from user mode to kernel mode is expensive [1].
It costs around 1000-1500 clock cycles for a call to getpid() on 
most systems. That's around 100 clock cycles for the actual 
switch and the rest is overhead.


My theory is this:
One of the reasons for the slowdown is very likely mutex 
un/locking of which there is more need when multiple processes 
and (global) resources are involved compared to a single instance.

Another is copying buffers.
 When you read a file the data is first read into a kernel buffer 
which is then copied to the user space buffer i.e. the buffer you 
allocated in your program (the reading part might not happen if 
the data is still in the cache).
If you read the file directly in your program, the data is copied 
once from kernel space to user space.
When you read from stdin (which is technically a file) it would 
seem that cat reads the file which means a copy from kernel to 
user space (cat), then cat outputs that buffer to stdout (also 
technically a file) which is another copy, then you read from 
stdin in your program which will cause another copy from stdout 
to stdin and finally to your allocated buffer.

Each of those steps may invlovle a mutex un/lock.
Also with pipes you start two programs. Starting a program takes 
a few ms.


PS. If you do your own caching, or if you don't care about it 
because you just read a file sequentially once, you may benefit 
from opening your file with the O_DIRECT flag which basically 
means that the kernel copies directly into user space buffers.


[1] https://en.wikipedia.org/wiki/Ring_(computer_security)


Re: Could someone calrify reserving and collecting memory via the Garbabe Collector ?

2020-08-06 Thread wjoe via Digitalmars-d-learn
On Thursday, 6 August 2020 at 17:18:12 UTC, rikki cattermole 
wrote:

On 07/08/2020 5:12 AM, wjoe wrote:
There's core.memory.GC.reserve which requests memory from the 
OS. Basically pre-allocating memory for the GC heap.


Is the GC heap shared among all threads ?


That is up to the GC implementation.


That means to be able to reason about it, I need to read the 
implementation and should it change, my reasoning might be wrong 
all of a sudden.


And is it correct that even if I call GC.disable, the GC may 
still start a collection run if, for instance, there's an 
allocation but no free memory on the GC heap ?


"Disables automatic garbage collections performed to minimize 
the process footprint. Collections may continue to occur in 
instances where the implementation deems necessary for correct 
program behavior, such as during an out of memory condition. 
This function is reentrant, but enable must be called once for 
each call to disable."


https://dlang.org/phobos/core_memory.html#.GC.disable

So yes.

Note, out of memory is related to the process, rather than GC 
internals (it does play a part, but lets just go with process).


I've read that but wasn't sure.
But the process isn't necessarily out of memory when the GC heap 
is completely in use.
Instead of starting a collection, the GC could for instance 
request more memory from the OS.


Thanks for your reply.


Could someone calrify reserving and collecting memory via the Garbabe Collector ?

2020-08-06 Thread wjoe via Digitalmars-d-learn
There's core.memory.GC.reserve which requests memory from the OS. 
Basically pre-allocating memory for the GC heap.


Is the GC heap shared among all threads ?
E.g what happens if I GC.reserve(4.MiB) ? Is it 4 MiB in total or 
per thread ?


And is it correct that even if I call GC.disable, the GC may 
still start a collection run if, for instance, there's an 
allocation but no free memory on the GC heap ?


Re: dynamic array .length vs .reserve - what's the difference?

2020-08-03 Thread wjoe via Digitalmars-d-learn
On Saturday, 1 August 2020 at 16:04:01 UTC, Steven Schveighoffer 
wrote:

On 7/31/20 12:32 PM, wjoe wrote:

On Friday, 31 July 2020 at 04:28:57 UTC, Ali Çehreli wrote:
Another option, which is curiously said to be more performant 
in memory allocation than native arrays, is 
std.array.Appender. I've used function-local static Appenders 
to cut down on memory allocation. Here is an uncompiled 
pseudo code:


[...]


This looks like an even better way to do it.

Thanks, Ali :)


Just FYI, the reason this is faster is because there is no need 
to go through the opaque calls into druntime to figure out if 
appending-in-place is possible. The reserved length is stored 
directly in the struct.


-Steve


That's good to know, thanks :)
By the looks of it, Appender is half duplicating the runtime :)


Re: dynamic array .length vs .reserve - what's the difference?

2020-07-31 Thread wjoe via Digitalmars-d-learn

On Friday, 31 July 2020 at 04:28:57 UTC, Ali Çehreli wrote:
Yes but the "sharing being terminated" phrase was my attempt at 
explaining things, which did not catch on. :)


Real shame. I quite like it - especially if you say it out loud 
with an Austrian accent :)



Another option, which is curiously said to be more performant 
in memory allocation than native arrays, is std.array.Appender. 
I've used function-local static Appenders to cut down on memory 
allocation. Here is an uncompiled pseudo code:


[...]


This looks like an even better way to do it.

Thanks, Ali :)


Re: dynamic array .length vs .reserve - what's the difference?

2020-07-30 Thread wjoe via Digitalmars-d-learn

On Thursday, 30 July 2020 at 16:33:22 UTC, Ali Çehreli wrote:

On 7/30/20 8:58 AM, wjoe wrote:


     b.reserve(n);
     b.length = n;


There may be something that I don't know but I think assigning 
to the .length property alone should be the same as reserving 
and then assigning.


reserve is supposed to make sure no memory will be allocated as 
elements are added.


So whichever instruction is redundant depends on whether I want 
an array of length n, or an empty array that can grow to at least 
n elements without reallocation.


This article is considered a must-read for understanding what 
is going on behind the scenes:


  https://dlang.org/articles/d-array-article.html

I tried to introduce the concept of slices "sharing elements" 
as well as how .capacity is used to determine whether sharing 
will be terminated, here:


  http://ddili.org/ders/d.en/slices.html#ix_slices..capacity

Ali


These resources are great. Thanks.



On Thursday, 30 July 2020 at 16:55:35 UTC, Steven Schveighoffer 
wrote:

On 7/30/20 11:58 AM, wjoe wrote:

Also there's .capacity - is that equivalent to reserve ?


Capacity tells you how many total elements the current reserved 
space can hold. If the array is not appendable, then this 
returns 0.


So .capacity can't be assigned a value like length to reserve the 
RAM ?


Another curiosity I noticed is that the docs say that the 
runtime tries to resize in place, however:


b = b[0..$-1]; if length==1 seems to collect the memory at 
once because if it's immediately followed by b.length = 1; or 
b ~= someT; b.ptr points to a new address.

Why ?


Because you would be overwriting the data already in the array.

For example:

auto a = b;
b = b[0 .. $-1];
b ~= someT;

If that last line is done in-place, then it overwrites a[$-1].


So this is a case of sharing being terminated ?

If you know that it's OK to do this, then you should call 
assumeSafeAppend on the array (which will adjust the "used" 
space down to the current array).


This array is a private array of pointers to released structs - 
technically a stack.
Every time a new element is requested, the most recently released 
element would be taken off the stack and be set to the new data 
until the stack was exhausted.
Expired structs are put back into (appended to) the array for 
reuse.
When the length of the array == 0, upon releasing a struct, this 
array is reallocated which isn't supposed to happen. It should 
just grow like it did with length > 1.

assumeSafeAppend should accomplish that :)


I know that b=b[0..0]; is equivalent to b = null;


No, if slicing b to b[0 .. 0], b.ptr does not change. b = null 
sets the pointer to null. In the former case, if you called 
assumeSafeAppend on it, then it could append in-place at that 
point. With the null pointer, it would reallocate.


-Steve


I could swear just a few weeks ago there was someone asking how 
to tell if an array was null or of length 0 and an answer was 
that it's the same and can't be distinguished so I assumed that 
assigning a slice of 0 length is the same as setting the array to 
null because the result is the same as a 0 length array.

Thanks for the explanations and corrections.



bachmeier, a picture tells more than a thousand words. Your 
illustration is very comprehensive. Thanks :)



Thank you everyone, your input is very much appreciated :)


dynamic array .length vs .reserve - what's the difference?

2020-07-30 Thread wjoe via Digitalmars-d-learn

I just stumbled upon code like this:

struct Foo(T)
{
T[] b;

this(int n)
{
b.reserve(n);
b.length = n;
}
}

.reserve looks redundant.

The docs are explaining .length nicely, however lack any 
specifics about reserve.


Changing the length of an array may relocate and copy. New items 
are initialized with T.init - is that true for both length and 
reserve ?


Also there's .capacity - is that equivalent to reserve ?

Another curiosity I noticed is that the docs say that the runtime 
tries to resize in place, however:


b = b[0..$-1]; if length==1 seems to collect the memory at once 
because if it's immediately followed by b.length = 1; or b ~= 
someT; b.ptr points to a new address.

Why ?

I know that b=b[0..0]; is equivalent to b = null; but I still 
don't understand the need for a new allocation when b could be 
resized in place.
How can I hold on to the memory originally reserved by b but at 
the same time allow the array to temporarily be empty?


Re: Good way to send/receive UDP packets?

2020-07-28 Thread wjoe via Digitalmars-d-learn

On Tuesday, 28 July 2020 at 15:01:08 UTC, Kagamin wrote:

On Monday, 27 July 2020 at 09:41:44 UTC, wjoe wrote:
But it's possible when bound with the socket option 
SO_REUSEPORT (at least that's the name of the flag on linux 
since 3.9).


The docs say it can't be used to hijack an address.
This option must be set on each socket (including the first 
socket) prior to calling bind(2) on the socket.


Nowhere did I claim that you could hijack a bound port but that 
it's possible to reuse a port.


Nothing prevents a UDP library from setting that option 
automatically or by default.
Nothing prevents any program to bind to a port with that option 
set.


Normal behavior doesn't matter - what matters is what the library 
you're using and other programs are doing.


All of this doesn't change the fact that every program that has a 
socket bound to the same port on the same address at the same 
time will get the datagrams deliverd.


One way to handle this scenario is to bind your socket with the 
reuse option unset.

That would be first come first served.
Problem not solved - you still need to consider the fact that 
another program or server on a different PC/address in the 
network can assume that their corresponding client is up and 
running and wants to receive on that very port.
Due to the nature of UDP communication, the server needn't care 
if this assumption is true  and send datagrams to it which you 
will receive instead.




Re: Why are std.bitmanip.bitfields so big ?

2020-07-28 Thread wjoe via Digitalmars-d-learn
On Tuesday, 28 July 2020 at 13:00:12 UTC, Steven Schveighoffer 
wrote:

On 7/28/20 5:46 AM, MoonlightSentinel wrote:

On Tuesday, 28 July 2020 at 09:28:27 UTC, wjoe wrote:
It was run on the doc page. I suppose the examples are 
wrapped in a unittest block?


Indeed, see 
https://github.com/dlang/phobos/blob/cd2ba0d2c378a893ec0eaefc57b87d0770a1990c/std/bitmanip.d#L293-L314




It doesn't necessarily need to be in a unittest block (AFAIK, 
the example executer isn't actually running the unittests of 
phobos), but it does need to be inside a function, because you 
have executable code there. Either way, yes, it's run inside a 
function, so you need to apply static to the struct to avoid 
the frame pointer. I tested that, and it prints 1 instead of 16.


-Steve


My reasoning was that a unittest is essentially a function and 
it's incredibly convenient for such things but I hadn't really 
checked prior to MoonlightSentinel's reply.


Thanks again :)


Re: Why are std.bitmanip.bitfields so big ?

2020-07-28 Thread wjoe via Digitalmars-d-learn

On Tuesday, 28 July 2020 at 09:46:01 UTC, MoonlightSentinel wrote:

On Tuesday, 28 July 2020 at 09:28:27 UTC, wjoe wrote:
It was run on the doc page. I suppose the examples are wrapped 
in a unittest block?


Indeed, see 
https://github.com/dlang/phobos/blob/cd2ba0d2c378a893ec0eaefc57b87d0770a1990c/std/bitmanip.d#L293-L314


Thank you.


Re: Why are std.bitmanip.bitfields so big ?

2020-07-28 Thread wjoe via Digitalmars-d-learn
On Monday, 27 July 2020 at 12:52:53 UTC, Steven Schveighoffer 
wrote:

On 7/27/20 5:49 AM, wjoe wrote:

struct A
{
     mixin(bitfields!(
    bool, "flag1",    1,
    bool, "flag2",    1,
    uint, "", 6));
}


Is this inside a function? If so, put `static` on it.

What you are seeing is the 8-byte frame pointer that comes from 
inner structs so you can access stack variables inside the 
struct.


-Steve


It was run on the doc page. I suppose the examples are wrapped in 
a unittest block?


Anyways, I appreciate your explanation.


Why are std.bitmanip.bitfields so big ?

2020-07-27 Thread wjoe via Digitalmars-d-learn

From the API documentation:


Create a bitfield pack of eight bits, which fit in one ubyte.
[...]

struct A
{
mixin(bitfields!(
   bool, "flag1",1,
   bool, "flag2",1,
   uint, "", 6));
}

A a;
writeln(a.flag1); // 0
a.flag1 = 1;
writeln(a.flag1); // 1
a.flag1 = 0;
writeln(a.flag1); // 0
writeln(a.sizeof);




Application output

false
true
false
16


I would expect a sizeof 1. Why is its size 16 ?

Source: https://dlang.org/library/std/bitmanip/bitfields.html


Re: Good way to send/receive UDP packets?

2020-07-27 Thread wjoe via Digitalmars-d-learn

On Thursday, 23 July 2020 at 13:29:47 UTC, Kagamin wrote:

On Wednesday, 22 July 2020 at 16:14:24 UTC, wjoe wrote:
If you send a UDP datagram to a single address, however, it 
will still be delivered to every program on that PC which 
receives UDP datagrams from that port.


Normally binding two sockets to the same port is not allowed.


But it's possible when bound with the socket option SO_REUSEPORT 
(at least that's the name of the flag on linux since 3.9).


Re: Good way to send/receive UDP packets?

2020-07-22 Thread wjoe via Digitalmars-d-learn

On Wednesday, 22 July 2020 at 16:14:24 UTC, wjoe wrote:
When receiving packets, the IP header contains the destination 
address of your public IP (the router), which it will translate 
to the local address according to the port forwarding setup.


Pardon me, I meant to say according to the current routing table 
rules.
Port Forwarding forwards all packets that match the defined 
criteria to the specified PC in the network.
A port forwarding rule isn't required for NAT to work. Sender and 
receiver both need to send a packet to each other. This will 
cause the router to add a rule and expect an answer on that port 
from the destination address.
When this packet arrives before the rule has been made it will be 
dropped (unless a port forwarding rule exists), so several 
packets may need to be sent for a successful punch-through.




Re: Good way to send/receive UDP packets?

2020-07-22 Thread wjoe via Digitalmars-d-learn

On Wednesday, 22 July 2020 at 15:26:23 UTC, Dukc wrote:

On Wednesday, 22 July 2020 at 13:17:11 UTC, wjoe wrote:
- Choosing a port which isn't in use right now isn't good 
enough because a few minutes later there may be another 
program using it, too, and for the same reason.


But doesn't the UDP header include the sender IP address? So 
together with the magic number, shouldn't it be good enough? I 
know it definitely is not going to hold against jamming or a 
man in the middle, but it isn't supposed to, at this stage. 
It's used only for simulations that have the criticality of a 
casual Tetris server.


I do acknowledge that the needs may rise later on. And if so, I 
understand that I'm much better off switching the protocol than 
trying to hardening the UDP.


No, the UDP header includes the source and destination ports only.
For transmission over the internet the Internet Protocol (IP) is 
used, which contains, among other things, the source and 
destination addresses.


The anatomy looks like this:

[  IP - Datagram -- ]
[IP-Header][UDP-Header][UDP-Data]
   [ - UDP - Datagram - ]

But keep in mind that the destination address can be a broadcast 
address, like e.g. 255.255.255.255, which you would use to 
announce your server to every PC in the network.
If you send a UDP datagram to a single address, however, it will 
still be delivered to every program on that PC which receives UDP 
datagrams from that port.


Also if you send UDP datagrams to multiple specific addresses, 
you need to send the same packet multiple times losing the major 
benefit of UDP - broadcast.
And packets with a broadcast address sent over the internet are 
dropped, as that would affect every connected PC.


If you are behind a router and send over the internet, your 
router will modify the IP-header, namely the sender address and 
replace that with your public address.
When receiving packets, the IP header contains the destination 
address of your public IP (the router), which it will translate 
to the local address according to the port forwarding setup.
That process is called network address translation (NAT) and is 
not only relevant for UDP.




Re: Good way to send/receive UDP packets?

2020-07-22 Thread wjoe via Digitalmars-d-learn

On Tuesday, 21 July 2020 at 18:35:34 UTC, notna wrote:
well, I guess all your remarks are true... and irrelevant at 
the same time.


please go back and read his first post starts with "I have 
a project where I need to take and send UDP packets over the 
Internet"...


... and continues with:

On Saturday, 18 July 2020 at 16:00:09 UTC, Dukc wrote:
[...] And only communication with a single address, no need to 
communicate with multiple clients concurrently.


Let me elaborate on why what I wrote is both, on topic and 
relevant at the same time:


It's a fundamental characteristic of UDP that you can't 
communicate with a single client only but you always are 
communicating with everyone who listens concurrently.


The combination of the Internet and theoretically only 65535 
available ports means that (mis)communication with other clients 
is likely to happen.
OP's client may receive datagrams that are broadcast on that port 
by other programs (port forwarding).
Likewise, other programs, which have a socket bound to the same 
port, may receive OP's data.


Examples:
- You behaving correctly yourself doesn't make others behave 
correctly now or retroactively.


- Choosing a port which isn't in use right now isn't good enough 
because a few minutes later there may be another program using 
it, too, and for the same reason.


- Checking a magic byte at offset 0 followed by the size isn't 
good enough.
Let's say I decide my magic is a word because I want to be able 
to determine byte order - I choose 0x015a.
When I broadcast a packet, e.g. [[0x015a], [0x0, 0x5a, 0xff]], 
but because I sent this from a little endian machine, the 
datagram will be delivered like so [0x5a, 0x01, 0x0, 0x5a, 0xff].

When OP's client receives this message it goes like so:
Read 2 bytes: [0x5a, 0x1]
 0x5a, oh that's me, 0x01 aha length of 1 byte - except it's not 
even a valid packet in the context of their program...


Using UDP in a good way is far more complicated than it first 
appears to be.




Re: Good way to send/receive UDP packets?

2020-07-21 Thread wjoe via Digitalmars-d-learn

On Sunday, 19 July 2020 at 09:48:24 UTC, notna wrote:
Someone once wrote about a UDP library, which was used to sync 
data to somewhere in APAC (Hongkong?) and by doing so the data 
transfer was magnitudes faster then before (over TCP)...




In the best case scenario, and orders of magnitude more 
unreliable otherwise.


Choosing UDP over TCP because speed is like choosing a hammer 
over a screwdriver to drive in a screw because it works and is 
faster. But it's still the wrong tool for the job.


UDP is a protocol for broadcasting messages which means it's 
connection less, unreliable (as in no guarantees for delivery of 
datagrams or that they'll be delivered only once, order i.e. 
datagrams sent in order A B C D can be delivered like e.g B C A 
D), and data integrity.

It's insecure (as in everyone who listens can receive it).

Once you need any of these features/guarantees you'll lose 
performance just as you would by using TCP, plus you pay the cost 
for re-inventing the wheel, bugs, testing, maintenance, support 
and all.


UDP is the protocol of choice when you want to broadcast, the 
data you send isn't important or the TCP overhead is bigger than 
the transmitted message. Like broadcasting radio/podcasts, 
weather updates for your status bar or some such or DNS queries.


If you need reliable transmission you need to use a reliable 
protocol.


Re: miscellaneous array questions...

2020-07-21 Thread wjoe via Digitalmars-d-learn

On Monday, 20 July 2020 at 22:05:35 UTC, WhatMeWorry wrote:
2) "The total size of a static array cannot exceed 16Mb" What 
limits this? And with modern systems of 16GB and 32GB, isn't 
16Mb excessively small?   (an aside: shouldn't that be 16MB in 
the reference instead of 16Mb? that is, Doesn't b = bits and B 
= bytes)


Static arrays are passed by value.

(Also I think you're right about Mb vs MB except it should be 
MiB. 1MB = 1000^2 (decimal) and 1MiB = 1024^2 (binary).
Note that MB is defined 1024^2 in JEDEC 100B.01 but, IMO, ISO 
standard is superior because it's unambiguous and JEDEC only 
defines units up to GB (inclusive))


Re: What's the point of static arrays ?

2020-07-13 Thread wjoe via Digitalmars-d-learn

On Friday, 10 July 2020 at 21:24:08 UTC, Ali Çehreli wrote:

What is important is overhead:


That's the major point I took from all this.
Thanks for your effort.

And thanks everybody else, too, I really appreciate it.


Re: What's the point of static arrays ?

2020-07-10 Thread wjoe via Digitalmars-d-learn

On Friday, 10 July 2020 at 14:20:15 UTC, wjoe wrote:

On Friday, 10 July 2020 at 10:47:49 UTC, psycha0s wrote:

On Friday, 10 July 2020 at 10:13:23 UTC, wjoe wrote:
A static array resides in this memory (with a fixed length, so 
a length needn't be stored because bounds can be checked at 
compile time) if declared as a variable and is accessed via 
stack pointer and offset.


resides is the wrong word again, sorry.

A static array is mapped into stack memory...




Re: What's the point of static arrays ?

2020-07-10 Thread wjoe via Digitalmars-d-learn

On Friday, 10 July 2020 at 11:13:51 UTC, Stanislav Blinov wrote:

On Friday, 10 July 2020 at 10:13:23 UTC, wjoe wrote:

So many awesome answers, thank you very much everyone!

Less overhead,
Using/needing it to interface with something else, and
Efficiency are very good points.

However stack memory needs to be allocated at program start. I 
don't see a huge benefit in allocation speed vs. heap 
pre-allocation, or is there?


Stack is allocated by the OS for the process when it's started. 
Reserving space for stack variables, including arrays, is 
effectively free, since the compiler assigns offsets statically 
at compile time.


I mean 1 allocation vs 2 isn't going to noticeably improve 
overall performance.


A GC allocation is way more complex than a mere 
bump-the-pointer. If your program is trivial enough you may 
actually find that one extra GC allocation is significant in 
its runtime. Of course, if you only ever allocate once and your 
program runs for ages, you won't really notice that allocation.




I think that memory for the program must be allocated when the 
process is created, this includes the stack, etc. but it is an 
allocation in computer RAM nonetheless.


A pre-allocated amount of memory for a dynamic array once is one 
additional allocation throughout the entire run time of the 
program.
Now I can't make any guess about how this allocation takes place 
- it might be allocated via malloc, a pool, new, etc. - but it is 
one additional allocation.
What I'm saying is even if this allocation is slow let's say 5ms, 
but it only happens once, that wouldn't matter to overall 
performance at all.


But performance isn't the focus of this question.

No. A slice is just a pointer/length pair - a contiguous view 
into *some* memory, regardless of where that memory came from:


Metadata is data that describes other data - a pointer/length 
pair, which describs a continuous view into memory, is matching 
that criteria, doesn't it ?
An array is, by definition, a length of the same kind of element 
mapped into continuous memory, no ?


A dynamic array is a pointer/length pair, a slice is a 
pointer/length pair, too.
Can a function, which is passed both, a dynamic array and a 
slice, tell the two apart, as in distinguish between the two ?
Also, can this function distinguish a slice of a dynamic array 
from a slice of a static array ?


void takeASlice(scope void[] data) // can take any slice since 
any slice converts to void[]

{
import std.stdio;
writefln("%x %d", data.ptr, data.length);
}

int[10] a;
takeASlice(a); // a[]
takeASlice(a[1 .. $-1]); // a[1 .. 9]

struct S
{
float x, y, z;
float dx, dy, dz;
}

S s;
takeASlice(()[0 .. 1]); // Slicing a pointer, not @safe but 
can be done.

takeASlice(new int[10]); // Array, GC allocation
takeASlice([1, 2, 3, 4]); // Array literal, may or may not be 
GC-allocated


`takeASlice` has no knowledge of where the memory came from.

Dynamic arrays only ever come into the picture if you try to 
manipulate the slice itself: resize it, append to it, etc.


that it's not possible to slice a static array because the 
slice would technically be akin to a dynamic array and hence 
be incompatible.


Incompatible to what?


void foo(int[4] a){}

int[4] x;
auto slice = x[];
foo(slice); // that's incompatible, isn't it?

Thank you for your explanations :)


  1   2   >