Re: Mixin helper help

2023-01-13 Thread bauss via Digitalmars-d-learn

On Friday, 13 January 2023 at 16:54:34 UTC, Ali Çehreli wrote:

On 1/13/23 00:48, bauss wrote:

> 1. Change your mixin template to something like this:

There was a technique as a workaround for this template mixin 
limitation but I can't find it right now.


> 2. Change the place where you instantiate to this:

I think the workaround I am trying to remember would not 
require any change for the users.


Ok, it was something like this:

mixin template myStatement() {
auto doIt() {
import std.stdio : writeln;
writeln("hi");
return 0;
}

auto ignoreThis = doIt();
}

void main() {
mixin myStatement!();
mixin myStatement!();
}

Ali


That's a good one!


Re: Failed to archive JPEG (ArchiveMember): Invalid UTF-8 sequence (at index 1)

2023-01-13 Thread Ki Rill via Digitalmars-d-learn

On Saturday, 14 January 2023 at 01:13:33 UTC, Adam D Ruppe wrote:

On Saturday, 14 January 2023 at 01:08:25 UTC, Ki Rill wrote:

a JPEG image.


member.expandedData(file.readText().dup().representation());


A jpeg image is not a text file. Read it with `std.file.read()` 
instead of `readText`. Then you can get rid of those useless 
dup.representation calls too.


Thank you for such a quick reply! It solved my issue!


Re: Failed to archive JPEG (ArchiveMember): Invalid UTF-8 sequence (at index 1)

2023-01-13 Thread Adam D Ruppe via Digitalmars-d-learn

On Saturday, 14 January 2023 at 01:08:25 UTC, Ki Rill wrote:

a JPEG image.

member.expandedData(file.readText().dup().representation());


A jpeg image is not a text file. Read it with `std.file.read()` 
instead of `readText`. Then you can get rid of those useless 
dup.representation calls too.


Failed to archive JPEG (ArchiveMember): Invalid UTF-8 sequence (at index 1)

2023-01-13 Thread Ki Rill via Digitalmars-d-learn
Please, help me solve the annoying error above. I've been 
refactoring and rewriting code for my archive utility called 
[zippo](https://github.com/rillki/zippo) and I face this error 
when it tries to archive a JPEG image.


I tracked it down to the following function that helps me add a 
new member to `ZipArchive`.


```D
void zipAddArchiveMember(ref ZipArchive zip, in string file) {
import std.conv: to;
import std.file: readText;
import std.string: representation;

ArchiveMember member = new ArchiveMember();
member.name = file;
writefln("%s", file);
member.expandedData(file.readText().dup().representation());
member.compressionMethod = CompressionMethod.deflate;
zip.addMember(member);
}
```

Am I missing something?



Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread Gavin Ray via Digitalmars-d-learn

On Friday, 13 January 2023 at 19:16:17 UTC, H. S. Teoh wrote:
On Fri, Jan 13, 2023 at 08:31:17AM -0800, Ali Çehreli via 
Digitalmars-d-learn wrote:

On 1/13/23 07:07, Gavin Ray wrote:

> This is "valid" D I hope?

Yes because static arrays are just elements side-by-side in 
memory. You can cast any piece of memory to a static array 
provided the length and alignment are correct.

[...]

Or to be more precise, cast the memory to a *pointer* to a 
static array of the right size.  Static arrays are by-value 
types; passing around the raw array will cause the array to be 
copied every time, which is probably not what is intended.



T


Thanks Teoh and Ali, I wound up passing a pointer to a static 
array.


If anyone is curious, here's the full WIP implementation -- it's 
for a toy database (Postgres-like) I'm writing for a hobby and 
learning project:


https://ldc.godbolt.org/z/Kvh7dv96c


Re: Coding Challenges - Dlang or Generic

2023-01-13 Thread Salih Dincer via Digitalmars-d-learn

On Friday, 13 January 2023 at 18:59:01 UTC, matheus wrote:

Unfortunately it's not working for me


Yeah, it was an old development version. I also implemented 
another version the same day:


* [Nested 
Class](https://forum.dlang.org/thread/vkjhkftvyprsivozy...@forum.dlang.org)
* [Only One 
Struct](https://forum.dlang.org/post/thxvuddjimgswalzo...@forum.dlang.org)


SDB@79

Sory...


Re: Unittests on a module

2023-01-13 Thread Dennis via Digitalmars-d-learn

On Friday, 13 January 2023 at 19:07:46 UTC, DLearner wrote:

Is this intended?


It is by design, though opinions differ on whether it's a good 
design.



It's not a problem to add temporary
```
void main() {

}
```
to the bottom of the module,


You can add the `-main` flag to make dmd automatically add such 
an empty main function when there isn't a `main` already.





Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jan 13, 2023 at 08:31:17AM -0800, Ali Çehreli via Digitalmars-d-learn 
wrote:
> On 1/13/23 07:07, Gavin Ray wrote:
> 
> > This is "valid" D I hope?
> 
> Yes because static arrays are just elements side-by-side in memory.
> You can cast any piece of memory to a static array provided the length
> and alignment are correct.
[...]

Or to be more precise, cast the memory to a *pointer* to a static array
of the right size.  Static arrays are by-value types; passing around the
raw array will cause the array to be copied every time, which is
probably not what is intended.


T

-- 
"You are a very disagreeable person." "NO."


Unittests on a module

2023-01-13 Thread DLearner via Digitalmars-d-learn
If unittest run without a main() being present, crashes on link 
error:

```
lld-link: error: subsystem must be defined
Error: linker exited with status 1
```

Is this intended?

It's not a problem to add temporary
```
void main() {

}
```
to the bottom of the module, but seems wrong as not then testing 
_exactly_ what is to be imported elsewhere.


Re: Coding Challenges - Dlang or Generic

2023-01-13 Thread matheus via Digitalmars-d-learn

On Thursday, 12 January 2023 at 19:06:49 UTC, Salih Dincer wrote:

...

Now, I wrote a nested class using range and copying from 
Matheus' code. Of course not as comprehensive as [your 
dcal](https://github.com/quickfur/dcal/blob/master/dcal.d). I 
like this one and even thought of a new challenge!


...


Hi Salih,

Unfortunately it's not working for me:

.d(79): Error: found `End of File` when expecting `}` following 
compound statement


So I think it's missing a "}" in main, and after I added that, it 
gives:


.d(46): Error: undefined identifier `replicated`, did you mean 
template `replicate(S)(S s, size_t n) if (isDynamicArray!S)`?


Matheus.


Re: Mixin helper help

2023-01-13 Thread Ali Çehreli via Digitalmars-d-learn

On 1/13/23 00:48, bauss wrote:

> 1. Change your mixin template to something like this:

There was a technique as a workaround for this template mixin limitation 
but I can't find it right now.


> 2. Change the place where you instantiate to this:

I think the workaround I am trying to remember would not require any 
change for the users.


Ok, it was something like this:

mixin template myStatement() {
auto doIt() {
import std.stdio : writeln;
writeln("hi");
return 0;
}

auto ignoreThis = doIt();
}

void main() {
mixin myStatement!();
mixin myStatement!();
}

Ali



Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread Ali Çehreli via Digitalmars-d-learn

On 1/13/23 07:22, Gavin Ray wrote:
> Maybe it would be better to wrap the slice in a new class with an
> invariant?

Possibly but please check before using because I think 'invariant' 
requires presence of member functions:


  https://dlang.org/spec/struct.html#Invariant

> Because what I want to do is:
>
> 1. Ensure that the length of the underlying referenced/pointed-to data
> is `PAGE_SIZE`

My first thought was why not use a slice anyway?

Worth noting that static arrays are value types. Also, they all have 
different types from each other and have the potential to cause template 
bloat.


> class BufferPool

Off-topic, most D programmers use struct unless they need class.

>  Frame[BUF_POOL_NUM_PAGES] frames;

Makes sense to me.

Ali



Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread Ali Çehreli via Digitalmars-d-learn

On 1/13/23 07:07, Gavin Ray wrote:

> This is "valid" D I hope?

Yes because static arrays are just elements side-by-side in memory. You 
can cast any piece of memory to a static array provided the length and 
alignment are correct.


However, such a cast is not allowed in @safe code.

Ali



Re: Why not allow elementwise operations on tuples?

2023-01-13 Thread H. S. Teoh via Digitalmars-d-learn
On Fri, Jan 13, 2023 at 02:22:34PM +, Sergei Nosov via Digitalmars-d-learn 
wrote:
> Hey, everyone!
> 
> I was wondering if there's a strong reason behind not implementing
> elementwise operations on tuples?
> 
> Say, I've decided to store 2d points in a `Tuple!(int, int)`. It would
> be convenient to just write `a + b` to yield another `Tuple!(int,
> int)`.

I've written a Vec type that implements precisely this, using tuples
behind the scenes as the implementation, and operator overloading to
allow nice syntax for vector arithmetic.

---snip
/**
 * Represents an n-dimensional vector of values.
 */
struct Vec(T, size_t n)
{
T[n] impl;
alias impl this;

/**
 * Per-element unary operations.
 */
Vec opUnary(string op)()
if (is(typeof((T t) => mixin(op ~ "t"
{
Vec result;
foreach (i, ref x; result.impl)
x = mixin(op ~ "this[i]");
return result;
}

/**
 * Per-element binary operations.
 */
Vec opBinary(string op, U)(Vec!(U,n) v)
if (is(typeof(mixin("T.init" ~ op ~ "U.init"
{
Vec result;
foreach (i, ref x; result.impl)
x = mixin("this[i]" ~ op ~ "v[i]");
return result;
}

/// ditto
Vec opBinary(string op, U)(U y)
if (isScalar!U &&
is(typeof(mixin("T.init" ~ op ~ "U.init"
{
Vec result;
foreach (i, ref x; result.impl)
x = mixin("this[i]" ~ op ~ "y");
return result;
}

/// ditto
Vec opBinaryRight(string op, U)(U y)
if (isScalar!U &&
is(typeof(mixin("U.init" ~ op ~ "T.init"
{
Vec result;
foreach (i, ref x; result.impl)
x = mixin("y" ~ op ~ "this[i]");
return result;
}

/**
 * Per-element assignment operators.
 */
void opOpAssign(string op, U)(Vec!(U,n) v)
if (is(typeof({ T t; mixin("t " ~ op ~ "= U.init;"); })))
{
foreach (i, ref x; impl)
mixin("x " ~ op ~ "= v[i];");
}

void toString(W)(W sink) const
if (isOutputRange!(W, char))
{
import std.format : formattedWrite;
formattedWrite(sink, "(%-(%s,%))", impl[]);
}
}

/**
 * Convenience function for creating vectors.
 * Returns: Vec!(U,n) instance where n = args.length, and U is the common type
 * of the elements given in args. A compile-time error results if the arguments
 * have no common type.
 */
auto vec(T...)(T args)
{
static if (args.length == 1 && is(T[0] == U[n], U, size_t n))
return Vec!(U, n)(args);
else static if (is(typeof([args]) : U[], U))
return Vec!(U, args.length)([ args ]);
else
static assert(false, "No common type for " ~ T.stringof);
}

///
unittest
{
// Basic vector construction
auto v1 = vec(1,2,3);
static assert(is(typeof(v1) == Vec!(int,3)));
assert(v1[0] == 1 && v1[1] == 2 && v1[2] == 3);

// Vector comparison
auto v2 = vec(1,2,3);
assert(v1 == v2);

// Unary operations
assert(-v1 == vec(-1, -2, -3));
assert(++v2 == vec(2,3,4));
assert(v2 == vec(2,3,4));
assert(v2-- == vec(2,3,4));
assert(v2 == vec(1,2,3));

// Binary vector operations
auto v3 = vec(2,3,1);
assert(v1 + v3 == vec(3,5,4));

auto v4 = vec(1.1, 2.2, 3.3);
static assert(is(typeof(v4) == Vec!(double,3)));
assert(v4 + v1 == vec(2.1, 4.2, 6.3));

// Binary operations with scalars
assert(vec(1,2,3)*2 == vec(2,4,6));
assert(vec(4,2,6)/2 == vec(2,1,3));
assert(3*vec(1,2,3) == vec(3,6,9));

// Non-numeric vectors
auto sv1 = vec("a", "b");
static assert(is(typeof(sv1) == Vec!(string,2)));
assert(sv1 ~ vec("c", "d") == vec("ac", "bd"));
assert(sv1 ~ "post" == vec("apost", "bpost"));
assert("pre" ~ sv1 == vec("prea", "preb"));
}

unittest
{
// Test opOpAssign.
auto v = vec(1,2,3);
auto w = vec(4,5,6);
v += w;
assert(v == vec(5,7,9));
}

unittest
{
int[4] z = [ 1, 2, 3, 4 ];
auto v = vec(z);
static assert(is(typeof(v) == Vec!(int,4)));
assert(v == vec(1, 2, 3, 4));
}

unittest
{
import std.format : format;
auto v = vec(1,2,3,4);
assert(format("%s", v) == "(1,2,3,4)");
}
---snip


T

-- 
Never ascribe to malice that which is adequately explained by incompetence. -- 
Napoleon Bonaparte


Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread Gavin Ray via Digitalmars-d-learn
Maybe it would be better to wrap the slice in a new class with an 
invariant?


Because what I want to do is:

1. Ensure that the length of the underlying referenced/pointed-to 
data is `PAGE_SIZE`

2. Benefit from the features of D that I can

The bounds-checking of slices saves a lot of headaches during 
development.


So maybe doing something like this might be better?

```d
struct Frame
{
ubyte[] data;

invariant
{
assert(data.length == PAGE_SIZE);
}
}

class BufferPool
{
align(PAGE_SIZE) ubyte[PAGE_SIZE * BUF_POOL_NUM_PAGES] data;
Frame[BUF_POOL_NUM_PAGES] frames;

this()
{
// mmap
foreach (i; 0 .. BUF_POOL_NUM_PAGES)
{
frame_idx_t frame_idx = cast(frame_idx_t) i;
			frames[frame_idx].data = data[frame_idx * PAGE_SIZE .. 
(frame_idx + 1) * PAGE_SIZE];

}
}
}
```







Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread Gavin Ray via Digitalmars-d-learn

On Friday, 13 January 2023 at 14:57:40 UTC, Ali Çehreli wrote:

On 1/13/23 06:49, Gavin Ray wrote:

> I am curious if you can return something like
`ubyte[PAGE_SIZE]*` or
> `ref ubyte[PAGE_SIZE]`?

A simple cast seems to work:

enum PAGE_SIZE = 4096;
enum BUF_POOL_NUM_PAGES = 1024;
alias frame_idx_t = size_t;

ubyte[10_000] data;

ubyte[PAGE_SIZE]* get_page(frame_idx_t frame_idx)
{
auto ptr = data.ptr + frame_idx * PAGE_SIZE;
return cast(ubyte[PAGE_SIZE]*)ptr;
}

void main() {
}

Ali


Ah, much thanks Ali!

This is "valid" D I hope?

I searched Github for `"ubyte[4096]*"` and I found two uses of 
it, in the `xtrix` repo which seems to be an Operating System 
written in D:


![screenshot-of-ubyte-sized-ptr-on-github](https://i.imgur.com/WaAklbq.png)



Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread Ali Çehreli via Digitalmars-d-learn

On 1/13/23 06:49, Gavin Ray wrote:

> I am curious if you can return something like `ubyte[PAGE_SIZE]*` or
> `ref ubyte[PAGE_SIZE]`?

A simple cast seems to work:

enum PAGE_SIZE = 4096;
enum BUF_POOL_NUM_PAGES = 1024;
alias frame_idx_t = size_t;

ubyte[10_000] data;

ubyte[PAGE_SIZE]* get_page(frame_idx_t frame_idx)
{
auto ptr = data.ptr + frame_idx * PAGE_SIZE;
return cast(ubyte[PAGE_SIZE]*)ptr;
}

void main() {
}

Ali



Re: Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread Gavin Ray via Digitalmars-d-learn
I probably should have mentioned, the equivalent in C++ is the 
below:


```cpp
#include 
#include 
#include 

static constexpr size_t PAGE_SIZE  = 4096;
static constexpr size_t BUF_POOL_NUM_PAGES = 1024;

class BufferPool
{
  private:
alignas(PAGE_SIZE) std::byte data[BUF_POOL_NUM_PAGES * 
PAGE_SIZE];


  public:
BufferPool()
{
mmap(data, BUF_POOL_NUM_PAGES * PAGE_SIZE,
 PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 
-1, 0);

}

// Return a fat-pointer of PAGE_SIZE bytes over the page, 
containing { T* ptr, len }

std::span get_page(size_t page_num)
{
return std::span(data + page_num * 
PAGE_SIZE, PAGE_SIZE);

}
};
```



Creating a pointer/slice to a specific-size buffer? (Handing out a page/frame from a memory manager)

2023-01-13 Thread Gavin Ray via Digitalmars-d-learn
Suppose that you have a memory manager, or arena-like class, 
which contains a buffer used to store memory.


And you want to hand out chunks of this memory to other parts of 
your program. These chunks should all be `PAGE_SIZE`.



You might have something like:

```d
enum PAGE_SIZE = 4096;
enum BUF_POOL_NUM_PAGES = 1024;

class BufferPool
{
align(PAGE_SIZE) ubyte[PAGE_SIZE * BUF_POOL_NUM_PAGES] data;

this()
{
mmap(, data.sizeof,
 PROT_READ | PROT_WRITE, MAP_ANONYMOUS | 
MAP_PRIVATE, -1, 0);

}
}
```

Now there should be a function, like `get_page()`, that returns a 
`PAGE_SIZE` pointer of `ubyte`. But I can only figure out how to 
return a `ubyte[]`:


```d
ubyte[] get_page(frame_idx_t frame_idx)
{
	return data[frame_idx * PAGE_SIZE .. (frame_idx + 1) * 
PAGE_SIZE];

}
```

I am curious if you can return something like `ubyte[PAGE_SIZE]*` 
or `ref ubyte[PAGE_SIZE]`?


Thank you =)





Re: Mixin helper help

2023-01-13 Thread Salih Dincer via Digitalmars-d-learn

On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote:
Why does the commented code work but the mixin not? Thanks for 
any pointers.


Why not directly use the mixin template for opDispatch()?

```d
mixin template helper() {
  void opDispatch(string name)() {
import std.stdio;
writeln(12);
  }
}

struct Foo {
  mixin helper;
  // ...
}

void main() {
  Foo.init.opDispatch!"bar"();
}
```

SDB@79



Why not allow elementwise operations on tuples?

2023-01-13 Thread Sergei Nosov via Digitalmars-d-learn

Hey, everyone!

I was wondering if there's a strong reason behind not 
implementing elementwise operations on tuples?


Say, I've decided to store 2d points in a `Tuple!(int, int)`. It 
would be convenient to just write `a + b` to yield another 
`Tuple!(int, int)`.


I can resort to using `int []` arrays and write elementwise 
operations as `c[] = a[] + b[]` which is almost fine - but it 
uses dynamic allocation and forces the user to create an explicit 
destination variable.


It seems a bit awkward given that it's fairly straightforward to 
write smth as


```
T opBinary(string op, T)(T lhs, T rhs)
if (isTuple!T)
{
T result;

static foreach (i; 0 .. T.Types.length)
{
mixin("result.field[i] = 
lhs.field[i]"~op~"rhs.field[i];");

}

return result;
}
```

You only need to turn it into a member function to make it work. 
You can even make it more general and allow such operations for 
different, but compatible tuple types (there's a function 
`areCompatibleTuples` to check for such compatibility). Yet, 
there's only a specialization for tuple concatenation of 
`opBinary` (and an implementation of `opCmp` and `opAssign`).


So, to repeat the question - is this a deliberate decision to not 
implement the default elementwise operation?




Re: Should importC fail on invalid C code?

2023-01-13 Thread Dennis via Digitalmars-d-learn

On Friday, 13 January 2023 at 12:50:44 UTC, kdevel wrote:

Should importC fail on invalid C code?


In general, no. The purpose is to build / interface with existing 
C code, not to develop new C code with it. ImportC also has its 
own extensions by borrowing D features such as __import, CTFE, 
and forward references. A strict C compiler would reject those.


Should importC fail on invalid C code?

2023-01-13 Thread kdevel via Digitalmars-d-learn
After reading Walter's remark "ImportC sees those macro 
definitions and transforms them into manifest constant 
declarations" in


Issue 23622 - ImportC #defines conflict with declarations

I wondered how it was implemented:

`myccode.c`
```
int getx ()
{
   return X;
#define X 1
}
```

`imc.d`
```
unittest {
   import myccode;
   assert (false, "Should img.c really compile?");
}
```

```
dmd -O -checkaction=context -unittest -main myccode.c -run imc.d
imc.d(3): [unittest] Should img.c really compile?
1/1 modules FAILED unittests
```


Re: Why does the importC example not compile?

2023-01-13 Thread Dennis via Digitalmars-d-learn

On Friday, 13 January 2023 at 12:33:28 UTC, kdevel wrote:
What must be added or changed in order to test every example 
which is intended to produce an executable?


Support for separate compilation / ImportC would need to be added 
to dspec_tester:

https://github.com/dlang/dlang.org/blob/master/tools/dspec_tester.d


Re: Why does the importC example not compile?

2023-01-13 Thread kdevel via Digitalmars-d-learn

On Friday, 13 January 2023 at 12:20:23 UTC, Dennis wrote:
I don't think there's a way to test examples of separate 
compilation in the spec currently.


What must be added or changed in order to test every example 
which is intended to produce an executable?


Re: Why does the importC example not compile?

2023-01-13 Thread Dennis via Digitalmars-d-learn

Thanks for reporting this. PR:
https://github.com/dlang/dlang.org/pull/3489

On Friday, 13 January 2023 at 11:10:23 UTC, kdevel wrote:
I would have expected that each and every piece of code in the 
documentation is automatically compiled with any new compiler 
release.


Individual D snippets can be tested when given the right DDoc 
macro, such as `SPEC_RUNNABLE_EXAMPLE_RUN` or 
`SPEC_RUNNABLE_EXAMPLE_FAIL`. (Thanks to Nick Treleaven for 
adding it to many examples that didn't have it before!)


I don't think there's a way to test examples of separate 
compilation in the spec currently.





Re: Why does the importC example not compile?

2023-01-13 Thread novice2 via Digitalmars-d-learn

try to rename function to distinguish from source module


Why does the importC example not compile?

2023-01-13 Thread kdevel via Digitalmars-d-learn

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

`square.c`
```
int square(int i)
{
   return i * i;
}
```

`demo.d`
```
import std.stdio;
import square;
void main()
{
int i = 7;
writefln("The square of %s is %s", i, square(i));
}
```

```
$ dmd --version
DMD64 D Compiler v2.101.1
Copyright (C) 1999-2022 by The D Language Foundation, All Rights 
Reserved written by Walter Bright

$ dmd demo.d square.c
demo.d(6): Error: function expected before `()`, not `module 
square` of type `void`

```

I would have expected that each and every piece of code in the 
documentation is automatically compiled with any new compiler 
release.


Re: Mixin helper help

2023-01-13 Thread bauss via Digitalmars-d-learn

On Thursday, 12 January 2023 at 08:03:34 UTC, John Chapman wrote:

I'm obviously doing something wrong, but don't quite understand.

```d
mixin template helper() {
  mixin("writeln(12);");
}

struct Foo {
  void opDispatch(string name)() {
import std.stdio;
mixin helper!();
//mixin("writeln(12);");
  }
}

void main() {
  Foo.init.opDispatch!"bar"();
}
```

The compiler emits these errors about the mixin 
("writeln(12);"):

unexpected `(` in declarator
basic type expected, not `12`
found `12` when expecting `)`
no identifier for declarator `writeln(_error_)`
semicolon expected following function declaration
declaration expected, not `)`

Why does the commented code work but the mixin not? Thanks for 
any pointers.


Mixin templates cannot have statements directly, so you need two 
changes for your code to work:


1. Change your mixin template to something like this:

```d
mixin template helper() {
// we place the statements in this function instead
void helper() {
mixin("writeln(12);");
}
}
```

2. Change the place where you instantiate to this:

```d
struct Foo {
  void opDispatch(string name)() {
import std.stdio;
mixin helper!();
helper(); // calling the function in the mixin template
  }
}
```