Re: How To: Passing curried functions around

2015-09-12 Thread Bahman Movaqar via Digitalmars-d-learn

On Friday, 11 September 2015 at 21:06:32 UTC, Ali Çehreli wrote:

On 09/11/2015 02:04 PM, Ali Çehreli wrote:

The same keyword has a different use with
templates:


And the official documentation:

  http://dlang.org/template.html#TemplateAliasParameter



Thanks again!


Re: How To: Passing curried functions around

2015-09-11 Thread Ali Çehreli via Digitalmars-d-learn

On 09/06/2015 12:05 PM, Bahman Movaqar wrote:
>  alias bool function(int n) validator_t;

There is the relatively newer alias syntax which is more intuitive:

alias Validator = bool function(int n);

>  bool isEven(int n) { ... }
>  bool isPrime(int n) { ... }
>  /**
>   * keeps asking for an int from the user until it passes
>   * the given validator.
>   */
>  int readInt(string prompt, validator_t validator) { ... }
>
>  // in part B of the application which knows nothing about part A
>  // -
>  /**
>   * does something that involves reading an integer from input
>   */
>  void foo(intReader_t reader) { ... }
>
> I'm trying to pass curried versions of `readInt` to `foo`.
> Obviously, I don't wish part B to know about the details of a "reader"
> nor I'd like to pass `prompt` and `validator` to `foo` (this really
> doesn't concern `foo` at all).
>
> I see that the solution is using `partial` from `std.functional`; for
> example:
>
>  partial!(partial!(readInt, "Enter an integer:"), )
>
> However, I'm not sure if this is correct

That does not compile because partial takes the function arguments as 
'value template parameters'. Unfortunately, a function pointer like 
 cannot be 'value template parameters'; only fundamental types 
and strings can... So, 'partial' is not an option for this problem.


> (let alone idiomatic!)

Idiomatic D uses templates and passes behavior in the form of 'alias 
template parameters.' Alias template parameters are the convenient way 
of allowing anything that is callable, not just functions. For example, 
foo() would be much more useful if it allowed a delegate or a class 
object that has an overloaded opCall() operator.


> and even
> if this is the correct way of currying `readInt`, what should be the
> signature of `foo`?

I think 'int delegate()' would do because all foo needs is a function 
that returns an int.


The idiomatic way is to leave it as a template parameter. However, this 
has the problem of making each instantiation of the foo template a 
different type, making them incompatible to be elements of the same array:


[ &(foo!myReader), &(foo!yourReader) ]  // <-- compilation error

One solution is to do what std.parallelism.task does: to provide both a 
foo template and another foo function that takes an 'int delegate()':


  http://ddili.org/ders/d.en/parallelism.html

(Search for "The task function above has been specified as a template 
parameter" on that page.)


> I'd appreciate any help/hint on this.

Here is a solution:

import std.stdio;

bool isEven(int n) {
return !(n % 2);
}

int readValidInt(alias validator)(string prompt) {
while (true) {
int i;
write(prompt);
readf(" %s", );
if (validator(i)) {
return i;
} else {
writeln("Sorry, that's not acceptable");
}
}
}

void foo(alias reader)() {
reader();
}

void main() {
auto reader = () => readValidInt!isEven("Enter an integer: ");

foo!reader();
}

You can add template constraints to make the code easier to use.

Ali



Re: How To: Passing curried functions around

2015-09-11 Thread Ali Çehreli via Digitalmars-d-learn

On 09/11/2015 02:41 AM, Bahman Movaqar wrote:
> On Friday, 11 September 2015 at 06:14:18 UTC, Ali Çehreli wrote:
>> partial takes the function arguments as 'value template parameters'.
>> Unfortunately, a function pointer like  cannot be 'value
>> template parameters'; only fundamental types and strings can... So,
>> 'partial' is not an option for this problem.
>
> Ah...now I understand the mysterious compiler errors.

I was wrong there: 'partial' does take its arguments as alias template 
parameters but it still doesn't work probably because of a compiler or 
language issue:


import std.functional;

alias Validator = bool function(int);

bool condition(int)
{
return true;
}

void foo(Validator validator)
{
validator(42);
}

void main()
{
alias f = partial!(foo, condition);// <-- ERROR
}

/usr/include/dmd/phobos/std/functional.d(662): Error: function 
deneme.condition (int _param_0) is not callable using argument types ()
/usr/include/dmd/phobos/std/functional.d(662): Error: cannot return 
non-void from void function


I wouldn't expect an actual call for that line of code but the compiler 
thinks that there is a call to condition() without a parameter. (This 
may be related to a syntax issue caused by no-parameter functions being 
called without parentheses.)


>> Idiomatic D uses templates and passes behavior in the form of 'alias
>> template parameters.' Alias template parameters are the convenient way
>> of allowing anything that is callable, not just functions. For
>> example, foo() would be much more useful if it allowed a delegate or a
>> class object that has an overloaded opCall() operator.
>
> True.  I guess I was just pushing D functions too far.

Not necessarily. You can do the same thing with function pointers as 
well but I don't think 'partial' has much to offer over a lambda. I am 
guessing that partial predates lambdas. (?)


>>   http://ddili.org/ders/d.en/parallelism.html
>>
>> (Search for "The task function above has been specified as a template
>> parameter" on that page.)
>
> Actually, I *am* using your book (which is, by the way, very well
> written) plus the language specs to learn D.  However, that section yet
> too advance for me to touch :-)
>
>> import std.stdio;
>>
>> bool isEven(int n) {
>> return !(n % 2);
>> }
>>
>> int readValidInt(alias validator)(string prompt) {

readValidInt() is a function template that takes two information:

1) The validator as its alias template parameter. alias template 
parameter allows it to work with anything that can be called.


2) The prompt as its function parameter.

>> while (true) {
>> int i;
>> write(prompt);
>> readf(" %s", );
>> if (validator(i)) {
>> return i;
>> } else {
>> writeln("Sorry, that's not acceptable");
>> }
>> }
>> }

The should be obvious.

>> void foo(alias reader)() {
>> reader();
>> }

Another function template that takes a callable entity and calls it.

>> void main() {
>> auto reader = () => readValidInt!isEven("Enter an integer: ");

The syntax above creates a lambda with this definition: Call 
readValidInt!isEven with the string argument "Enter an integer: ".


>> foo!reader();

foo takes that lambda. When foo eventually calls the lambda, 
readValidInt!isEven("Enter an integer: ") will be called.


>> }
>>
>> You can add template constraints to make the code easier to use.
>
> Clean one!  Even though I don't know what's going behind the scenes, I
> can easily read and understand it.
>
> Thanks for the help.

Ali



Re: How To: Passing curried functions around

2015-09-11 Thread Bahman Movaqar via Digitalmars-d-learn

On Friday, 11 September 2015 at 06:14:18 UTC, Ali Çehreli wrote:

On 09/06/2015 12:05 PM, Bahman Movaqar wrote:
>  alias bool function(int n) validator_t;

There is the relatively newer alias syntax which is more 
intuitive:


alias Validator = bool function(int n);


Great.  This is easily read by my eyes.

partial takes the function arguments as 'value template 
parameters'. Unfortunately, a function pointer like  
cannot be 'value template parameters'; only fundamental types 
and strings can... So, 'partial' is not an option for this 
problem.


Ah...now I understand the mysterious compiler errors.

Idiomatic D uses templates and passes behavior in the form of 
'alias template parameters.' Alias template parameters are the 
convenient way of allowing anything that is callable, not just 
functions. For example, foo() would be much more useful if it 
allowed a delegate or a class object that has an overloaded 
opCall() operator.


True.  I guess I was just pushing D functions too far.


> and even
> if this is the correct way of currying `readInt`, what should
be the
> signature of `foo`?

I think 'int delegate()' would do because all foo needs is a 
function that returns an int.


That's correct.  I realised this subtle point later on, but had 
already switched to a `struct`y approach.




The idiomatic way is to leave it as a template parameter. 
However, this has the problem of making each instantiation of 
the foo template a different type, making them incompatible to 
be elements of the same array:


[ &(foo!myReader), &(foo!yourReader) ]  // <-- compilation error

One solution is to do what std.parallelism.task does: to 
provide both a foo template and another foo function that takes 
an 'int delegate()':


  http://ddili.org/ders/d.en/parallelism.html

(Search for "The task function above has been specified as a 
template parameter" on that page.)


Actually, I *am* using your book (which is, by the way, very well 
written) plus the language specs to learn D.  However, that 
section yet too advance for me to touch :-)



import std.stdio;

bool isEven(int n) {
return !(n % 2);
}

int readValidInt(alias validator)(string prompt) {
while (true) {
int i;
write(prompt);
readf(" %s", );
if (validator(i)) {
return i;
} else {
writeln("Sorry, that's not acceptable");
}
}
}

void foo(alias reader)() {
reader();
}

void main() {
auto reader = () => readValidInt!isEven("Enter an integer: 
");


foo!reader();
}

You can add template constraints to make the code easier to use.


Clean one!  Even though I don't know what's going behind the 
scenes, I can easily read and understand it.


Thanks for the help.




Re: How To: Passing curried functions around

2015-09-11 Thread Bahman Movaqar via Digitalmars-d-learn

On Friday, 11 September 2015 at 18:39:15 UTC, Ali Çehreli wrote:

>> import std.stdio;
>>
>> bool isEven(int n) {
>> return !(n % 2);
>> }
>>
>> int readValidInt(alias validator)(string prompt) {

readValidInt() is a function template that takes two 
information:


1) The validator as its alias template parameter. alias 
template parameter allows it to work with anything that can be 
called.


I read "alias and with" chapter of the book to understand this 
but couldn't find any such use for `alias` there.  Does using 
`alias` instead of a type makes the parameter a `callable`?




Re: How To: Passing curried functions around

2015-09-11 Thread Ali Çehreli via Digitalmars-d-learn

On 09/11/2015 01:07 PM, Bahman Movaqar wrote:
> On Friday, 11 September 2015 at 18:39:15 UTC, Ali Çehreli wrote:
>> >> import std.stdio;
>> >>
>> >> bool isEven(int n) {
>> >> return !(n % 2);
>> >> }
>> >>
>> >> int readValidInt(alias validator)(string prompt) {
>>
>> readValidInt() is a function template that takes two information:
>>
>> 1) The validator as its alias template parameter. alias template
>> parameter allows it to work with anything that can be called.
>
> I read "alias and with" chapter of the book to understand this but
> couldn't find any such use for `alias` there.  Does using `alias`
> instead of a type makes the parameter a `callable`?

Sorry for the confusion. :) The same keyword has a different use with 
templates:



http://ddili.org/ders/d.en/templates_more.html#ix_templates_more.alias,%20template%20parameter

Ali



Re: How To: Passing curried functions around

2015-09-11 Thread Ali Çehreli via Digitalmars-d-learn

On 09/11/2015 02:04 PM, Ali Çehreli wrote:

The same keyword has a different use with
templates:


And the official documentation:

  http://dlang.org/template.html#TemplateAliasParameter

Ali



Re: How To: Passing curried functions around

2015-09-07 Thread Bahman Movaqar via Digitalmars-d-learn

On Monday, 7 September 2015 at 03:55:01 UTC, Meta wrote:
The name validator_t is not idiomatic in D. Something like 
ValidatorFun should be preferred. Same for intReader_t; 
ReadIntFun is probably preferred, or even IntReader (but that 
would imply that it's a struct/class in my mind).


Noted. Thanks.

As for the actual use of partial, it's perfectly fine and 
idiomatic to use.


Good. Now the questions is what should be the signature of the 
receiving functions if I'm going to pass the (double) curried 
function around?


For example, considering the original piece of code, if I do

alias partial!(partial!(readInt, "Enter an integer:"), 
) ReaderFun;


is the following a valid signature for `foo`, to which I'll pass 
a `ReaderFun`?


void foo((int delegate() readerFun)



Re: How To: Passing curried functions around

2015-09-06 Thread Meta via Digitalmars-d-learn
The name validator_t is not idiomatic in D. Something like 
ValidatorFun should be preferred. Same for intReader_t; 
ReadIntFun is probably preferred, or even IntReader (but that 
would imply that it's a struct/class in my mind).


As for the actual use of partial, it's perfectly fine and 
idiomatic to use.


Re: How To: Passing curried functions around

2015-09-06 Thread welkam via Digitalmars-d-learn

Now its clearer to me. You want delegates
http://wiki.dlang.org/Function_literals




How To: Passing curried functions around

2015-09-06 Thread Bahman Movaqar via Digitalmars-d-learn
I'm just learning D, so please bear with me if I'm asking 
something naive.


Consider the following code skeleton:

// in part A of the application...
// 
-

alias bool function(int n) validator_t;
bool isEven(int n) { ... }
bool isPrime(int n) { ... }
/**
 * keeps asking for an int from the user until it passes
 * the given validator.
 */
int readInt(string prompt, validator_t validator) { ... }

// in part B of the application which knows nothing about 
part A
// 
-

/**
 * does something that involves reading an integer from input
 */
void foo(intReader_t reader) { ... }

I'm trying to pass curried versions of `readInt` to `foo`.
Obviously, I don't wish part B to know about the details of a 
"reader" nor I'd like to pass `prompt` and `validator` to `foo` 
(this really doesn't concern `foo` at all).


I see that the solution is using `partial` from `std.functional`; 
for example:


partial!(partial!(readInt, "Enter an integer:"), )

However, I'm not sure if this is correct (let alone idiomatic!) 
and even if this is the correct way of currying `readInt`, what 
should be the signature of `foo`?


I'd appreciate any help/hint on this.



Re: How To: Passing curried functions around

2015-09-06 Thread Bahman Movaqar via Digitalmars-d-learn

On Sunday, 6 September 2015 at 19:22:41 UTC, welkam wrote:
I dont know much about functional programming, but what stops 
you defining


int readInt(string prompt, validator_t validator) { ... }

as a free standing function and just call it from both parts of 
your code? What is the benefit of indirection that you create 
when passing function pointer?


Nothing specific to FP here. I simply do not want to share the 
details of reading an integer with part B.


Imagine the same thing done with classes:

// part A
//
class IntReader {
   string prompt;
   validator_t validator;

   int read() const { ... }
}

// part B
//
auto ir = new IntReader(...);
foo(ir);

This way, all `foo` needs to know is calling `read` to get an 
integer. I'm trying to achieve the same thing here with 
functions, if possible.