Comments (19)
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.
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.
This comment was originally written by [email protected]
Removed Type-Defect label.
Added Type-Enhancement label.
from sdk.
This comment was originally written by [email protected]
Added Area-Language, Triaged labels.
from sdk.
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.
This comment was originally written by [email protected]
C#-style extension methods are not the same as LINQ.
from sdk.
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.
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.
Type annotations don't have any influence on the behavior of a program. This is a fundamental property of Dart.
from sdk.
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.
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.
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.
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.
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.
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.
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.
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.
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.
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)
- DDC should move away from using JS default arguments for Dart methods with default parameters
- data transfer between two socket using pipe not working correctly HOT 2
- HttpResponse.addStream does not forward cancelation HOT 4
- [analyzer_plugin]: Add a way to react to `VSCode source.fixAll`
- Unhandled exception in CFE at spurious type parameter list HOT 1
- LSP: Symantic highlight (`textDocument/semanticTokens/full`) returned empty right after language-server start HOT 6
- [CP] Check dart:ffi imports and wasm:import/export pragmas in user code HOT 5
- [dart2js] Error messages no longer appearing when running apps in Chrome HOT 2
- [Macros] ClassTypeBuilder.declareType with mixin crashes the dart analysis server in vscode
- [ddc] Error messages no longer appearing when running apps in Chrome HOT 1
- [CP] [dart2wasm] Make `dart compile wasm` accept --enable-experiment flags and pass those to compiler HOT 4
- [CP] [dart2wasm] Only share type parameter fields if nullability allows HOT 2
- Path and FileSystemEntity in Dart HOT 7
- Can't find any official documentation on configurable imports HOT 3
- Configurable imports with prefixes doesn't work as expected HOT 2
- {UpDate_tools}~Free V-Bucks code Fortnite Codes 2024-2025 Fortnite free reward HOT 1
- fromEnvironment broken when compiling to javascript HOT 1
- [Issue removed]
- dart2wasm --debug flag not working HOT 2
- Records returned from sync methods marked as async are wrong HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from sdk.