Steve Yegge's rant on The Next Big Language

Daniel Keep daniel.keep.lists at gmail.com
Tue Mar 13 21:06:25 PDT 2007



Vassily Gavrilyak wrote:
> Strange, for me inferring RETURN type is much more difficult then argument type, 
> and D already do exactly this.  
> Arguments types are already declared, in declaration of map
> R[] map(T[] arr, R delegate(T) fun);
> 
> From here it is clear that there is one argument, and its type is T for array of T's.
> But probably some D features will disallow such simple kind of inference.
> Inferring type R from above example seems much more complicated - 
> you need to look at the delegate code and find the return type.

See, the way I *think* DMD does it is that it goes from the inner-most
expression out.  So at the very inner-most level, we've got the
delegate.  It starts off by getting the type of the arguments, since we
need to know these to make sense of the body.  All good.  We then have
"return a>b".  Well, we know a and b, so the result of this is obviously
a bool.  We go to check the return type and... it's missing.  Hmm, well,
let's just fix it to bool.  Alright--delegate's done.

Now we come to the map call.  We're given an argument that's int[], so T
is obviously int.  We're given a delegate of type bool
delegate(int,int), so R is obviously bool.  Easy.

If we switch it around, it becomes messier: we need to do the type
inference for the call to map BEFORE we work out what the type of the
delegate is.  But we can't work out all the types, since we need to know
the type of the delegate to get R.  So we end up with the types of map
depending on the delegate, and the types on the delegate depending on
map.  Where do you start?

The obvious answer to this is to make the whole AST lazily-evaluated,
but I like Walter, and I think it's important for people to go outside
once in a while :P

>> Whoa, now *that* is nasty.  Quick: is foo(a,b=>a>b) a delegate of two
>> arguments or one?  What if a is declared outside the scope; which is it
> Hmm, for me it looks simple :-)
> It's a shortcut for delegate (int a, int b){return a>b;}
> It's the same as lazy  3+2  is just a shortcut for (void){return 3+2;}, but with parameters.
> From expanded version it is clear that a and b are local arguments and normal D rules 
> of name resolution is applied. (well, I do not know the exact rules, but it seems 
> as it will be error having the same variable name upper in the scope).
> Another similar example of already existing type inference is 
> foreach(i, v; arr)
> Here i and v are inferred from enumerated collection type, and map is actually the same
> arr.map((i, v)=>v+v);
>
> Hmm, but you are right with your question, it seems that parenthesis are mandatory 
> because otherwise it will be impossible to differentiate how many arguments needed.
> So the correct version will look like
> auto sorted = sort(arr,  (a,b) => a<b );

I just wanted to point out that the syntax is wildly different from
anything else in D.  The advantage of the current syntax, is that it
*looks* like some kind of function... it's got the parenthesised
argument list and the curly-brace body.

I see "=>" and immediately think of maps (er, the associative-array kind.)

Of course, the above syntax is also much shorter for single expressions.

>> *groans*  My brain hurts just trying to think about it >_<
> Ouch, I'm sorry for this. You give me a wonderful functools.d and I hurt your brain 
> in response. Never wanted such thing to happen. 
> But that are actual examples of how I am currently using functools.d :-).
> Many thanks for this lib, it helps me a lot.

You're very welcome!  I'm overjoyed to hear that someone is actually
using it!

> And that was actual example of C# 3.0 syntax.

I know; I always preferred Nemerle, tho :P  You wanna talk about
type-inference, go check that one out!

> Actually they implemented comprehensions too, but with somewhat strange "SQL-like"
> syntax. So my example with such syntax will look something like:
> var res = FROM [1,2,3] AS x SELECT x+x WHERE x<2 ORDER BY x;
> It's probably more readable but that's totally different language, no spirit of C here.

I think that they started developing LINQ because people wanted list
comprehensions, but instead of taking their cues from Haskell or
Python... they used SQL.  It's debatable as to whether that was a good
idea or not; I'll just say that I prefer Haskell/Python style list
comprehensions :)

> To conclude - D needs parametrized lazy arguments and more aggressive type inference. 
> It will cover most syntax sugar issues with array comprehensions and much more, 
> because syntax will not be restricted.
> Example I actually use often:
> Given an array of people build an associative array with name as a key;
> Person[char[]] peopleByName = people.hashBy((person)=>person.name);

With enough semantic analysis, I imagine you could get D to do anything.
  I agree, it *would* be nice to have, and being able to write shorter
lambda functions is always nice.  I wouldn't say it "needs" them,
though: I'd prefer to see more features that really honestly *can't* be
done at the moment added (like compile-time function evaluation or
better compile-time reflection) before incremental improvements like that.

Anyway, that's just my opinion, for what that's worth :P

I'll go now, I think I've started rambling again.

	-- Daniel

-- 
Unlike Knuth, I have neither proven or tried the above; it may not even
make sense.

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D
i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/



More information about the Digitalmars-d-announce mailing list