www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Make alias parameter optional?

reply "Robert Rouse" <robert.e.rouse gmail.com> writes:
Is it possible to do something like this?

void foo(T, T2, alias thing)(T a, T2 b) {
   // do stuff with a
   // call b (since b would be a delegate)
   // call thing if thing is given
}

I come from the Ruby world and I'm just playing around to see how 
much I can replicate of the "block" functionality that Ruby has.
Feb 25 2012
parent reply Trass3r <un known.com> writes:
void foo(T, T2, alias thing = (){})(T a, T2 b)
{
	thing();
}

void bar(){}

void main()
{
	foo!(int,int,bar)(1,2);
	foo(1,2);
}
Feb 25 2012
next sibling parent reply "Robert Rouse" <robert.e.rouse gmail.com> writes:
On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:
 void foo(T, T2, alias thing = (){})(T a, T2 b)
 {
 	thing();
 }

 void bar(){}

 void main()
 {
 	foo!(int,int,bar)(1,2);
 	foo(1,2);
 }

Cool. Didn't know you can do that, but I guess it makes sense that it would work that way. The only thing I wish for is if I didn't have to explicitly define what T and T2 were and I could just do foo!(bar)(1,2);
Feb 25 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/25/2012 01:55 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:
 void foo(T, T2, alias thing = (){})(T a, T2 b)
 {
 thing();
 }

 void bar(){}

 void main()
 {
 foo!(int,int,bar)(1,2);
 foo(1,2);
 }

Cool. Didn't know you can do that, but I guess it makes sense that it would work that way. The only thing I wish for is if I didn't have to explicitly define what T and T2 were and I could just do foo!(bar)(1,2);

The following works and is news to me. Apparently template parameters with default values need not be at the end of the template parameter list: void foo(alias thing = (){}, T, T2)(T a, T2 b) { thing(); } void bar(){} void main() { foo!(bar)(1,2); } Ali
Feb 25 2012
parent reply Ary Manzana <ary esperanto.org.ar> writes:
On 2/25/12 7:31 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 22:12:55 UTC, Ali Çehreli wrote:
 On 02/25/2012 01:55 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:
 void foo(T, T2, alias thing = (){})(T a, T2 b)
 {
 thing();
 }

 void bar(){}

 void main()
 {
 foo!(int,int,bar)(1,2);
 foo(1,2);
 }

Cool. Didn't know you can do that, but I guess it makes sense that it would work that way. The only thing I wish for is if I didn't have to explicitly define what T and T2 were and I could just do foo!(bar)(1,2);

The following works and is news to me. Apparently template parameters with default values need not be at the end of the template parameter list: void foo(alias thing = (){}, T, T2)(T a, T2 b) { thing(); } void bar(){} void main() { foo!(bar)(1,2); } Ali

This means that D can simulate Ruby blocks more than I thought. That's pretty awesome. I'm loving D more every day.

How's that like a Ruby block?
Feb 25 2012
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/25/2012 05:04 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote:
 On 2/25/12 7:31 PM, Robert Rouse wrote:


...
 This means that D can simulate Ruby blocks more than I thought. That's
 pretty awesome. I'm loving D more every day.

How's that like a Ruby block?

The D code simulates the following Ruby if you were to make bar print "something" with writeln. def foo(a, b, &block) puts "a is #{a}") b.call yield end f = lambda { puts "good bye" } foo(1, f) { puts "something" } That's what I'm talking about.

I don't know Ruby but from what I've read so far about Ruby blocks, their D equivalents may also be D ranges. Ali
Feb 26 2012
parent reply Jacob Carlborg <doob me.com> writes:
On 2012-02-26 11:03, Ali Çehreli wrote:
 On 02/25/2012 05:04 PM, Robert Rouse wrote:
  > On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote:
  >> On 2/25/12 7:31 PM, Robert Rouse wrote:

 ...

  >>> This means that D can simulate Ruby blocks more than I thought. That's
  >>> pretty awesome. I'm loving D more every day.
  >>
  >> How's that like a Ruby block?
  >
  > The D code simulates the following Ruby if you were to make bar print
  > "something" with writeln.
  >
  > def foo(a, b, &block)
  > puts "a is #{a}")
  > b.call
  > yield
  > end
  >
  > f = lambda { puts "good bye" }
  >
  > foo(1, f) { puts "something" }
  >
  >
  > That's what I'm talking about.
  >

 I don't know Ruby but from what I've read so far about Ruby blocks,
 their D equivalents may also be D ranges.

 Ali

A Ruby block is basically like a delegate in D and has nothing to do with ranges. Ruby: def foo (&block) block.call end foo do p "asd" end D: void foo (void delegate () block) { block(); } void main () { foo({ writeln("asd"); }); foo(() => writeln("asd")); // new lambda syntax } Both examples print "asd". If you want to have a more Ruby looking syntax in D you do some operator overload abuse: struct Block { void delegate (void delegate ()) impl; void opIn (void delegate () block) { impl(block); } } Block foo () { return Block((x) => x()); } void main () { foo in { writeln("asd"); }; } -- /Jacob Carlborg
Feb 26 2012
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 02/26/2012 03:45 AM, Jacob Carlborg wrote:
 On 2012-02-26 11:03, Ali Çehreli wrote:
 On 02/25/2012 05:04 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote:
 On 2/25/12 7:31 PM, Robert Rouse wrote:


...
 This means that D can simulate Ruby blocks more than I thought.



 pretty awesome. I'm loving D more every day.

How's that like a Ruby block?

The D code simulates the following Ruby if you were to make bar print "something" with writeln. def foo(a, b, &block) puts "a is #{a}") b.call yield end f = lambda { puts "good bye" } foo(1, f) { puts "something" } That's what I'm talking about.

I don't know Ruby but from what I've read so far about Ruby blocks, their D equivalents may also be D ranges. Ali

A Ruby block is basically like a delegate in D and has nothing to do with ranges. Ruby: def foo (&block) block.call end foo do p "asd" end D: void foo (void delegate () block) { block(); } void main () { foo({ writeln("asd"); }); foo(() => writeln("asd")); // new lambda syntax } Both examples print "asd". If you want to have a more Ruby looking syntax in D you do some operator overload abuse: struct Block { void delegate (void delegate ()) impl; void opIn (void delegate () block) { impl(block); } } Block foo () { return Block((x) => x()); } void main () { foo in { writeln("asd"); }; }

I see, thanks. The reason I thought about ranges is that the yield statement in the Ruby code above reminded me of Python's generators, and that D's ranges can also take the role of generators. Ali
Feb 26 2012
parent Jacob Carlborg <doob me.com> writes:
On 2012-02-27 00:04, Ali Çehreli wrote:
 On 02/26/2012 03:45 AM, Jacob Carlborg wrote:
  > On 2012-02-26 11:03, Ali Çehreli wrote:
  >> On 02/25/2012 05:04 PM, Robert Rouse wrote:
  >> > On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote:
  >> >> On 2/25/12 7:31 PM, Robert Rouse wrote:
  >>
  >> ...
  >>
  >> >>> This means that D can simulate Ruby blocks more than I thought.
  >> That's
  >> >>> pretty awesome. I'm loving D more every day.
  >> >>
  >> >> How's that like a Ruby block?
  >> >
  >> > The D code simulates the following Ruby if you were to make bar print
  >> > "something" with writeln.
  >> >
  >> > def foo(a, b, &block)
  >> > puts "a is #{a}")
  >> > b.call
  >> > yield
  >> > end
  >> >
  >> > f = lambda { puts "good bye" }
  >> >
  >> > foo(1, f) { puts "something" }
  >> >
  >> >
  >> > That's what I'm talking about.
  >> >
  >>
  >> I don't know Ruby but from what I've read so far about Ruby blocks,
  >> their D equivalents may also be D ranges.
  >>
  >> Ali
  >
  > A Ruby block is basically like a delegate in D and has nothing to do
  > with ranges.
  >
  > Ruby:
  >
  > def foo (&block)
  > block.call
  > end
  >
  > foo do
  > p "asd"
  > end
  >
  > D:
  >
  > void foo (void delegate () block)
  > {
  > block();
  > }
  >
  > void main ()
  > {
  > foo({
  > writeln("asd");
  > });
  >
  > foo(() => writeln("asd")); // new lambda syntax
  > }
  >
  > Both examples print "asd". If you want to have a more Ruby looking
  > syntax in D you do some operator overload abuse:
  >
  > struct Block
  > {
  > void delegate (void delegate ()) impl;
  >
  > void opIn (void delegate () block)
  > {
  > impl(block);
  > }
  > }
  >
  > Block foo ()
  > {
  > return Block((x) => x());
  > }
  >
  > void main ()
  > {
  > foo in {
  > writeln("asd");
  > };
  > }
  >

 I see, thanks. The reason I thought about ranges is that the yield
 statement in the Ruby code above reminded me of Python's generators, and
 that D's ranges can also take the role of generators.

 Ali

"yield" in Ruby is just a way to call a block: def foo yield end def bar (&block) block.call end The second example is a more explicit way of calling a block. Often blocks are used to iterate in Ruby: [3, 4, 5].each do |e| # do something with e end -- /Jacob Carlborg
Feb 27 2012
prev sibling parent Ary Manzana <ary esperanto.org.ar> writes:
On 2/25/12 10:04 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote:
 On 2/25/12 7:31 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 22:12:55 UTC, Ali Çehreli wrote:
 On 02/25/2012 01:55 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:
 void foo(T, T2, alias thing = (){})(T a, T2 b)
 {
 thing();
 }

 void bar(){}

 void main()
 {
 foo!(int,int,bar)(1,2);
 foo(1,2);
 }

Cool. Didn't know you can do that, but I guess it makes sense that it would work that way. The only thing I wish for is if I didn't have to explicitly define what T and T2 were and I could just do foo!(bar)(1,2);

The following works and is news to me. Apparently template parameters with default values need not be at the end of the template parameter list: void foo(alias thing = (){}, T, T2)(T a, T2 b) { thing(); } void bar(){} void main() { foo!(bar)(1,2); } Ali

This means that D can simulate Ruby blocks more than I thought. That's pretty awesome. I'm loving D more every day.

How's that like a Ruby block?

The D code simulates the following Ruby if you were to make bar print "something" with writeln. def foo(a, b, &block) puts "a is #{a}") b.call yield end f = lambda { puts "good bye" } foo(1, f) { puts "something" } That's what I'm talking about.

A Ruby block is much more than a delegate, because you can assign variables outside of the block and even returning from a block returns from the function that invokes it. I don't see how D can accomplish that. Here's some more about it: http://yehudakatz.com/2012/01/10/javascript-needs-blocks/
Feb 27 2012
prev sibling next sibling parent "Robert Rouse" <robert.e.rouse gmail.com> writes:
On Saturday, 25 February 2012 at 22:12:55 UTC, Ali Çehreli wrote:
 On 02/25/2012 01:55 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:
 void foo(T, T2, alias thing = (){})(T a, T2 b)
 {
 thing();
 }

 void bar(){}

 void main()
 {
 foo!(int,int,bar)(1,2);
 foo(1,2);
 }

Cool. Didn't know you can do that, but I guess it makes sense that it would work that way. The only thing I wish for is if I didn't have to explicitly define what T and T2 were and I could just do foo!(bar)(1,2);

The following works and is news to me. Apparently template parameters with default values need not be at the end of the template parameter list: void foo(alias thing = (){}, T, T2)(T a, T2 b) { thing(); } void bar(){} void main() { foo!(bar)(1,2); } Ali

This means that D can simulate Ruby blocks more than I thought. That's pretty awesome. I'm loving D more every day.
Feb 25 2012
prev sibling next sibling parent "Robert Rouse" <robert.e.rouse gmail.com> writes:
On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana wrote:
 On 2/25/12 7:31 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 22:12:55 UTC, Ali Çehreli 
 wrote:
 On 02/25/2012 01:55 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r wrote:
 void foo(T, T2, alias thing = (){})(T a, T2 b)
 {
 thing();
 }

 void bar(){}

 void main()
 {
 foo!(int,int,bar)(1,2);
 foo(1,2);
 }

Cool. Didn't know you can do that, but I guess it makes sense that it would work that way. The only thing I wish for is if I didn't have to explicitly define what T and T2 were and I could just do foo!(bar)(1,2);

The following works and is news to me. Apparently template parameters with default values need not be at the end of the template parameter list: void foo(alias thing = (){}, T, T2)(T a, T2 b) { thing(); } void bar(){} void main() { foo!(bar)(1,2); } Ali

This means that D can simulate Ruby blocks more than I thought. That's pretty awesome. I'm loving D more every day.

How's that like a Ruby block?

The D code simulates the following Ruby if you were to make bar print "something" with writeln. def foo(a, b, &block) puts "a is #{a}") b.call yield end f = lambda { puts "good bye" } foo(1, f) { puts "something" } That's what I'm talking about.
Feb 25 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 2/25/12, Ali =C7ehreli <acehreli yahoo.com> wrote:
 Apparently template parameters
 with default values need not be at the end of the template parameter list

Well it would make variadic templates rather hard to use if this was illega= l: void print(bool pretty =3D false, T...)(T args) { } void main() { print(1, "two", 3.0); }
Feb 25 2012
prev sibling next sibling parent "Robert Rouse" <robert.e.rouse gmail.com> writes:
On Monday, 27 February 2012 at 14:57:56 UTC, Ary Manzana wrote:
 On 2/25/12 10:04 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 23:10:51 UTC, Ary Manzana 
 wrote:
 On 2/25/12 7:31 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 22:12:55 UTC, Ali Çehreli 
 wrote:
 On 02/25/2012 01:55 PM, Robert Rouse wrote:
 On Saturday, 25 February 2012 at 18:54:35 UTC, Trass3r 
 wrote:
 void foo(T, T2, alias thing = (){})(T a, T2 b)
 {
 thing();
 }

 void bar(){}

 void main()
 {
 foo!(int,int,bar)(1,2);
 foo(1,2);
 }

Cool. Didn't know you can do that, but I guess it makes sense that it would work that way. The only thing I wish for is if I didn't have to explicitly define what T and T2 were and I could just do foo!(bar)(1,2);

The following works and is news to me. Apparently template parameters with default values need not be at the end of the template parameter list: void foo(alias thing = (){}, T, T2)(T a, T2 b) { thing(); } void bar(){} void main() { foo!(bar)(1,2); } Ali

This means that D can simulate Ruby blocks more than I thought. That's pretty awesome. I'm loving D more every day.

How's that like a Ruby block?

The D code simulates the following Ruby if you were to make bar print "something" with writeln. def foo(a, b, &block) puts "a is #{a}") b.call yield end f = lambda { puts "good bye" } foo(1, f) { puts "something" } That's what I'm talking about.

A Ruby block is much more than a delegate, because you can assign variables outside of the block and even returning from a block returns from the function that invokes it. I don't see how D can accomplish that. Here's some more about it: http://yehudakatz.com/2012/01/10/javascript-needs-blocks/

Which thing? Delegates can already access variables outside, because that's what they are for.
Feb 27 2012
prev sibling parent "David Nadlinger" <see klickverbot.at> writes:
On Monday, 27 February 2012 at 19:34:45 UTC, Robert Rouse wrote:
 Which thing? Delegates can already access variables outside, 
 because that's what they are for.

The »returning from block returns from outer function« part. Also applies to similar control statements. David
Feb 27 2012