Re: Is there a way to enforce UFCS?

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

On Friday, 6 January 2023 at 15:31:09 UTC, Salih Dincer wrote:
If you don't want to get the above output you should use the 
previous example. But don't forget to connect alias and opCall. 
For example, you can use @property in version 2.0.83 without 
all the fanfare.




I forgot one thing: if you implement getter/setter like below use 
inout as well.


Actually, this must be a bit of a bug and neither I nor anyone 
else reported it!  Ok they will say don't use @property.  But 
this time the screen output will be like typeid.  If you don't 
want that to happen, you have to use inout in getter functions.


```d
struct Funy(T)
{
  this(T x) {
    value = x;
  }

  T value;
  alias opCall this;

  @property:
  T opCall(T n)
  {
    return value = n;
  }

  T opCall() inout
  {
return value;
  }
}
```

SDB@79




Re: Is there a way to enforce UFCS?

2023-01-06 Thread Salih Dincer via Digitalmars-d-learn
On Thursday, 5 January 2023 at 23:05:17 UTC, thebluepandabear 
wrote:

them or remove them.


I agree, forbidding function call syntax would be a great 
usecase for `@property`.


It will probably never get implemented though.


In older versions, it worked when printing values ​​with writeln. 
But due to an error in formattedWrite, the program breaks. So I 
stopped using @property. For example, you can't see the 
difference in:


```d
struct Funy(T)
{
  import std.conv : to;
  this(X)(X x) {
    value = x.to!T;
  }
  T value;
  alias value this; // [a] getter
  //@property
  T opAssign(T x) { // [b] setter
return value = x;
  }
  alias opCall = opAssign; /* hack: `opAssign` methods
  are not used for initialization,
  but for subsequent assignments
  [c] incrementor: */
  //@property
  T opOpAssign(string op: "+", X)(X x) {
return value = value + x.to!T;
  }
}

import std.stdio;
void main()
{
  auto funy = Funy!uint(20);
  funy.value.writeln; // 20
  funy = 10;
  funy.value.writeln; // 1

  class Fun
  {
Funy!int n;
this(int i)
{
  n = i; // or:
  n(i + 1);
}
  }

  auto fun = new Fun(-2);
  fun.n.writeln; // -1
  fun.n += 19.999;
  fun.n.writeln; // 18
}
```

Let's continue the fun...

```d
struct Funy(T)
{
  this(T x) { value = x; }
  T value;
  alias opCall this;

  //@property:
  T opCall(T n) { return value = n; }
  T opCall() { return value; }
}

import std.stdio;
void main()
{
  auto funy = Funy!uint(20);
  funy.value.writeln; // 20
  funy = 10;
  funy.value.writeln; // 1

  class Fun
  {
Funy!int n;
this(int i) {
  n = i; // or:
  n(i + 1);
}
  }

  auto fun = new Fun(-2);
  fun.n.writeln; // -1
  fun.n = 20;
  fun.n.writeln; // 0
} /* PRINTS:
20
10
Funy!int(-1)
Funy!int(20)
```

If you don't want to get the above output you should use the 
previous example. But don't forget to connect alias and opCall. 
For example, you can use @property in version 2.0.83 without all 
the fanfare.


SDB@79


Re: Is there a way to enforce UFCS?

2023-01-05 Thread thebluepandabear via Digitalmars-d-learn

them or remove them.


I agree, forbidding function call syntax would be a great usecase 
for `@property`.


It will probably never get implemented though.


Re: Is there a way to enforce UFCS?

2023-01-05 Thread H. S. Teoh via Digitalmars-d-learn
On Thu, Jan 05, 2023 at 02:32:17PM +, Dom DiSc via Digitalmars-d-learn 
wrote:
[...]
> I think this is really another usecase for @property: we should forbid the
> function call syntax for them (so one needs to use them like a variable).
[...]
> Properties are not functions. If you want a function, use a function. If
> @properties would be the same as functions, they are superfluous garbage.
> Either make something useful out of them or remove them.

We have been talking about deprecating and removing @property for years
now.  Somebody just has to bite the bullet and push it through the
deprecation process...

... OR come up with a DIP that implements @property in a sane, fully
worked out way, not the half-hearted, incomplete, leaky implementation
that it is today.

//

In my own code, I've stopped bothering with @property for the most part.
Parentheses are optional for argumentless functions in general anyway,
so there's really no need to write @property on anything. This works:

struct S {
private int _x;
int x() { return _x; }
}

S s;
int y = s.x;

The only significant thing @property does right now is to add confusion
when the unary & operator is used or when the property function returns
a delegate.  Not worth the trouble, I say.  Just don't use @property at
all, plain old member functions work just fine.


T

-- 
Some ideas are so stupid that only intellectuals could believe them. -- George 
Orwell


Re: Is there a way to enforce UFCS?

2023-01-05 Thread Dom DiSc via Digitalmars-d-learn

On Wednesday, 4 January 2023 at 14:21:46 UTC, bauss wrote:

```d
class Foo {
  int bar;

  void setBar(Foo foo, int value) {
foo.bar = value;
  }
}

void main() {
  foo.setBar(100); // Not UFCS - just method call to the class
  foo.setBar = 100; // Not UFCS - simply a setter function call 
(equal to the above)

  setBar(foo, 100); // Error
}
```


I think this is really another usecase for @property: we should 
forbid the function call syntax for them (so one needs to use 
them like a variable).
This is useful to enable library authors to enforce this, so that 
if a property is replaced by a variable (e.g. during 
refactoring), it's not a braking change for the users of the 
library.
Else it could be that setters or getters are directly called, 
which would not compile anymore with a variable (that doesn't 
have getters or setters).


@properties are intended to be used like variables - the only 
differences (and the reason why they exist) is the read or write 
protection they provide, and that they may be calculated on the 
fly (not stored in memory at all). That they are realized with a 
construct that looks similar to (a pair of) functions should be 
completely transparent for the user of a library.


Properties are not functions. If you want a function, use a 
function. If @properties would be the same as functions, they are 
superfluous garbage. Either make something useful out of them or 
remove them.




Re: Is there a way to enforce UFCS?

2023-01-04 Thread thebluepandabear via Digitalmars-d-learn

On Wednesday, 4 January 2023 at 14:21:46 UTC, bauss wrote:
On Wednesday, 4 January 2023 at 03:42:28 UTC, thebluepandabear 
wrote:

...

My question is: is there a way to enforce UFCS-syntax?


None of your code actually uses UFCS.

This is UFCS:

```
class Foo {
  int bar;
}

void setBar(Foo foo, int value) {
  foo.bar = value;
}

void main() {
  foo.setBar(100); // UFCS
  setBar(foo, 100); // Non-UFCS (Above expands to this)
}
```

This is not UFCS but just class method calling:

```
class Foo {
  int bar;

  void setBar(Foo foo, int value) {
foo.bar = value;
  }
}

void main() {
  foo.setBar(100); // Not UFCS - just method call to the class
  foo.setBar = 100; // Not UFCS - simply a setter function call 
(equal to the above)

  setBar(foo, 100); // Error
}
```

Also note that @property doesn't really do anything now and 
there's even talk about deprecating it. Althought I personally 
still use it, then it doesn't have much of a function and none 
of your code is affected if you remove it.


Yeah I got mixed up.

I think a good use of `@property` is for code clarity, it makes 
it clear which parts of your code should be treated as properties.


Re: Is there a way to enforce UFCS?

2023-01-04 Thread bauss via Digitalmars-d-learn
On Wednesday, 4 January 2023 at 03:42:28 UTC, thebluepandabear 
wrote:

...

My question is: is there a way to enforce UFCS-syntax?


None of your code actually uses UFCS.

This is UFCS:

```
class Foo {
  int bar;
}

void setBar(Foo foo, int value) {
  foo.bar = value;
}

void main() {
  foo.setBar(100); // UFCS
  setBar(foo, 100); // Non-UFCS (Above expands to this)
}
```

This is not UFCS but just class method calling:

```
class Foo {
  int bar;

  void setBar(Foo foo, int value) {
foo.bar = value;
  }
}

void main() {
  foo.setBar(100); // Not UFCS - just method call to the class
  foo.setBar = 100; // Not UFCS - simply a setter function call 
(equal to the above)

  setBar(foo, 100); // Error
}
```

Also note that @property doesn't really do anything now and 
there's even talk about deprecating it. Althought I personally 
still use it, then it doesn't have much of a function and none of 
your code is affected if you remove it.


Re: Is there a way to enforce UFCS?

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

On 1/3/23 19:42, thebluepandabear wrote:

>  @property {

As your post proves, that feature is at most half-baked and is 
discouraged. Today, there is just one known obscure effect of using it.


>  void name(string name) {
>  _name = name;
>  }

>  d.name = "Poodle";

> In the code we can see that we have utilized UFCS (universal function
> call syntax)

UFCS is for calling free-standing functions as if they are member 
functions. Since your example already uses member functions, this 
feature is not UFCS. And I don't think it has a name.


It is always possible to pass a single-argument with the assignment syntax:

void foo(int i) {}

void main() {
foo = 42;
}

Pretty wild! :) But that's what makes your assignment above work. (Not 
UFCS.)


> not enforced [...] we can
> do the following in our code:

>  d.name("poodle");

I don't see a problem with that. :)

> I am disappointed that `@property` does not

Many people are disappointed that @property is pretty much useless.

> is there a way to enforce

D gives us the tools to do that but it's not trivial. The function can 
return an object that represents a variable (member variable or not). 
And an assignment to that representative object can set the actual variable.


However, I tried to achieve it with an intermediary object but failed 
because the same ="Poodle" syntax broke it and demanded that we type the 
empty parenthesis. So, I think what you want does not exist.


// I have a feeling something similar exists in Phobos
// but I could not find it.
//
// This is a reference to any variable.
struct MyRef(T) {
T * ptr;

void opAssign(T value) {
*ptr = value;
}

void toString(scope void delegate(in char[]) sink) const {
sink(*ptr);
}
}

// This is a convenience function template so that
// the users don't have to say e.g. MyRef!string
// themselves. (See name() below.)
auto myRef(T)(ref T var) {
return MyRef!T();
}

class Dog {
@property name() {
return myRef(_name);
}

private {
string _name;
}
}

void main() {
Dog d = new Dog();


// Great: The following won't work.
// d.name("poodle");


// However, now there is the empty parenthesis. :(
d.name() = "Poodle";

import std.stdio;
writeln(d.name);
}

Ali



Is there a way to enforce UFCS?

2023-01-03 Thread thebluepandabear via Digitalmars-d-learn

Say you have the following class which represents a dog :

```D
class Dog {
@property {
string name();

void name(string name) {
_name = name;
}
}

private {
string _name;
}
}
```

And you have the following code with constructs a `Dog` object:

```D
void main() {
Dog d = new Dog();

d.name = "Poodle";
writeln(d.name);
}
```

In the code we can see that we have utilized UFCS (universal 
function call syntax) to set the properties for the object. This 
feature is great. We have also used D's `@property` annotation 
which gives us some other advantages that you can see in the 
documentation.


The issue I have is that UFCS is not enforced, which I thought 
would be a rather good use for the `@property` annotation. This 
means that we can do the following in our code:


```D
void main() {
Dog d = new Dog();

d.name("poodle");
writeln(d.name());
}
```

I prefer the UFCS version over the non-UFCS version since it is 
more clear that it is a property and it matches closely with the 
official D style guide.


I am disappointed that `@property` does not enforce UFCS, as I 
believe that it would add to its usefulness. Sometimes throughout 
my codebase I get confused and write properties in non-UFCS 
syntax, which bugs me a bit.


My question is: is there a way to enforce UFCS-syntax?


Re: UFCS limit

2022-06-17 Thread Antonio via Digitalmars-d-learn

On Friday, 17 June 2022 at 12:26:05 UTC, Antonio wrote:

UFCS vs Functional curring... nice battle :-)


**UFCS & CFTE** vs **Functional currying**... nice battle :-)


Re: UFCS limit

2022-06-17 Thread Antonio via Digitalmars-d-learn

On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote:

On Thursday, 16 June 2022 at 23:59:06 UTC, Antonio wrote:
Is it there any way to apply UFCS on the returned method in 
the same expression?


Nope. The way UFCS works is that allows you to call free 
functions using member-function syntax, and member-function 
syntax is always `object.memberName`, so UFCS only works for 
functions that have a name, not anonymous functions.


Lets tray with a name :-)

```d
auto doSomething(string text)
{
  return (string text2)
  {
import std.stdio;
writeln(text,",",text2);
  };
}

void main()
{
  auto doHello = doSomething("Hello");
  doHello("X");
  "X".doHello();
}
```

Error:  onlineapp.d(16): Error: no property `doHello` for type 
`string`


It's true... the favomous "Rationale: Local function symbols are 
not considered by UFCS to avoid unexpected name conflicts."  (I 
consider it absurd... but I'n no-one)


Well lets try another possibility taking in account the power of 
CTFE


```d
auto doSomething(string text)
{
  return (string text2)
  {
import std.stdio;
writeln(text,",",text2);
  };
}

auto doHello = doSomething("Hello");

void main()
{
  doHello("X");
  "X".doHello();
}

```

Error: onlineapp.d(3): Error: closures are not yet supported in 
CTFE


:-/

UFCS vs Functional curring... nice battle :-)







Re: UFCS limit

2022-06-17 Thread bauss via Digitalmars-d-learn

On Friday, 17 June 2022 at 05:17:20 UTC, Tejas wrote:

On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote:



Nope. The way UFCS works is that allows you to call free 
functions using member-function syntax, and member-function 
syntax is always `object.memberName`, so UFCS only works for 
functions that have a name, not anonymous functions.


Would it be worthwhile to extend the scope of UFCS to 
accomodate this use case as well though??


I think it would lead to a lot of confusing and ambiguity.


Re: UFCS limit

2022-06-16 Thread Paul Backus via Digitalmars-d-learn

On Friday, 17 June 2022 at 05:17:20 UTC, Tejas wrote:

On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote:



Nope. The way UFCS works is that allows you to call free 
functions using member-function syntax, and member-function 
syntax is always `object.memberName`, so UFCS only works for 
functions that have a name, not anonymous functions.


Would it be worthwhile to extend the scope of UFCS to 
accomodate this use case as well though??


Probably not.


Re: UFCS limit

2022-06-16 Thread Tejas via Digitalmars-d-learn

On Friday, 17 June 2022 at 01:04:28 UTC, Paul Backus wrote:



Nope. The way UFCS works is that allows you to call free 
functions using member-function syntax, and member-function 
syntax is always `object.memberName`, so UFCS only works for 
functions that have a name, not anonymous functions.


Would it be worthwhile to extend the scope of UFCS to accomodate 
this use case as well though??


Re: UFCS limit

2022-06-16 Thread Paul Backus via Digitalmars-d-learn

On Thursday, 16 June 2022 at 23:59:06 UTC, Antonio wrote:
Is it there any way to apply UFCS on the returned method in the 
same expression?


Nope. The way UFCS works is that allows you to call free 
functions using member-function syntax, and member-function 
syntax is always `object.memberName`, so UFCS only works for 
functions that have a name, not anonymous functions.


UFCS limit

2022-06-16 Thread Antonio via Digitalmars-d-learn

```d
auto doSomething(string text)
{
  return (string text2)
  {
import std.stdio;
writeln(text,",",text2);
  };
}

void main()
{
  doSomething("Hello")("X");
  "X".doSomething("Hello")();
}
```
Compiler error:

```
...
onlineapp.d(13):expected 1 argument(s), not 2
```

I tried with some syntax change:

```d
void main()
{
  doSomething("Hello")("X");
  (doSomething("Hello"))("X"); // it works
  "X".(doSomething("Hello"))(); // fails!!!
}
```

```onlineapp.d(14): Error: identifier or `new` expected following 
`.`, not `(


Is it there any way to apply UFCS on the returned method in the 
same expression?





Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread james.p.leblanc via Digitalmars-d-learn

On Wednesday, 1 September 2021 at 22:11:29 UTC, user1234 wrote:

On Wednesday, 1 September 2021 at 22:01:12 UTC, user1234 wrote:


```

ProcessPipes gnuplot () {
__gshared ProcessPipes pipe;
return pipe.pid ? pipe : (pipe = 
pipeProcess("/usr/local/bin/gnuplot"));

}

```

user1234,

Thanks!  This is perfect, getting rid of the class altogether.

Yes, as pointed out in your response, that class was rather 
useless.
(For some unknown reason, I had been stuck on creating a 
singleton to
avoid multiple gnuplot processes -- very unnecessary as I now 
see.).


The ternary operator with the pipe id is much cleaner and leaner.

Thanks again, for your time, energy and insight.

Best Regards,
James



Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread user1234 via Digitalmars-d-learn

On Wednesday, 1 September 2021 at 22:01:12 UTC, user1234 wrote:
On Wednesday, 1 September 2021 at 20:59:15 UTC, james.p.leblanc 
wrote:

[...]
The question is if there is a way to enable UFCS without such 
wrapper


sorry my attention got stuck on the singleton.

So my suggestion is rather to only enable the ufcs style. This 
highlights the fact that the class is useless, you can use a 
simple getter that initializes a hidden global:


```d
module gnuplot_mod;

import std.stdio;
import std.process;
import std.algorithm : each;
import std.range : enumerate;

ProcessPipes gnuplot () {
__gshared ProcessPipes pipe;
return pipe.pid ? pipe : (pipe = 
pipeProcess("/usr/local/bin/gnuplot"));

}

static void cmd(string txt) {
with (gnuplot()) {
stdin.writeln(txt);
stdin.flush();
}
}

static void plot(double[] x, string txt = "ls 21 lw 2"){
with (gnuplot()) {
stdin.writeln("plot '-' u 1:2 with lines ", txt);
enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, 
v))();


sorry there was a format mistake not detected at compile time.

```diff
- enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, v))();
+ enumerate(x).each!(a => stdin.writefln!"%s %f"(a.index, 
a.value))();

```


stdin.writeln("e");
stdin.flush();
}
}

void main() {
  double[] x = [1.1, 0.2, 3.1, 2.2, 3.1, 0.6];
  double[] y = [-1.1, 0.2, -3.1, 2.2, 3.1, -0.6];
  y.plot("ls 41 lw 8");
  cmd("pause 2");
}

```





Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread user1234 via Digitalmars-d-learn
On Wednesday, 1 September 2021 at 20:59:15 UTC, james.p.leblanc 
wrote:

[...]
The question is if there is a way to enable UFCS without such 
wrapper


sorry my attention got stuck on the singleton.

So my suggestion is rather to only enable the ufcs style. This 
highlights the fact that the class is useless, you can use a 
simple getter that initializes a hidden global:


```d
module gnuplot_mod;

import std.stdio;
import std.process;
import std.algorithm : each;
import std.range : enumerate;

ProcessPipes gnuplot () {
__gshared ProcessPipes pipe;
return pipe.pid ? pipe : (pipe = 
pipeProcess("/usr/local/bin/gnuplot"));

}

static void cmd(string txt) {
with (gnuplot()) {
stdin.writeln(txt);
stdin.flush();
}
}

static void plot(double[] x, string txt = "ls 21 lw 2"){
with (gnuplot()) {
stdin.writeln("plot '-' u 1:2 with lines ", txt);
enumerate(x).each!((i,v) => stdin.writefln!"%s %f"(i, 
v))();

stdin.writeln("e");
stdin.flush();
}
}

void main() {
  double[] x = [1.1, 0.2, 3.1, 2.2, 3.1, 0.6];
  double[] y = [-1.1, 0.2, -3.1, 2.2, 3.1, -0.6];
  y.plot("ls 41 lw 8");
  cmd("pause 2");
}

```


Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread james.p.leblanc via Digitalmars-d-learn

On Wednesday, 1 September 2021 at 19:54:14 UTC, user1234 wrote:
On Wednesday, 1 September 2021 at 16:02:47 UTC, james.p.leblanc 
wrote:

Dear D-ers,

For simple plotting using a gnuplot process, I have created a 
singleton object (a stripped

down minimal working example is below.)

[...]

**However, those wrapper functions in the gnuplot_mod module 
looks a bit silly.**


[...]

Any suggestions on a better way are greatly appreciated.

Best Regards,
James


hello, I'd suggest this:

```d
shared static this() {
get(); // cache instance before main(){}
   // to get rid of the synchronized() stmt
}

static Gnuplot get() {
__gshared Gnuplot instance;
return instance ? instance : (instance = new Gnuplot());
}
```


user1234,

Thanks for your reply, I will need to look at it deeper.

I also realize that my post was not so clear, to clarify:

I needed to implement two wrapper functions ... that  are **in** 
the

module, but **outside** of the object, copied below:

**void cmd(string txt){**
**Gnuplot gp;**
**gp = gp.get();**
**gp.cmd(txt);**
**}**

**void plot(double[] x, string txt){**
**Gnuplot gp;**
**gp = gp.get();**
**gp.plot(x, txt);**
**}**

These enable use of the UFCS in main() (without prefixing with 
instantiated object's name
**gp** ).  The gp prefix only needs to be in these wrappers that 
exist in the module, not in the main().


The question is if there is a way to enable UFCS without such 
wrapper

(see example in main() in original posting).

Thanks again, and now I need to play a bit with your suggestion 
to learn

from it.

Best Regards,
James



Re: Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread user1234 via Digitalmars-d-learn
On Wednesday, 1 September 2021 at 16:02:47 UTC, james.p.leblanc 
wrote:

Dear D-ers,

For simple plotting using a gnuplot process, I have created a 
singleton object (a stripped

down minimal working example is below.)

[...]

**However, those wrapper functions in the gnuplot_mod module 
looks a bit silly.**


[...]

Any suggestions on a better way are greatly appreciated.

Best Regards,
James


hello, I'd suggest this:

```d
shared static this() {
get(); // cache instance before main(){}
   // to get rid of the synchronized() stmt
}

static Gnuplot get() {
__gshared Gnuplot instance;
return instance ? instance : (instance = new Gnuplot());
}
```


Singleton Object, calling member functions using UFCS (an "ugly?" example) ... better way?

2021-09-01 Thread james.p.leblanc via Digitalmars-d-learn

Dear D-ers,

For simple plotting using a gnuplot process, I have created a 
singleton object (a stripped

down minimal working example is below.)

In the example, there are two plots calls:

   1) First, call is made using the object member function 
"gp.plot(x, etc.)"
   2) The second uses a wrapper to allow use of the UFCS (uniform 
function call syntax)


The ability to use the UFCS has the usual UFCS advantages, 
additionally the coder
doesn't need to care about the actual name of the object's 
instantiation.


**However, those wrapper functions in the gnuplot_mod module 
looks a bit silly.**


**Is there a more elegant way to do this?**

First, the module:

--

   module gnuplot_mod;

   import std.stdio;
   import std.process;
   import std.conv : to;

   class Gnuplot {

  // modification of wiki.dlang.org/Low-Lock_Singleton_Pattern
  ProcessPipes pipe;
  private this() {
 this.pipe = pipeProcess("/usr/local/bin/gnuplot") ;
  }

  private static bool instantiated_;
  private __gshared Gnuplot instance_;

  static Gnuplot get() {
 if (!instantiated_) {
synchronized(Gnuplot.classinfo) {
   if (!instance_) {
  instance_ = new Gnuplot();
   }
   instantiated_ = true;
}
 }
 return instance_;
  }

  void cmd(string txt) {
 this.pipe.stdin.writeln(txt);
 this.pipe.stdin.flush();
 return;
  }

  void plot(double[] x, string txt = "ls 21 lw 2"){
 this.pipe.stdin.writeln("plot '-' u 1:2 with lines " ~ 
txt);
 foreach( ind, val ; x) this.pipe.stdin.writeln( 
to!string(ind) ~ " " ~ to!string(val) );

 this.pipe.stdin.writeln("e");
 this.pipe.stdin.flush();
  }
   }

   void cmd(string txt){
  Gnuplot gp;
  gp = gp.get();
  gp.cmd(txt);
   }

   void plot(double[] x, string txt){
  Gnuplot gp;
  gp = gp.get();
  gp.plot(x, txt);
   }

---
Now, the main ...

---

   import gnuplot_mod;
   import std.stdio;

   void main(){

  Gnuplot gp;
  gp = gp.get();

  double[] x = [1.1, 0.2, 3.1, 2.2, 3.1, 0.6];
  double[] y = [-1.1, 0.2, -3.1, 2.2, 3.1, -0.6];

  writeln("\nusing singleton's member functions: plot and 
cmd");


  gp.plot(x, "ls 31 lw 3");
      gp.cmd("pause 2");

  writeln("\nusing uniform function call syntax (UFCS): plot 
and cmd");


  y.plot("ls 41 lw 8");
  cmd("pause 2");
   }


Any suggestions on a better way are greatly appreciated.

Best Regards,
James



Re: UFCS doubt

2021-07-08 Thread Dennis via Digitalmars-d-learn

On Thursday, 8 July 2021 at 23:31:57 UTC, Antonio wrote:
"It works as described in the manual, not as expected" (from 
MySQL haters club :-p) .


Yeah, 50/285 people answering the question "What language 
features do you miss?" chose "UFCS for local symbols" in the 
[State of D survey 
(2018)](https://rawgit.com/wilzbach/state-of-d/master/report.html), but no one has championed a language change for it yet.


Re: UFCS doubt

2021-07-08 Thread Antonio via Digitalmars-d-learn

On Thursday, 8 July 2021 at 22:31:49 UTC, Dennis wrote:

On Thursday, 8 July 2021 at 22:24:26 UTC, Antonio wrote:
I supossed  that ```mfp(c,20)``` and ```c.mfp(20)``` should be 
equivalent because UFCS in second example, but it is not... 
why?


UFCS does not work for nested functions.

Functions declared in a local scope are not found when 
searching for a matching UFCS function.

...
Rationale: Local function symbols are not considered by UFCS 
to avoid unexpected name conflicts. See below problematic 
examples.


https://dlang.org/spec/function.html#pseudo-member


Thanks.

I read the example and the assumption of "name conflict" does not 
seem to be justified (from my point of view)


i.e. Without dot notation, this example must fail
```
int front(int[] arr) { return arr[0]; }
void main()
{
int[] a =[1,2,3];
auto front = 1;   // front is now a variable
auto y = front(a);   // Error, front is not a function
}
```
Changing to y = a.front() should not change the behavior (it is 
only a notation change )... but it does!!!

```
int front(int[] arr) { return arr[0]; }
void main()
{
int[] a =[1,2,3];
auto front = 1;   // front is now a variable
auto y = a.front() // NO ERROR!!!
}
```

"It works as described in the manual, not as expected" (from 
MySQL haters club :-p) .




Re: UFCS doubt

2021-07-08 Thread jfondren via Digitalmars-d-learn

On Thursday, 8 July 2021 at 22:24:26 UTC, Antonio wrote:

onlineapp.d(9): Error: no property `mfp` for type `onlineapp.C`

I supossed  that ```mfp(c,20)``` and ```c.mfp(20)``` should be 
equivalent because UFCS in second example, but it is not... why?


https://dlang.org/spec/function.html#pseudo-member

6. Functions declared in a local scope are not found when 
searching for a matching UFCS function.


Re: UFCS doubt

2021-07-08 Thread Dennis via Digitalmars-d-learn

On Thursday, 8 July 2021 at 22:24:26 UTC, Antonio wrote:
I supossed  that ```mfp(c,20)``` and ```c.mfp(20)``` should be 
equivalent because UFCS in second example, but it is not... why?


UFCS does not work for nested functions.

Functions declared in a local scope are not found when 
searching for a matching UFCS function.

...
Rationale: Local function symbols are not considered by UFCS to 
avoid unexpected name conflicts. See below problematic examples.


https://dlang.org/spec/function.html#pseudo-member




Re: UFCS doubt

2021-07-08 Thread Adam Ruppe via Digitalmars-d-learn

On Thursday, 8 July 2021 at 22:24:26 UTC, Antonio wrote:
I supossed  that ```mfp(c,20)``` and ```c.mfp(20)``` should be 
equivalent because UFCS in second example, but it is not... why?


UFCS only works with functions defined at top level, not nested 
inside other functions. That's just how it is defined i don't 
really know why.


UFCS doubt

2021-07-08 Thread Antonio via Digitalmars-d-learn
In this example (extracted from 
https://digitalmars.com/articles/b68.html), this works:

```
class C {
  int a;
  int foo(int i) { return i + a; }
}

auto mfp = (C self, int i)=>self.foo(i);

void main(){
  auto c = new C;
  assert( c.mfp(20)==20);
}
```

but this fails

```
class C {
  int a;
  int foo(int i) { return i + a; }
}

void main(){
  auto mfp = (C self, int i)=>self.foo(i);
  auto c = new C;
  assert( c.mfp(20)==20);
}
```

onlineapp.d(9): Error: no property `mfp` for type `onlineapp.C`

I supossed  that ```mfp(c,20)``` and ```c.mfp(20)``` should be 
equivalent because UFCS in second example, but it is not... why?





Re: How can I use UFCS for a loop

2021-01-25 Thread Jesse Phillips via Digitalmars-d-learn

On Tuesday, 26 January 2021 at 02:19:10 UTC, Tim wrote:

On Tuesday, 26 January 2021 at 01:38:45 UTC, Q. Schroll wrote:

On Tuesday, 26 January 2021 at 00:47:09 UTC, Tim wrote:

Hi all,

How can I change the following to a more D-like approach by 
using UFCS?



double[3] result;


Unless you have a good reason, use a slice and not a static 
array:


double[] result;

The result of std.array.array will be a slice anyway.


Why would I need to use a slice instead of a static array? I'm 
using a static array in this instance because I have and 
underlying 3d vector with double[3] as its base type


In that case, maybe this untested code

double[3] result;

res.readJson[].map!(to!double).copy(result[]);


Re: How can I use UFCS for a loop

2021-01-25 Thread Tim via Digitalmars-d-learn

On Tuesday, 26 January 2021 at 01:38:45 UTC, Q. Schroll wrote:

On Tuesday, 26 January 2021 at 00:47:09 UTC, Tim wrote:

Hi all,

How can I change the following to a more D-like approach by 
using UFCS?



double[3] result;


Unless you have a good reason, use a slice and not a static 
array:


double[] result;

The result of std.array.array will be a slice anyway.


Why would I need to use a slice instead of a static array? I'm 
using a static array in this instance because I have and 
underlying 3d vector with double[3] as its base type


Re: How can I use UFCS for a loop

2021-01-25 Thread Q. Schroll via Digitalmars-d-learn

On Tuesday, 26 January 2021 at 00:47:09 UTC, Tim wrote:

Hi all,

How can I change the following to a more D-like approach by 
using UFCS?



double[3] result;


Unless you have a good reason, use a slice and not a static array:

double[] result;

The result of std.array.array will be a slice anyway.


Re: How can I use UFCS for a loop

2021-01-25 Thread Q. Schroll via Digitalmars-d-learn

On Tuesday, 26 January 2021 at 00:47:09 UTC, Tim wrote:

Hi all,

How can I change the following to a more D-like approach by 
using UFCS?



double[3] result;
Json json = res.readJson;
for(int i = 0; i < json.length; i++){
result[i] = json[i].to!double;
}


I'd prefer to do something like:


result = res.readJson[].map!(to!double);


Use std.array.array (alias: std.range.array) to make the range 
returned my map!(to!double) into an array.
Note that the result of map isn't actually evaluated until it is 
iterated. std.array.array will iterate and collect. 
https://dlang.org/phobos/std_array.html#array


result = res.readJson[].map!(to!double).array;

should work perfectly.




How can I use UFCS for a loop

2021-01-25 Thread Tim via Digitalmars-d-learn

Hi all,

How can I change the following to a more D-like approach by using 
UFCS?



double[3] result;
Json json = res.readJson;
for(int i = 0; i < json.length; i++){
result[i] = json[i].to!double;
}


I'd prefer to do something like:


result = res.readJson[].map!(to!double);


Re: UFCS functions with both pointers and refs

2020-12-18 Thread Marcone via Digitalmars-d-learn
Two differents types; Foo type and pointer type. Need function 
overload foe each or just use ref and avoid pointer.





Re: UFCS functions with both pointers and refs

2020-12-17 Thread Q. Schroll via Digitalmars-d-learn

On Tuesday, 15 December 2020 at 20:38:04 UTC, Dave P. wrote:
The use case would be to define extension methods on a struct 
outside of where the struct is defined. The extension method 
mutates the state of the struct, so I want to ensure I am 
modifying the original struct and not a copy. If it’s a method 
and I call it on a pointer to the struct, the pointer will get 
auto-dereferenced and everything is great. So my question is 
that if I want an extension method as a free function, do I 
have to write both the version whose first argument is a 
pointer to the struct and the version whose first argument is a 
ref, or is there some keyword or other technique so that the 
pointer gets auto-dereferenced the same way as if it were a 
method. It sounds like the answer is no and I have to write a 
version that just dereferences the pointer and calls the ref 
version.


Now it's coming together.

The easiest way to do this is using an overload taking a `ref` 
(non-pointer) value and another taking a pointer (by copy, I 
guess).


R f(ref T value, Ts args) { /* doing the actual work */ }
R f(T* ptr, Ts args) { f(*p, args); } // manually dereference

You cannot get around doing the actual `f`, and the addition 
isn't that big. I think that's the best solution unless you have 
to deal with non-copyable types among Ts. Then you need to 
forward those properly.
I couldn't really do better using one template instead of this 
simple overload. (Certainly a template can be made, but it is 
clearly not the better solution.)


Re: UFCS functions with both pointers and refs

2020-12-15 Thread Dave P. via Digitalmars-d-learn

On Wednesday, 16 December 2020 at 03:50:07 UTC, Mike Parker wrote:

On Sunday, 13 December 2020 at 19:02:34 UTC, Dave P. wrote:

On Sunday, 13 December 2020 at 18:44:20 UTC, Mike Parker wrote:

On Sunday, 13 December 2020 at 18:31:54 UTC, Dave P. wrote:
[...]


Based on you requirement to use pointers, I assume you're doing 
this for a type you get from a C library. I did the same thing 
for the SDL_Rect type when working with SDL. All I did was 
implement a pointer version of my "extension" functions. When I 
had an instance and not a pointer, I took its address when I 
called the function. If that's inconvenient (lots of generic 
code, perhaps), you can always have the pointer version forward 
to the ref version, but it seems to me like just having the one 
version is the way to go most of the time.


Yeah, in this case the C library is the rest of my program :). I 
am porting
an application I had written in C to D in betterC mode piece by 
piece and there’s
a good number of functions where it’d be convenient to call them 
via UFCs.


Thanks for answering my questions!


Re: UFCS functions with both pointers and refs

2020-12-15 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 13 December 2020 at 19:02:34 UTC, Dave P. wrote:

On Sunday, 13 December 2020 at 18:44:20 UTC, Mike Parker wrote:

On Sunday, 13 December 2020 at 18:31:54 UTC, Dave P. wrote:
Do I have to write both and have one forward to the other for 
more

complicated functions?


For free functions, yes.


Is there any way to write the function as a template that is 
generic over a parameter being a pointer or a reference, but 
does not allow passing a copy?


Even with a templated function, you'd still need to declare the 
first parameter to the function either as a pointer or as a `ref` 
parameter. I'm unaware of any way to get around that. Free 
functions and member functions are just different beasts


Based on you requirement to use pointers, I assume you're doing 
this for a type you get from a C library. I did the same thing 
for the SDL_Rect type when working with SDL. All I did was 
implement a pointer version of my "extension" functions. When I 
had an instance and not a pointer, I took its address when I 
called the function. If that's inconvenient (lots of generic 
code, perhaps), you can always have the pointer version forward 
to the ref version, but it seems to me like just having the one 
version is the way to go most of the time.






Re: UFCS functions with both pointers and refs

2020-12-15 Thread Dave P. via Digitalmars-d-learn

On Tuesday, 15 December 2020 at 19:45:50 UTC, Q. Schroll wrote:

On Sunday, 13 December 2020 at 19:02:34 UTC, Dave P. wrote:

On Sunday, 13 December 2020 at 18:44:20 UTC, Mike Parker wrote:

On Sunday, 13 December 2020 at 18:31:54 UTC, Dave P. wrote:
Do I have to write both and have one forward to the other 
for more

complicated functions?


For free functions, yes.


Is there any way to write the function as a template that is 
generic over a parameter being a pointer or a reference, but 
does not allow passing a copy?


I'm not sure what you mean by a reference. D doesn't have 
references in general, only class references that are just 
glorified pointers. There are also `ref` parameters, but those 
aren't generally referred to as "references" and are inside the 
function almost indiscernible from non-ref parameters. So, I'll 
ignore that.


Copying only takes place under one circumstance: When an lvalue 
is passed to a function that does not take that argument by 
`ref`. So one possibility is to just define that overload and 
@disable it. You don't even need a template for this:


void f(X x); // matches lvalues and rvalues
void f(ref X x); // matches lvalues only

The latter is a better match than the former for lvalues. 
@disable'ing it will do the job. On the other hand, not 
@disable'ing it will make `f` work with any argument by moving 
rvalues to the former overload and referencing lvalues using 
the second one.


On templates, those can be unified by slapping `auto ref` 
before the parameter. You can also use `auto ref` (which infers 
`ref` from the passed argument) and check it with an `if` 
template constraint:


void f(T)(auto ref T arg)
if (!__tratis(isRef, arg)) // only accepts non-ref args
{ /* your code here */ }

The constraint can easily be flipped.


The use case would be to define extension methods on a struct 
outside of where the struct is defined. The extension method 
mutates the state of the struct, so I want to ensure I am 
modifying the original struct and not a copy. If it’s a method 
and I call it on a pointer to the struct, the pointer will get 
auto-dereferenced and everything is great. So my question is that 
if I want an extension method as a free function, do I have to 
write both the version whose first argument is a pointer to the 
struct and the version whose first argument is a ref, or is there 
some keyword or other technique so that the pointer gets 
auto-dereferenced the same way as if it were a method. It sounds 
like the answer is no and I have to write a version that just 
dereferences the pointer and calls the ref version.


Thanks for the explanation though!


Re: UFCS functions with both pointers and refs

2020-12-15 Thread Q. Schroll via Digitalmars-d-learn

On Sunday, 13 December 2020 at 19:02:34 UTC, Dave P. wrote:

On Sunday, 13 December 2020 at 18:44:20 UTC, Mike Parker wrote:

On Sunday, 13 December 2020 at 18:31:54 UTC, Dave P. wrote:
Do I have to write both and have one forward to the other for 
more

complicated functions?


For free functions, yes.


Is there any way to write the function as a template that is 
generic over a parameter being a pointer or a reference, but 
does not allow passing a copy?


I'm not sure what you mean by a reference. D doesn't have 
references in general, only class references that are just 
glorified pointers. There are also `ref` parameters, but those 
aren't generally referred to as "references" and are inside the 
function almost indiscernible from non-ref parameters. So, I'll 
ignore that.


Copying only takes place under one circumstance: When an lvalue 
is passed to a function that does not take that argument by 
`ref`. So one possibility is to just define that overload and 
@disable it. You don't even need a template for this:


void f(X x); // matches lvalues and rvalues
void f(ref X x); // matches lvalues only

The latter is a better match than the former for lvalues. 
@disable'ing it will do the job. On the other hand, not 
@disable'ing it will make `f` work with any argument by moving 
rvalues to the former overload and referencing lvalues using the 
second one.


On templates, those can be unified by slapping `auto ref` before 
the parameter. You can also use `auto ref` (which infers `ref` 
from the passed argument) and check it with an `if` template 
constraint:


void f(T)(auto ref T arg)
if (!__tratis(isRef, arg)) // only accepts non-ref args
{ /* your code here */ }

The constraint can easily be flipped.


Re: UFCS functions with both pointers and refs

2020-12-13 Thread Dave P. via Digitalmars-d-learn

On Sunday, 13 December 2020 at 18:44:20 UTC, Mike Parker wrote:

On Sunday, 13 December 2020 at 18:31:54 UTC, Dave P. wrote:
Do I have to write both and have one forward to the other for 
more

complicated functions?


For free functions, yes.


Is there any way to write the function as a template that is 
generic over a parameter being a pointer or a reference, but does 
not allow passing a copy?


Re: UFCS functions with both pointers and refs

2020-12-13 Thread Mike Parker via Digitalmars-d-learn

On Sunday, 13 December 2020 at 18:31:54 UTC, Dave P. wrote:
If I define a method on a type, then I can call it both through 
a pointer and

through a reference and the compiler does the right thing. Eg:

struct Foo {
int x;
void fooey(){
x++;
}
void report(){
printf("%d\n", x);
}
}

int main(){
Foo f;
f.fooey;
Foo* pf = 
pf.fooey;
f.report; // prints 2
return 0;
}

However, if I define it as a free function and try to invoke it 
via UFCS,

it seems like I have to define it twice.

struct Foo {
int x;
void report(){
printf("%d\n", x);
}
}

void fooey(Foo* f){
f.x++;
}
void fooey(ref Foo f){
f.x++;
}

int main(){
Foo f;
f.fooey;
Foo* pf = 
pf.fooey;
f.report; // prints 2
return 0;
}

Am I missing something or is this just how it has to work 
generally?


These are two very different concepts.

Member functions have a hidden 'this' parameter as the first 
function parameter. For structs, it's a reference to the 
instance. Whether you call it through a pointer or a reference, 
that never changes: there's only one implementation of the 
function, the first parameter is always a reference to the 
instance.


Free functions do not belong to any type (hence the "free"). UFCS 
doesn't change that. UFCS is simply a convenience that rewrites 
`foo.func` as `func(foo)`. You aren't calling "through" a pointer 
or a reference. So if the first parameter is a pointer, you can't 
give it a reference, and vice versa.


Do I have to write both and have one forward to the other for 
more

complicated functions?


For free functions, yes.



UFCS functions with both pointers and refs

2020-12-13 Thread Dave P. via Digitalmars-d-learn
If I define a method on a type, then I can call it both through a 
pointer and

through a reference and the compiler does the right thing. Eg:

struct Foo {
int x;
void fooey(){
x++;
}
void report(){
printf("%d\n", x);
}
}

int main(){
Foo f;
f.fooey;
Foo* pf = 
pf.fooey;
f.report; // prints 2
return 0;
}

However, if I define it as a free function and try to invoke it 
via UFCS,

it seems like I have to define it twice.

struct Foo {
int x;
void report(){
printf("%d\n", x);
}
}

void fooey(Foo* f){
f.x++;
}
void fooey(ref Foo f){
f.x++;
}

int main(){
Foo f;
f.fooey;
Foo* pf = 
pf.fooey;
f.report; // prints 2
return 0;
}

Am I missing something or is this just how it has to work 
generally?

Do I have to write both and have one forward to the other for more
complicated functions?




Re: How Performance down slow it is using UFCS friendly function?

2020-11-20 Thread Paul Backus via Digitalmars-d-learn

On Saturday, 21 November 2020 at 00:26:03 UTC, Marcone wrote:

// Função receive()
char[] receive(Socket socket, int size = 8192) nothrow {
try {
char[] buffer;
buffer.length = size;
int rq = socket.receive(buffer);
return buffer[0..rq];
} catch(Throwable){return null;}
}


s = new Socket(AddressFamily.INET, SocketType.STREAM);
writeln(s.receive(8192)); // How slow is using as friendly 
function?


Calling a function with or without UFCS makes absolutely no 
difference to performance. The compiler will generate the exact 
same code whether you write `receive(s, 8192)` or 
`s.receive(8192)`.


How Performance down slow it is using UFCS friendly function?

2020-11-20 Thread Marcone via Digitalmars-d-learn

// Função receive()
char[] receive(Socket socket, int size = 8192) nothrow {
try {
char[] buffer;
buffer.length = size;
int rq = socket.receive(buffer);
return buffer[0..rq];
} catch(Throwable){return null;}
}


s = new Socket(AddressFamily.INET, SocketType.STREAM);
writeln(s.receive(8192)); // How slow is using as friendly 
function?


Function Templates with Only Template Parameters and UFCS

2020-05-10 Thread Seven Seas via Digitalmars-d-learn

Given the code:

```
auto foo(alias A, string str)()
{
// do stuff
}

struct Bar
{
// members
}

Bar bar;
bar.foo!"hello"; // This is an error. Would have to do foo!(bar, 
"hello")

```

Assuming that I haven't misunderstood or borked something, having 
UFCS for function templates whose parameters are only for the 
template would, seemingly, be nice. Are there workarounds? Is it 
possible to implement, and possibly the more important question, 
is it a good idea? One downside is there would be more ambiguity 
when one is parsing that last line.





Re: Can’t use UFCS to create InputRange?

2020-04-29 Thread Paul Backus via Digitalmars-d-learn

On Wednesday, 29 April 2020 at 12:23:11 UTC, Simen Kjærås wrote:
Of course, nothing stops us from defining our own front, 
popFront and friends that combine the two approaches above:



[...]


We could conceivably add these to std.range.primitives 
(probably adding some constraints first), and suddenly UFCS 
ranges are possible! (I am as of yet not convinced that we 
should, though)


--
  Simen


This is basically what C++ calls "argument-dependent lookup." 
Discussion about adding this sort of thing to D has come up 
before on the forums [1], and iirc Walter has generally been 
opposed to it. If it were to be added as a library feature, it 
would probably have to be opt-in.


[1] 
https://forum.dlang.org/post/mailman.123.1472818535.2965.digitalmar...@puremagic.com


Re: Can’t use UFCS to create InputRange?

2020-04-29 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 29 April 2020 at 09:16:58 UTC, user1234 wrote:
The static checker doesn't see your free funcs because to do so 
it would have to import the whole module. (is it possible to do 
that ? no idea.)


Of course it's possible! :) We can find the context of R (in this 
case, the module) with __traits(parent), and import that:


mixin("import "~__traits(parent, R).stringof["module 
".length..$]~";");


However, doing that in isInputRange doesn't help much. First, all 
other range functions would have to do it, and second, just 
importing into function scope doesn't enable UFCS lookup.



Also your signature for the primitives are quite unusual (i.e 
not idiomatic). Usually they dont take param. Usually we pass a 
type that contains the member funcs matching to IsIntputRange.


You can see a good counterexample to this in 
https://dlang.org/library/std/range/primitives/pop_front.html, 
which defines popFront for regular arrays. However, that is the 
one and only counterexample I know of.


Of course, nothing stops us from defining our own front, popFront 
and friends that combine the two approaches above:



template front(R) {
auto front(R r) {
return __traits(getMember, __traits(parent, R), 
"front")(r);

}
}
template popFront(R) {
auto popFront(R r) {
return __traits(getMember, __traits(parent, R), 
"popFront")(r);

}
}
template empty(R) {
auto empty(R r) {
return __traits(getMember, __traits(parent, R), 
"empty")(r);

}
}

We could conceivably add these to std.range.primitives (probably 
adding some constraints first), and suddenly UFCS ranges are 
possible! (I am as of yet not convinced that we should, though)


--
  Simen


Re: Can’t use UFCS to create InputRange?

2020-04-29 Thread user1234 via Digitalmars-d-learn

On Wednesday, 29 April 2020 at 08:34:53 UTC, Ogi wrote:

struct R {}
int front(R r) { return 42; }
void popFront(R r) {}
bool empty(R r) { return false; }

void main() {
import std.range.primitives : isInputRange;
static assert(isInputRange!R);
}


Error: static assert:  `isInputRange!(R)` is false


Whats really weird is that if I replace isInputRange with its 
definition from std.range.primitives, it returns true:


import std;

struct R {}
int front(R r) { return 42; }
void popFront(R r) {}
bool empty(R r) { return false; }

void main() {
static assert(is(typeof(R.init) == R)
&& is(ReturnType!((R r) => r.empty) == bool)
&& is(typeof((return ref R r) => r.front))
&& !is(ReturnType!((R r) => r.front) == void)
&& is(typeof((R r) => r.popFront)));
}
This compiles.

What’s going on here?


The static checker doesn't see your free funcs because to do so 
it would have to import the whole module. (is it possible to do 
that ? no idea.)
Also your signature for the primitives are quite unusual (i.e not 
idiomatic). Usually they dont take param. Usually we pass a type 
that contains the member funcs matching to IsIntputRange.


Re: Can’t use UFCS to create InputRange?

2020-04-29 Thread Simen Kjærås via Digitalmars-d-learn

On Wednesday, 29 April 2020 at 08:34:53 UTC, Ogi wrote:

struct R {}
int front(R r) { return 42; }
void popFront(R r) {}
bool empty(R r) { return false; }

void main() {
import std.range.primitives : isInputRange;
static assert(isInputRange!R);
}


Error: static assert:  `isInputRange!(R)` is false


What’s going on here?



The template IsInputRange is in the std.range.primitives module, 
and thus can't see the front, popFront and empty definitions in 
your module.


--
  Simen


Can’t use UFCS to create InputRange?

2020-04-29 Thread Ogi via Digitalmars-d-learn

struct R {}
int front(R r) { return 42; }
void popFront(R r) {}
bool empty(R r) { return false; }

void main() {
import std.range.primitives : isInputRange;
static assert(isInputRange!R);
}


Error: static assert:  `isInputRange!(R)` is false


Whats really weird is that if I replace isInputRange with its 
definition from std.range.primitives, it returns true:


import std;

struct R {}
int front(R r) { return 42; }
void popFront(R r) {}
bool empty(R r) { return false; }

void main() {
static assert(is(typeof(R.init) == R)
&& is(ReturnType!((R r) => r.empty) == bool)
&& is(typeof((return ref R r) => r.front))
&& !is(ReturnType!((R r) => r.front) == void)
&& is(typeof((R r) => r.popFront)));
}
This compiles.

What’s going on here?


Re: No UFCS with nested functions?

2019-11-05 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, November 5, 2019 9:16:27 AM MST ixid via Digitalmars-d-learn 
wrote:
> On Monday, 4 November 2019 at 20:46:41 UTC, H. S. Teoh wrote:
> > On Mon, Nov 04, 2019 at 07:51:26PM +, Tobias Pankrath via
> >
> > Digitalmars-d-learn wrote:
> >> Why does the following not work? It works, if I move the
> >> 'prop' out of 'foo'.
> >
> > UFCS is only supported for module-level functions, as far as I
> > know.
> >
> >> ---
> >> struct S {
> >>
> >>ubyte[12] bar;
> >>
> >> }
> >>
> >> bool foo (ref S s)
> >> {
> >>
> >>static bool prop(const(ubyte)[] f) {
> >>
> >>   return f.length > 1;
> >>
> >>}
> >>
> >>return s.bar[].prop;
> >>
> >> }
> >> ---
> >
> > [...]
> >
> >
> > T
>
> Is this a necessary limitation? It feels inconsistent and clunky.

It's explained at the end of this section of the documentation:

https://dlang.org/spec/function.html#pseudo-member

- Jonathan M Davis





Re: No UFCS with nested functions?

2019-11-05 Thread ixid via Digitalmars-d-learn

On Monday, 4 November 2019 at 20:46:41 UTC, H. S. Teoh wrote:
On Mon, Nov 04, 2019 at 07:51:26PM +, Tobias Pankrath via 
Digitalmars-d-learn wrote:
Why does the following not work? It works, if I move the 
'prop' out of 'foo'.


UFCS is only supported for module-level functions, as far as I 
know.




---
struct S {
ubyte[12] bar;
}

bool foo (ref S s)
{
   static bool prop(const(ubyte)[] f) {
  return f.length > 1;
   }
return s.bar[].prop;
}
---

[...]


T


Is this a necessary limitation? It feels inconsistent and clunky.


Re: No UFCS with nested functions?

2019-11-04 Thread Paul Backus via Digitalmars-d-learn
On Tuesday, 5 November 2019 at 00:34:33 UTC, Nicholas Wilson 
wrote:

https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/

struct S {
ubyte[12] bar;
}

alias I(alias f) = f;

bool foo (ref S s)
{
   static bool prop(const(ubyte)[] f) {
  return f.length > 1;
   }
return s.bar[].I!prop;
}


It's in Phobos:

import std.meta: Alias;

return s.bar[].Alias!prop


Re: No UFCS with nested functions?

2019-11-04 Thread Nicholas Wilson via Digitalmars-d-learn

On Monday, 4 November 2019 at 19:51:26 UTC, Tobias Pankrath wrote:
Why does the following not work? It works, if I move the 'prop' 
out of 'foo'.


---
struct S {
ubyte[12] bar;
}

bool foo (ref S s)
{
   static bool prop(const(ubyte)[] f) {
  return f.length > 1;
   }
return s.bar[].prop;
}
---

Thanks!


https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/

struct S {
ubyte[12] bar;
}

alias I(alias f) = f;

bool foo (ref S s)
{
   static bool prop(const(ubyte)[] f) {
  return f.length > 1;
   }
return s.bar[].I!prop;
}


Re: No UFCS with nested functions?

2019-11-04 Thread H. S. Teoh via Digitalmars-d-learn
On Mon, Nov 04, 2019 at 07:51:26PM +, Tobias Pankrath via 
Digitalmars-d-learn wrote:
> Why does the following not work? It works, if I move the 'prop' out of
> 'foo'.

UFCS is only supported for module-level functions, as far as I know.


> ---
> struct S {
>   ubyte[12] bar;
> }
> 
> bool foo (ref S s)
> {
>static bool prop(const(ubyte)[] f) {
>   return f.length > 1;
>}
>   return s.bar[].prop;
> }
> ---
[...]


T

-- 
I am not young enough to know everything. -- Oscar Wilde


No UFCS with nested functions?

2019-11-04 Thread Tobias Pankrath via Digitalmars-d-learn
Why does the following not work? It works, if I move the 'prop' 
out of 'foo'.


---
struct S {
ubyte[12] bar;
}

bool foo (ref S s)
{
   static bool prop(const(ubyte)[] f) {
  return f.length > 1;
   }
return s.bar[].prop;
}
---

Thanks!




Re: Cannot use UFCS in lambda?

2018-09-16 Thread Paul Backus via Digitalmars-d-learn

On Sunday, 16 September 2018 at 10:55:43 UTC, berni wrote:
The problem is more general: you can only use top-level 
symbols in UFCS.


You can use an identity alias template to bypass this:
https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/
(search for UFCS in the page).


Good to know. :-)


Worth noting, this is now included in Phobos as `std.meta.Alias`.


Re: Cannot use UFCS in lambda?

2018-09-16 Thread berni via Digitalmars-d-learn
The problem is more general: you can only use top-level symbols 
in UFCS.


You can use an identity alias template to bypass this:
https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/
(search for UFCS in the page).


Good to know. :-)


Re: Cannot use UFCS in lambda?

2018-09-16 Thread Vladimir Panteleev via Digitalmars-d-learn

On Sunday, 16 September 2018 at 09:46:15 UTC, berni wrote:

Where is my mistake?


Lambdas are not the issue here. The problem is more general: you 
can only use top-level symbols in UFCS.


You can use an identity alias template to bypass this:
https://blog.thecybershadow.net/2015/04/28/the-amazing-template-that-does-nothing/
(search for UFCS in the page).



Cannot use UFCS in lambda?

2018-09-16 Thread berni via Digitalmars-d-learn

The following program does not compile:


import std.stdio;
import std.algorithm;

struct A
{
   struct S
   {
   int x;
   }

   const bool foo(in S s, in int k)
   {
   return s.xa.foo(3)).writeln;
   }
}

void main()
{
   A().bar();
}


I get (using rdmd):


test.d(18): Error: no property foo for type S
/usr/include/dmd/phobos/std/algorithm/iteration.d(1108):
instantiated from here: >FilterResult!(__lambda1, S[])

test.d(18):instantiated from here: filter!(S[])


When I replace the UFCS-Syntax in the lambda by a function call 
it works:



[S(1),S(2),S(3),S(4),S(5)].filter!(a=>foo(a,3)).writeln;


Where is my mistake?


Re: Why does not UFCS work for method defined inside unittest block?

2018-08-01 Thread Ky-Anh Huynh via Digitalmars-d-learn

On Tuesday, 31 July 2018 at 08:42:28 UTC, Simen Kjærås wrote:



From https://dlang.org/spec/function.html#pseudo-member:
"A free function can be called with a syntax that looks as if 
the function were a member function of its first parameter 
type."


 [...]


Thanks a lot Simen :)



Re: Why does not UFCS work for method defined inside unittest block?

2018-07-31 Thread Simen Kjærås via Digitalmars-d-learn

On Tuesday, 31 July 2018 at 08:28:01 UTC, Ky-Anh Huynh wrote:

Hi,

Can I define a new quick function to use inside a unittest 
block?


I have the following code:

[code]
auto foo(string[] sta) {
  return sta;
}

auto bar(string[] sta) {
  return sta;
}

auto h(string[] sta) {
  return sta.foo.bar;
}

unittest {
  import std.format;

  auto f = (string[] sta) => sta.foo.bar;
  auto g(string[] sta) {
return sta.foo.bar;
  }

  assert(f(["test"]) == ["test"]);
  assert(g(["test"]) == ["test"]);
  assert(["test"].h == ["test"]);
  assert(["test"].g == ["test"]);
}
[/code]

(Src: 
https://gist.github.com/icy/64ec1838929d448d9f874d1e8261e56a)


The last test will fail: Error: no property g for type string[]

Please advise.


From https://dlang.org/spec/function.html#pseudo-member:
"A free function can be called with a syntax that looks as if the 
function were a member function of its first parameter type."


A function defined in a function scope (which a unittest block 
is), is not a free function, and so does not benefit from UFCS. 
There is an explanation for why at the bottom of the above page:
"The reason why local symbols are not considered by UFCS, is to 
avoid unexpected name conflicts."


If you need a function that's available for UFCS in a unittest 
but is not there in a non-unittest context, use a version block:


version (unittest) {
auto fun(string[] s) { return s }
}

And if you need something with a context:

version (unittest) {
string delegate (string) test;
}
unittest {
string s1 = "foo";
test = s => s ~ s1;
"foo".test;
}

--
  Simen


Re: Why does not UFCS work for method defined inside unittest block?

2018-07-31 Thread Ky-Anh Huynh via Digitalmars-d-learn

dmd version that I'm using:

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




Why does not UFCS work for method defined inside unittest block?

2018-07-31 Thread Ky-Anh Huynh via Digitalmars-d-learn

Hi,

Can I define a new quick function to use inside a unittest block?

I have the following code:

[code]
auto foo(string[] sta) {
  return sta;
}

auto bar(string[] sta) {
  return sta;
}

auto h(string[] sta) {
  return sta.foo.bar;
}

unittest {
  import std.format;

  auto f = (string[] sta) => sta.foo.bar;
  auto g(string[] sta) {
return sta.foo.bar;
  }

  assert(f(["test"]) == ["test"]);
  assert(g(["test"]) == ["test"]);
  assert(["test"].h == ["test"]);
  assert(["test"].g == ["test"]);
}
[/code]

(Src: 
https://gist.github.com/icy/64ec1838929d448d9f874d1e8261e56a)


The last test will fail: Error: no property g for type string[]

Please advise.

Thanks a lot.





Re: UFCS confusion

2018-07-16 Thread vit via Digitalmars-d-learn

On Friday, 13 July 2018 at 11:37:09 UTC, Michael wrote:

On Friday, 13 July 2018 at 11:17:32 UTC, Radu wrote:

On Friday, 13 July 2018 at 11:12:47 UTC, Michael wrote:

On Friday, 13 July 2018 at 10:52:54 UTC, Radu wrote:

On Friday, 13 July 2018 at 10:21:54 UTC, Michael wrote:

[...]


Do you try to call member functions? UFCS only works with 
free functions, meaning declared at module level.


https://dlang.org/spec/function.html#pseudo-member


I'm not intentionally trying to call member functions, no. 
The functions are all static functions of a class, but the 
chaining of them using UFCS doesn't seem to work.


OK, static functions of a class are static *member* functions, 
they are not free functions.


Oh, really? Well that will explain it then. I was sure I had 
used this syntax before but perhaps not. Thanks for your help!


try this:

import std.functional : pipe;

createVector(langSize, index).pipe!createSet.length;


Re: UFCS confusion

2018-07-13 Thread Michael via Digitalmars-d-learn

On Friday, 13 July 2018 at 11:17:32 UTC, Radu wrote:

On Friday, 13 July 2018 at 11:12:47 UTC, Michael wrote:

On Friday, 13 July 2018 at 10:52:54 UTC, Radu wrote:

On Friday, 13 July 2018 at 10:21:54 UTC, Michael wrote:

[...]


Do you try to call member functions? UFCS only works with 
free functions, meaning declared at module level.


https://dlang.org/spec/function.html#pseudo-member


I'm not intentionally trying to call member functions, no. The 
functions are all static functions of a class, but the 
chaining of them using UFCS doesn't seem to work.


OK, static functions of a class are static *member* functions, 
they are not free functions.


Oh, really? Well that will explain it then. I was sure I had used 
this syntax before but perhaps not. Thanks for your help!


Re: UFCS confusion

2018-07-13 Thread Radu via Digitalmars-d-learn

On Friday, 13 July 2018 at 11:12:47 UTC, Michael wrote:

On Friday, 13 July 2018 at 10:52:54 UTC, Radu wrote:

On Friday, 13 July 2018 at 10:21:54 UTC, Michael wrote:

[...]


Do you try to call member functions? UFCS only works with free 
functions, meaning declared at module level.


https://dlang.org/spec/function.html#pseudo-member


I'm not intentionally trying to call member functions, no. The 
functions are all static functions of a class, but the chaining 
of them using UFCS doesn't seem to work.


OK, static functions of a class are static *member* functions, 
they are not free functions.


Re: UFCS confusion

2018-07-13 Thread Michael via Digitalmars-d-learn

On Friday, 13 July 2018 at 10:52:54 UTC, Radu wrote:

On Friday, 13 July 2018 at 10:21:54 UTC, Michael wrote:

Hello,

I am nesting some function calls, and I'm pretty used to 
making use of D's Uniform Function Call Syntax, but I'm 
getting an error if I try to convert this line:



createSet(createVector(langSize, index)).length;


which works, into this line:


createVector(langSize, index).createSet.length;


receiving the error "Error: no property createSet for type 
int[]", when the signature for createSet is:



static auto createSet(in int[] vector) pure


What am I missing here? I'm sure it's stupidly obvious but it 
expects one argument, so I'm just calling it without 
parentheses.


Do you try to call member functions? UFCS only works with free 
functions, meaning declared at module level.


https://dlang.org/spec/function.html#pseudo-member


I'm not intentionally trying to call member functions, no. The 
functions are all static functions of a class, but the chaining 
of them using UFCS doesn't seem to work.


Re: UFCS confusion

2018-07-13 Thread Radu via Digitalmars-d-learn

On Friday, 13 July 2018 at 10:21:54 UTC, Michael wrote:

Hello,

I am nesting some function calls, and I'm pretty used to making 
use of D's Uniform Function Call Syntax, but I'm getting an 
error if I try to convert this line:



createSet(createVector(langSize, index)).length;


which works, into this line:


createVector(langSize, index).createSet.length;


receiving the error "Error: no property createSet for type 
int[]", when the signature for createSet is:



static auto createSet(in int[] vector) pure


What am I missing here? I'm sure it's stupidly obvious but it 
expects one argument, so I'm just calling it without 
parentheses.


Do you try to call member functions? UFCS only works with free 
functions, meaning declared at module level.


https://dlang.org/spec/function.html#pseudo-member


UFCS confusion

2018-07-13 Thread Michael via Digitalmars-d-learn

Hello,

I am nesting some function calls, and I'm pretty used to making 
use of D's Uniform Function Call Syntax, but I'm getting an error 
if I try to convert this line:



createSet(createVector(langSize, index)).length;


which works, into this line:


createVector(langSize, index).createSet.length;


receiving the error "Error: no property createSet for type 
int[]", when the signature for createSet is:



static auto createSet(in int[] vector) pure


What am I missing here? I'm sure it's stupidly obvious but it 
expects one argument, so I'm just calling it without parentheses.


Re: UFCS syntax I never saw before.

2018-05-24 Thread aliak via Digitalmars-d-learn

On Thursday, 24 May 2018 at 22:03:38 UTC, aliak wrote:
It feels like the only difference between a no-arg function 
that is @property and one that is not is that the former could 
be invoked with optional parentheses and the latter should be 
illegal with parentheses.


Edit: err... other way around!





Re: UFCS syntax I never saw before.

2018-05-24 Thread aliak via Digitalmars-d-learn

On Tuesday, 22 May 2018 at 14:33:20 UTC, Jonathan M Davis wrote:
A free function with a single argument works just fine as a 
setter property. e.g. you could do something like


void env(Tuple!(string, string)[] str)
{
// set environment variables
}

env = [tuple("foo", "bar")];

is perfectly legal. I question that there are many cases where 
such a function would be considered good design, but basically 
any case where it would make sense to have a function act like 
a global variable is currently allowed but would be disallowed 
if you couldn't have a setter property with only one argument.


- Jonathan M Davis


That can be attributed with @property if the developer intends 
for it to be used in that way, else should be illegal.





Re: UFCS syntax I never saw before.

2018-05-24 Thread aliak via Digitalmars-d-learn
On Tuesday, 22 May 2018 at 13:59:16 UTC, Steven Schveighoffer 
wrote:
The derailed plan was to leave alone the ability to call no-arg 
functions without parentheses, but to REQUIRE @property to call 
an argument-taking function with the assignment style.


See the DIP here: https://wiki.dlang.org/DIP23

Written by Walter and Andrei. I can't remember why it didn't 
happen.


-Steve


Aha. Thanks for the link!

It feels like the only difference between a no-arg function that 
is @property and one that is not is that the former could be 
invoked with optional parentheses and the latter should be 
illegal with parentheses.


Whereas an argument taking function marked as @property should 
probably allow read or write operations depending on whether or 
not it's invoked with an implicit first argument or not:


@property int f(int) { ... }
1.f; // read op
f = 1; // write op

And to make parentheses illegal as well of course.




Re: UFCS syntax I never saw before.

2018-05-22 Thread Jonathan M Davis via Digitalmars-d-learn
On Tuesday, May 22, 2018 13:48:16 aliak via Digitalmars-d-learn wrote:
> On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis wrote:
> > writeln = "foo";
> >
> > is legal, and it's dumb, but it hasn't mattered much in
> > practice. So, causing a bunch of code breakage in order to
> > disallow it is unlikely to go over well. It would also then
> > make getters and setters inconsistent in that setters would
> > require @property and getters wouldn't. How much that matters
> > is debatable, but it does make such a change less palatable.
> >
> > [...]
>
> Can't assignment to a function be fixed though? Are there any
> cases where fixing that will cause problems for @property free
> functions because they all must take more that one parameter i
> assume.
>
> It's quite a big wart so we don't have to fix all of @property at
> least, but that should be fixed if fixing it does not crap on
> UFCS and @property free functions.

A free function with a single argument works just fine as a setter property.
e.g. you could do something like

void env(Tuple!(string, string)[] str)
{
// set environment variables
}

env = [tuple("foo", "bar")];

is perfectly legal. I question that there are many cases where such a
function would be considered good design, but basically any case where it
would make sense to have a function act like a global variable is currently
allowed but would be disallowed if you couldn't have a setter property with
only one argument.

- Jonathan M Davis



Re: UFCS syntax I never saw before.

2018-05-22 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/22/18 9:48 AM, aliak wrote:

On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis wrote:


writeln = "foo";

is legal, and it's dumb, but it hasn't mattered much in practice. So, 
causing a bunch of code breakage in order to disallow it is unlikely 
to go over well. It would also then make getters and setters 
inconsistent in that setters would require @property and getters 
wouldn't. How much that matters is debatable, but it does make such a 
change less palatable.


[...]



Can't assignment to a function be fixed though? Are there any cases 
where fixing that will cause problems for @property free functions 
because they all must take more that one parameter i assume.


It's quite a big wart so we don't have to fix all of @property at least, 
but that should be fixed if fixing it does not crap on UFCS and 
@property free functions.




The derailed plan was to leave alone the ability to call no-arg 
functions without parentheses, but to REQUIRE @property to call an 
argument-taking function with the assignment style.


See the DIP here: https://wiki.dlang.org/DIP23

Written by Walter and Andrei. I can't remember why it didn't happen.

-Steve


Re: UFCS syntax I never saw before.

2018-05-22 Thread aliak via Digitalmars-d-learn

On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis wrote:


writeln = "foo";

is legal, and it's dumb, but it hasn't mattered much in 
practice. So, causing a bunch of code breakage in order to 
disallow it is unlikely to go over well. It would also then 
make getters and setters inconsistent in that setters would 
require @property and getters wouldn't. How much that matters 
is debatable, but it does make such a change less palatable.


[...]



Can't assignment to a function be fixed though? Are there any 
cases where fixing that will cause problems for @property free 
functions because they all must take more that one parameter i 
assume.


It's quite a big wart so we don't have to fix all of @property at 
least, but that should be fixed if fixing it does not crap on 
UFCS and @property free functions.




Re: UFCS syntax I never saw before.

2018-05-22 Thread aliak via Digitalmars-d-learn
On Monday, 21 May 2018 at 14:19:35 UTC, Steven Schveighoffer 
wrote:

On 5/21/18 8:15 AM, SrMordred wrote:

Right, so this should´n be working I think.


struct SomeStruct
{
    void foo(int);
}

SomeStruct s;
s.foo = 10;


I thought that only with @property this will work.



That was the plan, but it got derailed.

Whoever wrote that original line of code, they need a stern 
talking-to.


-Steve


While wearing the naughty pointy hat and sitting in a corner :p


Re: UFCS syntax I never saw before.

2018-05-22 Thread ANtlord via Digitalmars-d-learn

On Monday, 21 May 2018 at 18:53:19 UTC, Jonathan M Davis wrote:
On Monday, May 21, 2018 14:00:55 ANtlord via 
Digitalmars-d-learn wrote:


If someone wrote an good DIP on the subject, I expect that 
things could be accelerated, but it's not much a real paint 
point in practice, and the chances of @property actually ever 
meaning anything like it was originally intended to mean are 
pretty much zero. UFCS killed that.


- Jonathan M Davis


First of all thanks a lot for the response. It cleans something 
for me. I need a few time to think.




Re: UFCS syntax I never saw before.

2018-05-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, May 21, 2018 14:00:55 ANtlord via Digitalmars-d-learn wrote:
> On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:
> > After all this time I saw this:
> >
> > writeln = iota = 5;
> >
> > what??
> >
> > I never saw that before!
> >
> > This is interesting, there is something useful that i can do
> > with this kind of call?
>
> What the hell is this? I don't figure out why are there so many
> syntax features? It doesn't make the language more easier. Is it
> any reason to support 2 additional cases of function calling? We
> have no literal for a tuple but we call a function via 3 cases.
> I'm frustrated.

This particular example is a result of how property functions were
originally introduced into the language, and UCFS just compounded the
problem. It's also why () is optional on function calls.

foo = bar;

is treating foo like a setter property, and

auto result = foo;

is treating foo like a getter property. Heck, in

foo = bar;

both foo and bar could be function calls. As long as it's used
intelligently, this is great, because then you can treat functions as
properties. But it gets really bad when someone does something dumb like

writeln = "hello";

Because this can get really dumb, @property was introduced into the language
with the idea that it would be used to mark functions which were supposed to
be used as properties. Then dumb stuff like

writeln = "hello";

could become illegal, whereas stuff functions that were actually intended to
be used as properties could continue to be used as properties. So, the clean
uses would be left, and the bad uses would be illegal. Unfortunately,
because moving to @property meant breaking code (even code that was using
properties legitimately, since it was introduced before @property was a
thing), that meant that we had to introduce @property as doing nothing and
then switch to enforcing it later. Somewhere along the line, the -property
flag was introduced to start enforcing it, but it only partially enforced
it, and of course code continued to be written without using it. So,
actually moving to enforcing everything with @property was slow.

And then UFCS happened, and that pretty much killed the whole thing. The
problem was twofold:

1. A number of folks just got in the habit of calling functions without
parens and liked it. They would generally agree that

writeln = "foo";

was dumb, but they liked being able to just not use parens when doing stuff
like

myObj = foo;

or

myFunc(foo);

So, telling them that they couldn't do that anymore didn't go over well.

2. Once, UFCS came into the game, instead of having code like

auto result = map!(a => a / 2)(range);

you got

auto result = range.map!(a => / 2)();

and you all of a sudden had a bunch of templated functions with empty
parens when called, and since you already had a one set of parens for the
template argument, folks thought that that was ugly. So, they started
writing

auto result = range.map!(a => / 2);

So, requiring that they then use parens for that as they would have to if
parens were required when calling all non-@property functions as had been
the plan was _not_ going to go over well. It basically became completely
unacceptable to require @property for property functions, and so plans to
properly implement @property were dropped.

The result is that @property does almost nothing (it affects what typeof
does, and it affects __traits - and thus std.traits.functionAttributes - and
you can't overload an @property function and a normal function, but that's
pretty much it). Lots of us use it all the time to indicate what we intend
to be used as a property function, but it's just documentation.

Now, even if you think that calling functions with no parens is great, that
still leaves us with two problems:

1. writeln = "foo"; is still legal. Maybe we could make it so that @property
is required with free functions used as setters that aren't used with UFCS,
but figuring out a set of rules that doesn't require putting @property on
all setter functions while still disallowing the really dumb stuff isn't
easy, and it's questionable that requiring @property on setters at this
point is going to go over well. It's very annoying that stuff like

writeln = "foo";

is legal, and it's dumb, but it hasn't mattered much in practice. So,
causing a bunch of code breakage in order to disallow it is unlikely to go
over well. It would also then make getters and setters inconsistent in that
setters would require @property and getters wouldn't. How much that matters
is debatable, but it does make such a change less palatable.

2. The other issue that @property was supposed to fix was property functions
that return callables - e.g. foo could return a delegate, but the compiler
has to assume that the parens on foo() are calling foo, not the delegate
that it returns. So, 

Re: UFCS syntax I never saw before.

2018-05-21 Thread SrMordred via Digitalmars-d-learn

"%s %s".writefln = ("foo".tuple = "bar").expand;

lol



Re: UFCS syntax I never saw before.

2018-05-21 Thread Dennis via Digitalmars-d-learn

On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:

what??


Here's another weird example:
```
void funWithUfcsAndPropertySyntax() {
import std.typecons : tuple;
"%s %s".writefln = ("foo".tuple = "bar").expand;
}
```

source: 
https://github.com/Hackerpilot/Idiotmatic-D/blob/master/idiotmatic.d#L78


Re: UFCS syntax I never saw before.

2018-05-21 Thread Chris M. via Digitalmars-d-learn

On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:

After all this time I saw this:

writeln = iota = 5;

what??

I never saw that before!

This is interesting, there is something useful that i can do 
with this kind of call?


That's pretty cool, but at the same time this should be wiped off 
the face of the Earth.


Re: UFCS syntax I never saw before.

2018-05-21 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/21/18 8:15 AM, SrMordred wrote:

Right, so this should´n be working I think.


struct SomeStruct
{
    void foo(int);
}

SomeStruct s;
s.foo = 10;


I thought that only with @property this will work.



That was the plan, but it got derailed.

Whoever wrote that original line of code, they need a stern talking-to.

-Steve


Re: UFCS syntax I never saw before.

2018-05-21 Thread ANtlord via Digitalmars-d-learn

On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:

After all this time I saw this:

writeln = iota = 5;

what??

I never saw that before!

This is interesting, there is something useful that i can do 
with this kind of call?


What the hell is this? I don't figure out why are there so many 
syntax features? It doesn't make the language more easier. Is it 
any reason to support 2 additional cases of function calling? We 
have no literal for a tuple but we call a function via 3 cases. 
I'm frustrated.


D has a lot cool features, I like D, but that is one of those 
which make me doubt the language future. I don't play a big role 
in the project but I talk to all my python co-workers: "You 
know... so there so cool language, it's called D. It can do this 
and that... It supports convenient static typing so you 
definitely know what happens in a piece of code.". But something 
like this make doubt about what happens in a piece of code. There 
is static typing so I know that type a variable has, but I look 
at a method calling and I ask: "Is it data field? No. Is it 
property? No. Is it method? No. It's UFCS! Okay." And now I see 
that UFCS can works the same way as a property!


Re: UFCS syntax I never saw before.

2018-05-21 Thread SrMordred via Digitalmars-d-learn

Right, so this should´n be working I think.


struct SomeStruct
{
void foo(int);
}

SomeStruct s;
s.foo = 10;


I thought that only with @property this will work.



Re: UFCS syntax I never saw before.

2018-05-21 Thread Rubn via Digitalmars-d-learn

On Monday, 21 May 2018 at 11:38:12 UTC, SrMordred wrote:

After all this time I saw this:

writeln = iota = 5;

what??

I never saw that before!

This is interesting, there is something useful that i can do 
with this kind of call?


I probably wouldn't use that. That wasn't what it was intended 
for and it's not really UFCS. It's was meant for properties that 
are defined as functions.


struct SomeStruct
{
void foo(int);
}

SomeStruct s;
s.foo = 10;

It's kind of horrible syntax for what it is doing, where it isn't 
obvious what is happening. Writeln and iota aren't setting 
anything, they are just function calls that happen to be able to 
take one parameter.


UFCS syntax I never saw before.

2018-05-21 Thread SrMordred via Digitalmars-d-learn

After all this time I saw this:

writeln = iota = 5;

what??

I never saw that before!

This is interesting, there is something useful that i can do with 
this kind of call?


Re: UFCS in generic libraries, silent hijacking, and compile errors.

2018-03-13 Thread aliak via Digitalmars-d-learn

On Sunday, 11 March 2018 at 15:24:31 UTC, Jonathan M Davis wrote:
On Sunday, March 11, 2018 08:39:54 aliak via 
Digitalmars-d-learn wrote:

On Saturday, 10 March 2018 at 23:00:07 UTC, Jonathan M Davis
> issue in practice. That doesn't mean that it's never a 
> problem, but from what I've seen, it's very rarely a 
> problem, and it's easy to work around if you run into a 
> particular case where it is a problem.


Ya, it's easy to work around but the caveat there is you need 
to realize it's happening first, and add that to that it's 
"rarely a problem" and well ... now it seems scary enough for 
this to mentioned somewhere I'd say.


You're talking about a situation where you used a function 
whose parameters match that of a member function exactly enough 
that a member function gets called instead of a free function. 
That _can_ happen, but in most cases, there's going to be a 
mismatch, and you'll get a compiler error if the type defines a 
member function that matches the free function. I don't think 
that I have ever seen that happen or ever seen anyone complain 
about it. The only case I recall along those lines was someone 
who was trying to use a free function that they'd decided to 
call front instead of something else, and it had parameters 
beyond just the input range, so that programmer got compilation 
errors when they tried to use it in their range-based functions.


Not saying it's common, just something to be aware of that is 
non-obvious (well it was not to me at least when I started 
getting in to D). It's _probably_ not going to be a problem, but 
if it ever is then it's going to be a very hard to detect one. 
And sure, the solution is to just not use ufcs to be certain, but 
ufcs is pretty damn appealing, which is probably why I didn't 
realize this at the beginning. As generic codes bases grow, the 
chances of this happening is certainly not 0 though.




Essentially yes, though you're passing too many arguments to 
put. There are cases where put(output, foo) will compile while 
output.put(foo) will not. In particular, 
std.range.primitives.put will accept both individual elements 
to be written to the output range and ranges of elements to be 
written, whereas typically, an output range will be written to 
only accept an element at a time. It's even more extreme with 
output ranges of characters, because the free function put will 
accept different string types and convert them, and even if the 
programmer who designed the output range added various 
overloads to put for completeness, it's enough extra work to 
deal with all of the various character types that they probably 
didn't. And put also works with stuff like delegates (most 
frequently used with a toString that accepts an output range), 
which don't have member functions. So, if you write your 
generic code to use the member function put, it's only going to 
work with user-defined types that define the particular 
overload(s) of put that you're using in your function, whereas 
if you use the free function, you have more variety in the 
types of output ranges that your code works with, and you have 
more ways that you can call put (e.g. passing a range of 
elements instead of a single element).


Ooh ouch, well that's certainly good to know about.



Basically I don't see a reason why we wouldn't want the 
following to work:


struct S { void f() {} }
void f(S s, int i) {}
S().f(3); // error


So, are you complaining that it's an error, or you want it to 
be an error? As it stands, it's an error, because as far as the 
compiler is concerned, you tried to call a member function with 
an argument that it doesn't accept.


Complaining that it is an error :) well, not complaining, more 
trying to understand why really. And I appreciate you taking the 
time to explain. There're a lot of points in there so here we 
go...




If you want that code to work, then it would have to add the 
free function to the overload set while somehow leaving out the 
overloads that matches the member function, which isn't how D 
deals with overloading at this point.


Yeah, I'd say that's an implementation detail, but the main idea 
would be to treat an overload set that completely fails as an 
undefined function so that ufcs would kick in. Your problems with 
put would also go away then and implementing an output range 
would be less of a hassle.


But if it did, then you have problems as soon as the type adds 
another member function overload.


I'm not sure I see how. The member function would win out. This 
is the situation now anyway, with the added (IMO) disadvantage of 
ufcs being unusable then.


Also, if you have a free function that matches the name of a 
member function but where their parameters don't match, 
wouldn't they be unrelated functions?


Well, maybe. The free function takes T as the first parameter so 
it's certainly related to the type. I suppose they are unrelated 
in the same way that:


struct S {

Re: UFCS in generic libraries, silent hijacking, and compile errors.

2018-03-11 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, March 11, 2018 08:39:54 aliak via Digitalmars-d-learn wrote:
> On Saturday, 10 March 2018 at 23:00:07 UTC, Jonathan M Davis
> > issue in practice. That doesn't mean that it's never a problem,
> > but from what I've seen, it's very rarely a problem, and it's
> > easy to work around if you run into a particular case where it
> > is a problem.
>
> Ya, it's easy to work around but the caveat there is you need to
> realize it's happening first, and add that to that it's "rarely a
> problem" and well ... now it seems scary enough for this to
> mentioned somewhere I'd say.

You're talking about a situation where you used a function whose parameters
match that of a member function exactly enough that a member function gets
called instead of a free function. That _can_ happen, but in most cases,
there's going to be a mismatch, and you'll get a compiler error if the type
defines a member function that matches the free function. I don't think that
I have ever seen that happen or ever seen anyone complain about it. The only
case I recall along those lines was someone who was trying to use a free
function that they'd decided to call front instead of something else, and it
had parameters beyond just the input range, so that programmer got
compilation errors when they tried to use it in their range-based functions.

I think that this is really a theoretical concern and not a practical one.
Certainly, it's really only going to potentially be an issue in library code
that gets used by a ton of folks with completely unexpected types. If it's
in your own code, you're usually well aware of what types are going to be
used with a generic function, and proper testing would catch the rare case
where there would be a problem. If you're really worried about it, then just
don't use UFCS, but for better or worse, it seems to be the case that the
vast majority of D programmers use UFCS all the time and don't run into
problems like this.

> > The one case that I am aware of where best practice is to avoid
> > UFCS is with put for output ranges, but that has nothing to
> > with your concerns here. Rather, it has to do with the fact
> > that std.range.primitives.put has a lot of overloads for
> > handling various arguments (particularly when handling ranges
> > of characters), and almost no one implements their output
> > ranges with all of those overloads. So, if you use put with
> > UFCS, you tend to run into problems if you do anything other
> > than put a single element of the exact type at a time, whereas
> > the free function handles more cases (even if they ultimately
> > end up calling that member function with a single argument of
> > the exact type). We probably shouldn't have had the free
> > function and the member function share the same name.
>
> Oh, can you share a short example here maybe? Not sure I followed
> completely
>
> Is it basically:
>
> // if r is output range
>
> r.put(a, b) // don't do this?
>
> put(r, a, b) // but do this?
>
> (Cause compilation error)

Essentially yes, though you're passing too many arguments to put. There are
cases where put(output, foo) will compile while output.put(foo) will not. In
particular, std.range.primitives.put will accept both individual elements to
be written to the output range and ranges of elements to be written, whereas
typically, an output range will be written to only accept an element at a
time. It's even more extreme with output ranges of characters, because the
free function put will accept different string types and convert them, and
even if the programmer who designed the output range added various overloads
to put for completeness, it's enough extra work to deal with all of the
various character types that they probably didn't. And put also works with
stuff like delegates (most frequently used with a toString that accepts an
output range), which don't have member functions. So, if you write your
generic code to use the member function put, it's only going to work with
user-defined types that define the particular overload(s) of put that you're
using in your function, whereas if you use the free function, you have more
variety in the types of output ranges that your code works with, and you
have more ways that you can call put (e.g. passing a range of elements
instead of a single element).

> How about if it's not part of the overload set, but is looked up
> if the function does not exist in the overload set. What would
> the problems there be?
>
> Basically I don't see a reason why we wouldn't want the following
> to work:
>
> struct S { void f() {} }
> void f(S s, int i) {}
> S().f(3); // error

So, are you complaining that it's an error, or you want it to be an error?
As it stands, it's an error, because as far as the compiler is concerned,
you tried to 

Re: UFCS in generic libraries, silent hijacking, and compile errors.

2018-03-11 Thread aliak via Digitalmars-d-learn
On Saturday, 10 March 2018 at 23:00:07 UTC, Jonathan M Davis 
wrote:


The idea is that the type can provide its own version of the 
function that is better optimized for it - e.g. it could 
potentially provide a member function find that is more 
efficient for it than std.algorithm.searching.find. That's 
actually the only technical reason why UFCS is superior to the 
normal function call syntax.


I think this may have hit the nail on the spot. So basically my 
thinking is that if you're going to use UFCS inside a generic 
function where you can't know what kind of methods the type has, 
do not do it unless you want this particular behavior or if your 
intent is to use a type's known API.


issue in practice. That doesn't mean that it's never a problem, 
but from what I've seen, it's very rarely a problem, and it's 
easy to work around if you run into a particular case where it 
is a problem.


Ya, it's easy to work around but the caveat there is you need to 
realize it's happening first, and add that to that it's "rarely a 
problem" and well ... now it seems scary enough for this to 
mentioned somewhere I'd say.




The one case that I am aware of where best practice is to avoid 
UFCS is with put for output ranges, but that has nothing to 
with your concerns here. Rather, it has to do with the fact 
that std.range.primitives.put has a lot of overloads for 
handling various arguments (particularly when handling ranges 
of characters), and almost no one implements their output 
ranges with all of those overloads. So, if you use put with 
UFCS, you tend to run into problems if you do anything other 
than put a single element of the exact type at a time, whereas 
the free function handles more cases (even if they ultimately 
end up calling that member function with a single argument of 
the exact type). We probably shouldn't have had the free 
function and the member function share the same name.


Oh, can you share a short example here maybe? Not sure I followed 
completely


Is it basically:

// if r is output range

r.put(a, b) // don't do this?

put(r, a, b) // but do this?

(Cause compilation error)




Is there something I'm not seeing as to why UFCS is not part 
of the overload set, and is there a way other than not using 
UFCS to prevent the silent hijacking?


If it were part of the overload set, then you have problems 
calling member functions, particularly because there is no way 
to call a member function other than with UFCS, whereas you can 
call free functions without UFCS, and if you _really_ want to 
be sure that a very specific function is called, then you can 
even give its entire module path when calling it. When UFCS was 
introduced, it was decided that having member functions always 
win out would cause the fewest problems.


- Jonathan M Davis


Ah yes, ok this makes sense.

Follow up:

How about if it's not part of the overload set, but is looked up 
if the function does not exist in the overload set. What would 
the problems there be?


Basically I don't see a reason why we wouldn't want the following 
to work:


struct S { void f() {} }
void f(S s, int i) {}
S().f(3); // error

Thanks!




Re: UFCS in generic libraries, silent hijacking, and compile errors.

2018-03-10 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, March 10, 2018 21:50:42 aliak via Digitalmars-d-learn wrote:
> What are the recommended guidelines for using/not using UFCS in
> writing generic libraries?
>
> I ask because if you have an internal generic free function that
> you use on types in a generic algorithm via ufcs, then everything
> works fine until the type being operated on has a member function
> with a similar name.

The idea is that the type can provide its own version of the function that
is better optimized for it - e.g. it could potentially provide a member
function find that is more efficient for it than
std.algorithm.searching.find. That's actually the only technical reason why
UFCS is superior to the normal function call syntax. Everything else is a
matter of personal preference, though some folks prefer UFCS enough that
they use it everywhere. And as long as the code isn't generic, that's
usually not a problem, but using UFCS in generic code with a function that
isn't well-known can risk problems if it happens to match a member function.
The main reason that this isn't generally a problem is that most generic
code operates on either a fairly specific subset of types or on a specific
API where types implementing that API don't usually implement extra
functions (in particular, ranges normally only define the range API
functions, so it's rare that they have member functions that conflict with
anything). But if you're worried about it or want a specific function to be
called that definitely isn't a member function, then just don't use UFCS.
The situation that you're concerned about is not one that seems to be much
of an issue in practice. That doesn't mean that it's never a problem, but
from what I've seen, it's very rarely a problem, and it's easy to work
around if you run into a particular case where it is a problem.

The one case that I am aware of where best practice is to avoid UFCS is with
put for output ranges, but that has nothing to with your concerns here.
Rather, it has to do with the fact that std.range.primitives.put has a lot
of overloads for handling various arguments (particularly when handling
ranges of characters), and almost no one implements their output ranges with
all of those overloads. So, if you use put with UFCS, you tend to run into
problems if you do anything other than put a single element of the exact
type at a time, whereas the free function handles more cases (even if they
ultimately end up calling that member function with a single argument of the
exact type). We probably shouldn't have had the free function and the member
function share the same name.

> Is there something I'm not seeing as to why UFCS is not part of
> the overload set, and is there a way other than not using UFCS to
> prevent the silent hijacking?

If it were part of the overload set, then you have problems calling member
functions, particularly because there is no way to call a member function
other than with UFCS, whereas you can call free functions without UFCS, and
if you _really_ want to be sure that a very specific function is called,
then you can even give its entire module path when calling it. When UFCS was
introduced, it was decided that having member functions always win out would
cause the fewest problems.

- Jonathan M Davis



UFCS in generic libraries, silent hijacking, and compile errors.

2018-03-10 Thread aliak via Digitalmars-d-learn
What are the recommended guidelines for using/not using UFCS in 
writing generic libraries?


I ask because if you have an internal generic free function that 
you use on types in a generic algorithm via ufcs, then everything 
works fine until the type being operated on has a member function 
with a similar name.


If the signature matches the free function then the member 
function is called instead of the free function (silently) and if 
the signature does not match then you get a compiler error.


I.e.:

auto identity(T)(T t) { return t; }
auto fun(T)(T t) {
return t.identity;
}

void main() {
fun(3).writeln; // ok, print 3

struct S1 {}
fun(S1()).writeln; // ok, prints S1()

struct S2 { int identity() { return 77; } }
fun(S2()).writeln; // silent hijack, prints 77

struct S3 { int identity(int i) { return i + 2; } }
fun(S3()).writeln; // compile error
}

So the problem is that fun wants to use a utility function that 
it knows about, but it turns out that T can hijack that internal, 
private, utility if you use ufcs.


So basically, it seems like ufcs is fun until it doesn't work, 
and it's not really obvious that you can run in to these problems 
with ufcs.


I feel like the last case where it's a compilation error should 
maybe be ok though, since the function being called is actually 
undefined so ufcs should kick in. The problem as I understand it 
is that ufcs is not part of an overload set. Making it part of it 
would not prevent the silent hijack, but would remove the 
compilation problem.


Is there something I'm not seeing as to why UFCS is not part of 
the overload set, and is there a way other than not using UFCS to 
prevent the silent hijacking?


Cheers
- Ali


Re: As many thanks As possible to who crates D and UFCS feature

2017-05-13 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 13 May 2017 at 10:51:09 UTC, k-five wrote:

Okay, and NOW I understood what you are trying to say.
First of all I thought you got mad at me. And I became sad.


My sincere apologies! Always assume the best in people :-) I am 
glad you asked for clarification.



[...] Still I am a beginner and learner.


I am too, and learners we are all.


Thanks anyway.


Welcome.



Re: As many thanks As possible to who crates D and UFCS feature

2017-05-13 Thread k-five via Digitalmars-d-learn

On Saturday, 13 May 2017 at 10:15:34 UTC, Bastiaan Veelo wrote:

On Saturday, 13 May 2017 at 08:23:55 UTC, k-five wrote:

[...]


OK understood.


[...]


I am sorry for expressing myself poorly. What I meant to say is 
that it looked like you can write an interesting article about 
your experience learning and using C++ and learning and using 
D, comparing the two. D could come out of that comparison 
favourably considering 1) how long it takes to learn, 2) how 
much code you need to write, 3) whether there are difficulties 
along the way, and 4) how productive you can be (getting things 
done). I may have been jumping to conclusions, but it could 
still be an interesting read, especially for people that 
consider learning C++ or D. In particular the focus on UFCS is 
interesting, as that can be rather alien to beginners, and 
something you are enthusiastic about.



[...]


Understood.


[...]


Posting it here is fine. You could also have posted in the 
general forum, as it is more of a compliment than a question. 
But if you want to write more about your positive experience, 
then a blog article might be nice. It would reach more people, 
and it would maybe help some of them. If you want to do that 
work, then maybe Mike Parker would want to put it on the D 
blog, and help you polish it.


Whatever you decide to do, thanks for sharing your experience 
here :-)


Bastiaan.


On Saturday, 13 May 2017 at 10:15:34 UTC, Bastiaan Veelo wrote:

--

Okay, and NOW I understood what you are trying to say.
First of all I thought you got mad at me. And I became sad. 
Since; I tell this really that I was so happy about the code in 
D, that I would want to share my happiness here with others and 
not expressing myself. Still I am a beginner and learner.

Thanks anyway.



Re: As many thanks As possible to who crates D and UFCS feature

2017-05-13 Thread Bastiaan Veelo via Digitalmars-d-learn

On Saturday, 13 May 2017 at 08:23:55 UTC, k-five wrote:

On Friday, 12 May 2017 at 20:53:56 UTC, Bastiaan Veelo wrote:

Is it safe to say that these 40 lines of D do the same as your 
324 lines of C++ [1]?


No. I cannot say that.
Since this is not a full port of renrem in C++ to D. It was 
just an example in D, nothing else.


OK understood.

This, and your comments on the difficulties of building renrem 
[2] versus doing "rdmd", and the steepness of the learning 
curve (1 year C++ vs 2 weeks D), and the productivity (2 hours 
D vs ?? C++)


I am not sure about understanding your purpose correctly.


I think are plenty material for a nice little blog.


Which English Grammar rule is used here? Sorry but I do not 
know!

are: linking verb after
think: main verb and subject!


I am sorry for expressing myself poorly. What I meant to say is 
that it looked like you can write an interesting article about 
your experience learning and using C++ and learning and using D, 
comparing the two. D could come out of that comparison favourably 
considering 1) how long it takes to learn, 2) how much code you 
need to write, 3) whether there are difficulties along the way, 
and 4) how productive you can be (getting things done). I may 
have been jumping to conclusions, but it could still be an 
interesting read, especially for people that consider learning 
C++ or D. In particular the focus on UFCS is interesting, as that 
can be rather alien to beginners, and something you are 
enthusiastic about.


I just want to say D is easy to learn and use; that is it. I 
have no arguing about which Language is better no not. Of 
course that program with C++, took me 1 month until it got 
ready, but in 2 days I could ported to D, since I had the 
already experience of implementing it.


Understood.

Mike Parker runs the D blog, and I think he might be 
interested. No need to worry about the english language, you 
are safe with Mike. I'll see if I can get you his attention.


Sorry ... Still could not understand ... except you may want me 
to put such post in D blog not here, and in this case, your are 
right, the best way for such examples is on a blog or similar. 
Sorry for posting it here.


Posting it here is fine. You could also have posted in the 
general forum, as it is more of a compliment than a question. But 
if you want to write more about your positive experience, then a 
blog article might be nice. It would reach more people, and it 
would maybe help some of them. If you want to do that work, then 
maybe Mike Parker would want to put it on the D blog, and help 
you polish it.


Whatever you decide to do, thanks for sharing your experience 
here :-)


Bastiaan.


Re: As many thanks As possible to who crates D and UFCS feature

2017-05-13 Thread k-five via Digitalmars-d-learn

On Friday, 12 May 2017 at 20:53:56 UTC, Bastiaan Veelo wrote:

Is it safe to say that these 40 lines of D do the same as your 
324 lines of C++ [1]?


No. I cannot say that.
Since this is not a full port of renrem in C++ to D. It was just 
an example in D, nothing else.


This, and your comments on the difficulties of building renrem 
[2] versus doing "rdmd", and the steepness of the learning 
curve (1 year C++ vs 2 weeks D), and the productivity (2 hours 
D vs ?? C++)


I am not sure about understanding your purpose correctly.


I think are plenty material for a nice little blog.


Which English Grammar rule is used here? Sorry but I do not know!
are: linking verb after
think: main verb and subject!
---
I just want to say D is easy to learn and use; that is it. I have 
no arguing about which Language is better no not. Of course that 
program with C++, took me 1 month until it got ready, but in 2 
days I could ported to D, since I had the already experience of 
implementing it.



Mike Parker runs the D blog, and I think he might be 
interested. No need to worry about the english language, you 
are safe with Mike. I'll see if I can get you his attention.


Sorry ... Still could not understand ... except you may want me 
to put such post in D blog not here, and in this case, your are 
right, the best way for such examples is on a blog or similar. 
Sorry for posting it here.





Re: As many thanks As possible to who crates D and UFCS feature

2017-05-12 Thread Nicholas Wilson via Digitalmars-d-learn

On Friday, 12 May 2017 at 21:26:01 UTC, Bastiaan Veelo wrote:

On Friday, 12 May 2017 at 15:24:52 UTC, k-five wrote:
A full version that I just added to my gitgub: 
https://github.com/k-five/dren


You may like getopt[1] for command line argument parsing.

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


see also
https://blog.thecybershadow.net/2014/08/05/ae-utils-funopt/
https://github.com/CyberShadow/ae/blob/master/utils/funopt.d



Re: As many thanks As possible to who crates D and UFCS feature

2017-05-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 12 May 2017 at 15:24:52 UTC, k-five wrote:
A full version that I just added to my gitgub: 
https://github.com/k-five/dren


You may like getopt[1] for command line argument parsing.

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


Re: As many thanks As possible to who crates D and UFCS feature

2017-05-12 Thread Bastiaan Veelo via Digitalmars-d-learn

On Friday, 12 May 2017 at 15:24:52 UTC, k-five wrote:

On Friday, 12 May 2017 at 11:10:01 UTC, k-five wrote:
I was waiting for a stable version of C++17 ( standard library 
) to add some features of fileSystem in C++17 to my program 
that wants to iterate through all files in a directory 
recursively.


I was thinking how could I do for implementing that and add it 
to my program.


Now after starting to learn D ( nearby 2 weeks so far ). I can 
do it in 6 lines!


void main( string[] args ){

	string[] all_file_name =  dirEntries( ".", SpanMode.depth, 
false )
 .filter!( file => !file.name.matchFirst( regex( args[ 
1 ] ) ).empty() )
 .filter!( file => ( args[ 2 ] == "-f" || args[ 2 ] == 
"-d"  ? ( args[ 2 ] == "-f" ? !file.isDir : !file.isFile ) : ( 
!file.isSymlink ) ) )

 .map!( file => file.name )
 .array;
foreach( string item; all_file_name ) writeln( item );

}

./bin-file '[A-Z]$' -f   ---> print all files that are matched 
against [A-Z]$


./bin-file '[A-Z]$' -d   ---> print all directory that are 
matched against [A-Z]$


./bin-file '[A-Z]$' "anything-else"  ---> print both files and 
directory that are matched against [A-Z]$


I am so happy since after more than one year practicing in C++ 
and putting a collection more than 2000 examples of C++ on my 
github, I was not sure I could do it in 6 lines.


May it is a Spam but I think it is worth it.


--

May it has worth it to be an example on how great D is, in 
somewhere like, in the tour section or std.file or std.regex to 
attract others.


A full version that I just added to my gitgub: 
https://github.com/k-five/dren


Is it safe to say that these 40 lines of D do the same as your 
324 lines of C++ [1]? This, and your comments on the difficulties 
of building renrem [2] versus doing "rdmd", and the steepness of 
the learning curve (1 year C++ vs 2 weeks D), and the 
productivity (2 hours D vs ?? C++) I think are plenty material 
for a nice little blog.


Mike Parker runs the D blog, and I think he might be interested. 
No need to worry about the english language, you are safe with 
Mike. I'll see if I can get you his attention.


[1] https://github.com/k-five/renrem
[2] https://github.com/k-five/renrem/blob/master/src/README.md
[3] https://dlang.org/blog/


Re: As many thanks As possible to who crates D and UFCS feature

2017-05-12 Thread k-five via Digitalmars-d-learn

On Friday, 12 May 2017 at 11:10:01 UTC, k-five wrote:
I was waiting for a stable version of C++17 ( standard library 
) to add some features of fileSystem in C++17 to my program 
that wants to iterate through all files in a directory 
recursively.


I was thinking how could I do for implementing that and add it 
to my program.


Now after starting to learn D ( nearby 2 weeks so far ). I can 
do it in 6 lines!


void main( string[] args ){

	string[] all_file_name =  dirEntries( ".", SpanMode.depth, 
false )
 .filter!( file => !file.name.matchFirst( regex( args[ 
1 ] ) ).empty() )
 .filter!( file => ( args[ 2 ] == "-f" || args[ 2 ] == 
"-d"  ? ( args[ 2 ] == "-f" ? !file.isDir : !file.isFile ) : ( 
!file.isSymlink ) ) )

 .map!( file => file.name )
 .array;
foreach( string item; all_file_name ) writeln( item );

}

./bin-file '[A-Z]$' -f   ---> print all files that are matched 
against [A-Z]$


./bin-file '[A-Z]$' -d   ---> print all directory that are 
matched against [A-Z]$


./bin-file '[A-Z]$' "anything-else"  ---> print both files and 
directory that are matched against [A-Z]$


I am so happy since after more than one year practicing in C++ 
and putting a collection more than 2000 examples of C++ on my 
github, I was not sure I could do it in 6 lines.


May it is a Spam but I think it is worth it.


--

May it has worth it to be an example on how great D is, in 
somewhere like, in the tour section or std.file or std.regex to 
attract others.


A full version that I just added to my gitgub: 
https://github.com/k-five/dren


  1   2   3   4   5   >