D as a prototyping language (for C/C++ projects)

H. S. Teoh hsteoh at quickfur.ath.cx
Wed Feb 27 12:12:02 PST 2013


On Wed, Feb 27, 2013 at 08:54:21PM +0100, Jacob Carlborg wrote:
> On 2013-02-27 18:35, H. S. Teoh wrote:
> 
> >Not sure who you're referring to here, but the reason reduce probably
> >will not change is because a lot of code relies on the current order
> >of parameters, and deliberately breaking that just for aesthetic
> >(rather than functional) reasons is not a good idea. It would be a
> >different story if the current order of parameters somehow makes it
> >impossible to implement some particular functionality. I agree that
> >perhaps the current situation is not perfect, but at least it's not a
> >complete road blocker.
> 
> That's the problem. Then we will have a language with a slightly
> inconsistent and inconvenient standard library.

Well, given that we have UFCS now, maybe we *do* want to standardize on
the range always being the first argument, so that UFCS chaining always
works.  I'm OK to have reduce change the order of arguments... but given
the amount of code it will break, I doubt it will get in. One way is to
introduce the new version under a different name and deprecate "reduce".

I'm not the person you have to convince, though; it's Jonathan or Andrei
who will decide whether to accept this change.


> >Isn't that the same as:
> >
> >	map!((obj x) { doSomething(x); return x; })(range)
> >
> >?
> >
> >I know it's not as pretty, but at least it's possible.
> 
> No it's not the same thing. "map" expects a range and returns a new
> range. "map" will pass each element from the range to the delegate
> and then return a new range of all elements returned for each call
> to the delegate.
> 
> "tap" on the other hand expects an object or value. It will then
> pass the object to the delegate and then return the object. Note
> that it doesn't return whats returned from the delegate. It will
> always return the object passed to "tap".

Oh I get it now. So basically it's a wrapper around functions to make
UFCS chaining possible?


> The most basic, non-templated implementation of "tap" would look like
> this:
> 
> Object tap (alias func) (Object o)
> {
>     func(o);
>     return o;
> }

What would a templated version add to this functionality?


> class Point
> {
>     int x;
>     int y;
> }
> 
> Point createPoint ()
> {
>     return (new Point).tap!((p) { p.x = 3; p.y = 4 });
> }

I guess I'm skeptical about the value of using tap in this context,
since you could just call the function on the object, then set its
values, then return it. So this is just syntactic sugar.

But I guess I can see some use cases where you're chaining a bunch of
stuff inside nested function calls, then tap might become convenient:

	return map!myFunc(zip(r1, [
		new X().tap!myFunc2(),
		new X().tap!myFunc2()
	]));

Which can be unpacked into linear code, but you would would need a bunch
of temporary variables to hold the intermediate results.


> >Again, my point was not that it's a bad idea to have isBlank. My point
> >was that if you add isBlank, then isPresent is redundant, and I would
> >argue even harmful. The best APIs are minimal ones, that provide all
> >*necessary* primitives with minimal overlap between them.
> 
> OK, then it was a misunderstanding, my bad. But with this philosophy
> it will not be as easy create quick scripts compared to scripting
> languages. This the original question, how to improve that in D.
[...]

I disagree with this point. Writing !isBlank is just as easy as writing
isPresent (in fact, a few characters less). I don't see how this helps
with writing scripts faster.


T

-- 
Answer: Because it breaks the logical sequence of discussion. / Question: Why is top posting bad?


More information about the Digitalmars-d mailing list