June 16, 2013
Adam D. Ruppe:

> I made a network server/client that needs no library except Phobos. Came in a little under 500 lines but is quite generic:

Normal Rosettacode entries are under 40-100 lines. Many entries are about 10-20 lines long.

There are are few entries (in C or Ada) that reach 500 lines, but I think they miss the point of Rosettacode, where code is meant to illustrate, it's not a place for heavy implementations. That's why I suggested to just call a library...

What do you suggest to do?

Bye,
bearophile
June 16, 2013
On Sunday, 16 June 2013 at 23:06:40 UTC, bearophile wrote:
> Normal Rosettacode entries are under 40-100 lines. Many entries are about 10-20 lines long.

I think that biases it toward giant standard libraries. I've joked before that we could just say:

import rosettacode;
mixin Distributed!();

and win the code golf every time! :P

But this asks for something pretty generic and the Go version for instance uses a rpc package that looks pretty similar to what I did here. The only reason their thing is short is because it is in the stdlib. (I betcha Go's stdlib implementation is longer than 500 lines too!)

> What do you suggest to do?

We could break the file into two parts, and link to one. Just as I feared though, the structs don't work because mixing in their name doesn't get the right import either. This is one disappointing limitation of string mixins that I've hit before too, when doing default arguments in web.d. It works for basic types but not for enums because while I can get the string representation, I can't get the actual type anymore.

It would be great if we could describe a very specific type in a string mixin that the compiler knows, even if the imports aren't necessarily there.


If I remove the struct example, it works with separate modules, so let's try that for now until I can think of a solution to the general problem here.

code:
http://arsdnet.net/dcode/rpc-example.d

library:
https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/rpc.d
June 18, 2013
Adam D. Ruppe:

> and win the code golf every time! :P

Some Rosettacode D entries are a bit compressed, but that site is not for code golfing. It's just preferred to not write long programs, for several reasonable reasons.


> code:
> http://arsdnet.net/dcode/rpc-example.d
>
> library:
> https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff/blob/master/rpc.d

I have reformatted your code a little for the D standard of Rosettacode (72 columns max, etc):
http://codepad.org/lAxAJwoG


With your code I have found a dmd compiler bug, are you able and willing to further reduce this?


import std.conv: to;
import std.traits: ParameterTypeTuple;
mixin template NetworkServer(Interface) {
  void callByNumber(int functionNumber, int sequenceNumber, const(ubyte)[] buffer) {
    string callCode() {
      string code;
      foreach(memIdx, member; __traits(allMembers, Interface)) {
        code ~= "\t\tcase " ~ to!string(memIdx + 1) ~ ":\n";
        alias mem = PassThrough!(__traits(getMember, Interface, member));
        foreach(i, arg; ParameterTypeTuple!mem) {
          auto istr = to!string(i);
          code ~= "\t\t\t" ~ arg.stringof ~ " arg" ~ istr ~ ";\n";
          code ~= "\t\t\tbuffer = deserializeInto(buffer, arg" ~ istr ~ ");\n";
        }
        code ~= "\t\tbreak;\n";
      }
      return code;
    }
    switch(functionNumber) {
      mixin(callCode());
    }
  }
}
template PassThrough(alias a) {
  alias PassThrough = a;
}
void deserializeInto(T)(inout(ubyte)[] buffer, ref T s) {
  s.length = 1;
}
mixin template NetworkClient(Interface) {
  private static void createClass() {}
  mixin(createClass());
}
interface ExampleNetworkFunctions {
  void sayHello(in string);
}
class ExampleServer : ExampleNetworkFunctions {
  override void sayHello(in string) {}
  mixin NetworkServer!ExampleNetworkFunctions;
}
void main() {}



Bye,
bearophile
June 18, 2013
On 2013-06-18, 05:00, bearophile wrote:

> With your code I have found a dmd compiler bug, are you able and willing to further reduce this?

Tried this with 2.063.2, and there are three errors in the code - deserializeInto
should return its buffer, the switch on line 19 needs a default: case, and
deserializeInto tries to modify its non-buffer argument (which in this case is a
const string. None of these seem to be a compiler bug.

-- 
Simen
June 18, 2013
Simen Kjaeraas:

> Tried this with 2.063.2, and there are three errors in the code - deserializeInto
> should return its buffer, the switch on line 19 needs a default: case, and
> deserializeInto tries to modify its non-buffer argument (which in this case is a
> const string. None of these seem to be a compiler bug.

I have introduced the first two errors in the reduction process. The third is the one that triggers a crash of my DMD version. I am keeping my compiler updated, I have compiled it yesterday, and it crashes after giving the error:

test.d(28): Error: cannot modify const expression s

Now I don't know if it's a problem of just my compiler, or if it's a normal compiler bug.

Bye,
bearophile
June 18, 2013
On Tuesday, 18 June 2013 at 09:22:05 UTC, bearophile wrote:
> third is the one that triggers a crash of my DMD version. I am keeping my compiler updated, I have compiled it yesterday, and it crashes after giving the error:
>
> test.d(28): Error: cannot modify const expression s
>
> Now I don't know if it's a problem of just my compiler, or if it's a normal compiler bug.


Hmm, on my compiler it just fails to compile
test11.d(32): Error: cannot modify const expression s
test11.d(26): Error: template instance test11.deserializeInto!(const(immutable(char)[])) error instantiating


which is actually expected because it is referring to this function:
        override void sayHello(in string) {}

and the ParameterTypeTuple there will return a fully const type because of the "in", so assigning to it won't work without a cast.

I can't reproduce the compiler crash you saw though.
June 18, 2013
Adam D. Ruppe:

> I can't reproduce the compiler crash you saw though.

Thank you. Then it's somehow just my compiler...

Bye,
bearophile
June 22, 2013
On Saturday, 16 February 2013 at 11:30:00 UTC, Jos van Uden wrote:
> On 16-2-2013 8:58, qznc wrote:
>> On Saturday, 16 February 2013 at 06:58:01 UTC, qznc wrote:
>>> On Saturday, 16 February 2013 at 02:23:42 UTC, Jos van Uden wrote:
>>>> On 5-2-2013 20:45, Jos van Uden wrote:
>>>>
>>>>> By the way, I think 'Qznc' may want to have a look at 'The dining
>>>>> philosophers':
>>>>>
>>>>> http://rosettacode.org/wiki/Dining_philosophers
>>>
>>> I should find the time to solve it this weekend.
>>
>> Wow, my kid let me do some hacking right now and it was simpler than expected.
>> Posted a solution already.
>
> Wow, that was quick. Thanks!

The current D code for Dining philosophers does not compile with dmd v2.063.2, the error message being

dining.d(34): Error: cannot uniquely infer foreach argument types

The code looks OK to me (but I'm a D newbie) so I wonder if someone could explain the inference issue. Where should an annotation be added to allow this to compile?


     1	import std.stdio, std.algorithm, std.string, std.parallelism,
     2	  core.sync.mutex;
     3	
     4	void eat(in uint i, in string name, Mutex[] forks) {
     5	  writeln(name, " is hungry.");
     6	
     7	  immutable j = (i + 1) % forks.length;
     8	
     9	  // Take forks i and j. The lower one first to prevent deadlock.
    10	  auto fork1 = forks[min(i, j)];
    11	  auto fork2 = forks[max(i, j)];
    12	
    13	  fork1.lock();
    14	  scope(exit) fork1.unlock();
    15	
    16	  fork2.lock();
    17	  scope(exit) fork2.unlock();
    18	
    19	  writeln(name, " is eating.");
    20	  writeln(name, " is full.");
    21	}
    22	
    23	void think(in string name) {
    24	  writeln(name, " is thinking.");
    25	}
    26	
    27	void main() {
    28	  const philosophers = "Aristotle Kant Spinoza Marx Russell".split();
    29	  Mutex[philosophers.length] forks;
    30	  foreach (ref fork; forks)
    31	    fork = new Mutex();
    32	
    33	  defaultPoolThreads = forks.length;
    34	  foreach (uint i, philo; taskPool.parallel(philosophers)) {
    35	    foreach (_; 0 .. 100) {
    36	      eat(i, philo, forks);
    37	      think(philo);
    38	    }
    39	  }
    40	}

BTW, I like the coding style being used in the rosetta examples and TDPL much better than the library style.

-- Brian



June 22, 2013
Brian Rogoff:

> The current D code for Dining philosophers does not compile with dmd v2.063.2, the error message being
>
> dining.d(34): Error: cannot uniquely infer foreach argument types

I try to keep the D entries on Rosettacode updated, but every dmd release breaks tons of code, and Rosettacode has almost one thousand D programs (many tasks have two or more D entries, to show different solutions or different coding style, or to show code with different tradeoffs, etc), so you find some broken programs.

I don't know what's changed in taskPool.parallel, I will investigate later. Or you can investigate yourself if you want.


> BTW, I like the coding style being used in the rosetta examples and TDPL much better than the library style.

I try to keep the D code on Rosettacode with a quite uniform style. It follows the dstyle, the main difference is the opening brace that's in Egyptian style, but such brace style is required only in Phobos, while the dstyle does not require the Phobos style for all D code, it's in "Additional Requirements for Phobos":
http://dlang.org/dstyle.html

Later,
bearophile
June 22, 2013
On 06/22/2013 11:53 AM, Brian Rogoff wrote:

> The current D code for Dining philosophers does not compile with dmd
> v2.063.2, the error message being
>
> dining.d(34): Error: cannot uniquely infer foreach argument types

The code compiles under 32-bit (e.g. with the -m32 compiler switch) where size_t is an alias of uint.

>       4    void eat(in uint i, in string name, Mutex[] forks) {

1) Replace that uint with size_t:

void eat(in size_t i, in string name, Mutex[] forks) {

>      34      foreach (uint i, philo; taskPool.parallel(philosophers)) {

2) Remove that uint:

  foreach (i, philo; taskPool.parallel(philosophers)) {

Ali