Code Monkey home page Code Monkey logo

Comments (19)

DartBot avatar DartBot commented on August 28, 2024 1

This comment was originally written by [email protected]


Hi,

Thanks for your response. The important thing is I have to emphasise is, the feature I'm asking for is extension methods, not LINQ. LINQ is built on top of extension methods, but is a different and far more involved feature, that brings in an inline query syntax and translation of expression trees into SQL.

Extension methods are far simpler, and solve a far more generic problem. I would suggesting reading around a little more on C# extension methods to get a better understanding of them, but I will do my best to explain here:

Extension methods are a way of solving a problem that manifests in Java, namely writing library code that can be used to operate on interfaces, particularly collections, in a fluent and convenient way. For example, writing a 'first' method that returns the first value in an iterator (IEnumerator in C#) that fulfils a supplied predicate lambda. Java's (and it seem's Dart's) method of doing this is to have helper classes with names like 'Collections' that contain static methods to operate on instances of their similarly-named interface.

So, our 'first' method in a traditional Java-esque language might look something like this:

public class Iterators {
   public static T first<T>(Iterator<T> iterator, Predicate<T> filter) {
      while (iterator.hasNext()) {
         T next = iterator.next();

         if (filter.apply(next)) {
            return next;
         }
      }

      return null;
   }
}

There can be lots more of these methods to support operations like 'where' (e.g. all values that match a predicate), 'orderBy', to return an iterator ordered by a particular field of the object, 'select' to map all the values of an iterator.

All well and good, but the problem comes when we try and use these methods, even if the language supports lambdas the usage is problematic:

lastName = Iterators.Select(Iterators.orderBy(Iterators.where(dataset.getAllPeople(), (r) => r.getFirstName() == 'Jon'), (r) => r.getAge()), (r) => r.getLastName());

It's verbose, involves a lot of nesting, and it also means the lambdas are split from the name of the operation they apply to.

C# (and Java 8) solved this problem using extension methods. They are syntactic sugar that allows you to declare static methods that can be called on objects as if they belonged to the object itself.

Writing our 'First' method in a C#-esque language wouldn't be much different:

public static class EnumeratorEx {
   public static T First<T>(this IEnumerator<T> enumerator, Predicate<T> predicate) {
      while (enumerator.MoveNext()) {
         if (predicate(enumerator.Current)) {
            return enumerator.Current;
         }
      }
      return default(T);
   }
}

The key is the usage of the 'this' keyword in the method signature, which identifies to the compiled that this is an extension method, intended to extend instances of IEnumerator<T>. While the declaration isn't much different, the usage is:

lastName = dataset.GetAllPeople()
                  .Where(p => p.FirstName == 'Jon'),
                  .OrderBy(p => p.Age)
                  .Select(p => p.LastName)

The syntax is much shorter, cleaner and more fluent and functional. It lets you concentrate on what is happening, rather than how it's happening. It's no surprise that Java is adopting virtually the same mechanisms for Java 8. For JavaScript, a similar solution for collections is provided by UnderscoreJS, although that requires explicitly wrapping and chaining objects using a global constructor function.

The thing is, working with and transforming collections of data is one of the most commonplace and important tasks application developers do. Getting Dart right in this regard is absolutely vital if you want to make it an efficient and enjoyable language to work with. C# extension methods offer the best syntax I've seen for doing this well in an imperative language.

Now, maybe you guys have your own ideas how to achieve this, and will come out with something that will blow all this away. But I worry from what I've read here, for example conflating LINQ with extension methods, that you haven't really thought much about it or grasped how important it is.

You say you want to make a better language than JavaScript. Well, the areas where you need to improve on JavaScript aren't things like inheritance. App developers should rarely need to use inheritance if the runtime framework is good enough. But they will need to manipulate collections, observe object mutations, perform data-binding, and getting the mechanisms right for these things is absolutely vital. Copying what Java did ten years ago is not getting it right.

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Oh, and obviously I was going to write a 'exists' method example first, then changed it to 'first', but forgot to update the return types. But I'm sure you still get the idea...

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Removed Type-Defect label.
Added Type-Enhancement label.

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Added Area-Language, Triaged labels.

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Linq is a language extension, something that is not currently part of the language.

As for the second, there is Isolates that would leverage the processing of the iterator into a separate thread, while you would wait for it to return the value you requested, by your predicate.

Perhaps this is an altogether different programming model as in C# or Java?

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


C#-style extension methods are not the same as LINQ.

from sdk.

gbracha avatar gbracha commented on August 28, 2024

C# extension methods rely on mandatory static typing. That is not an option in Dart.

LINQ like mechanisms can be added to a language by other means. We might consider something in this space down the line.


Added WontFix label.

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Well you could support i when static type is present, c# don't support it on variables of dynamic types either

from sdk.

floitschG avatar floitschG commented on August 28, 2024

Type annotations don't have any influence on the behavior of a program. This is a fundamental property of Dart.

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Why would you need anything more than type annotation for extension methods?

Extension methods are just a really nice syntactic sugar

http://www.hanselman.com/blog/HowDoExtensionMethodsWorkAndWhyWasANewCLRNotRequired.aspx

from sdk.

floitschG avatar floitschG commented on August 28, 2024

One of the fundamental properties of Dart is that type-annotations don't have any effect on the behavior of the program. We thus can't use them for extension methods.

from sdk.

floitschG avatar floitschG commented on August 28, 2024

If the transformation is based on the annotated type of the first parameter, then the optional type has an effect on the program. There would be a difference between:
var a = ...
a.foo();
and
ClassName a = ...
a.foo();

One of Dart's fundamental properties is, that type-annotations don't have any effect on the behavior. These two code samples must behave the same way. Therefore extension methods, as implemented in C#, can't be implemented in Dart.

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Um OK, so don't compile to different behaviour. Just have the compiler make the translation regardless of type, and flag it up as a warning in the static checker if the types don't match.

If you're worried about cases where top level and object bound function names collide, then just have the compiler act as follows...

for call 'a.foo()'
  if there exists top level function 'foo'
    emit 'if (foo.hasFunction('foo') a.foo() else foo(a);'
  else
    emit 'a.foo()';

...or have some kind of TLF targeting operator like a:foo()

The point of this enhancement request was for C# STYLE extension methods, e.g. an equivalent feature not an exact duplication. Obviously there may be requirements for slightly different implementation or usage pattern due to Dart being a different language, it just requires a little bit of thinking about. Given that you released this language and asked for feedback, and here you have some feedback that a number of people are clearly interested in, you seem to be in an awful hurry to mark it WONTFIX.

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Furthermore, if "LINQ like mechanisms can be added to a language by other means. We might consider something in this space down the line." then why are you closing the bug at all? Why not implement it using those "other means" and use this bug to track it/gauge interest in the feature?

from sdk.

jmesserly avatar jmesserly commented on August 28, 2024

FWIW, there's a ES strawman for how to get the same effect in JS:
http://wiki.ecmascript.org/doku.php?id=strawman:scoped_object_extensions

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Deleted my comment from a few hours ago as it was unjustifiably rude and inflammatory. Apologies. Nevertheless, I stand by my opinion that is a perfectly realisable feature and has being prematurely closed.

from sdk.

gbracha avatar gbracha commented on August 28, 2024

Hi Jon,

Missed your previous comment - just as well, I guess. So let me try and explain why I closed the bug, and what to do about it.

The bug was feature request for C# style extension methods. We can't do that, at least literally. I try and keep feature requests narrowly focused because i have found that they tend to meander, touching on various design options/alternatives and features. It becomes very hard to know where the discussion of a given topic is. And having lots of open bugs that may live for a long time is very hard to manage.

So, if we want "support LINQ style functionality" that would be a separate bug, and one which I would be very supportive of. The question is how to do it. There are different mechanisms by which one might achieve that. It is always good to know what problem you want to solve (in this case, uniform, convenient access to data) rather than what solution you are familiar with/fond of. Specific mechanisms don't always carry over from one language to another.

So feel free to open another issue that is more focused on LINQ and less on mechanism.

from sdk.

gbracha avatar gbracha commented on August 28, 2024

Hi Jon,

I know what extension methods are. I know what they are good for. I also know of several other mechanisms in the programming language literature that attempt to solve related problems. Each one behaves a bit differently. I admit I've never seen one I think is satisfactory. Some of these mechanisms depend on static typing (as in C# or Haskell's type classes) some do not (class boxes, selector namespaces).

Those that rely on types are not an option for Dart. Other schemes are essentially research. We are consciously trying to avoid over-innovating. This is a language that will have large numbers of users, not a testbed for cool language experiments. I've done plenty of that.

On the other hand, if a really good scheme comes along, we wouldn't exclude it. We'd want to get experience with it before rushing into it. As a rule, features do not trivially migrate from one language to another.

Finally, if you think we are copying Java you are sorely mistaken. Likewise if you think we have not thought about these issues.

Anyway, thank you for your input.

from sdk.

DartBot avatar DartBot commented on August 28, 2024

This comment was originally written by [email protected]


Further to the above, you seem to basing your objections to this bug on the fact that extension methods are directly transferable, in implementation terms, from C# to Dart due to differences in the typing system. This may be, but I still don't quite understand why that makes an extension methods feature request unreasonable.

Extension methods are a language feature, the same as classical inheritance, properties, mixins, traits, interfaces, etc. If a bug asking for LINQ equivalent function would be reasonable, why is this not?

I am not asking for extension methods to be exactly copied from C#, I am asking for the ability to attach additional behaviour to all instances of classes and interfaces and call them using a fluent syntax. That is all. That is what 'extension methods' essentially is: methods that extend an interface or object. If there is some other, more implementation-agnostic terminology that I should use when referring to the ability, then I will happily do so and raise a new bug using it, but nobody has suggested any. This feature is called Extension Methods in C#, and AFAIK it is called Extension Methods in Java 8 as well.

It definitely is not "LINQ", and it would be far more incorrect for me to raise a bug calling it that.

from sdk.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.