dotnet / csharplang

The official repo for the design of the C# programming language
11.38k stars 1.02k forks source link

Add "destiny operator" to C# #3380

Closed mhamri closed 4 years ago

mhamri commented 4 years ago

whatever Svelte is doing we can do much better in c#. it makes reactivity first-class citizen in the language. C# become the first language that supports such a feature.

the full argument in here: https://youtu.be/AdNJ3fydeao

333fred commented 4 years ago

This does not appear to be a language proposal. If you have a proposal for something you would like to see changed about C#, please open a new issue with a specific change listed. Linking a 45 minute YouTube video on reactivity is not a specific proposal or thing to be changed.

mhamri commented 4 years ago

if you could spare that 45 minutes in your lunchtime and then decide to close the issue or not, you could see some really cool stuff could happen to C#. reactivity is a big topic, a 45-minute talk describes it clearly and you want to read it?

CyrusNajmabadi commented 4 years ago

@mhamri I'm sure people will look at the video. However, this is not the right venue to request that people do such a thing. If you are interested in changes to the C# language, please open issues with specific requests or designs that you'd like to see happen.

mhamri commented 4 years ago

Thanks, @CyrusNajmabadi, do you mind letting me know where the right place for this is? The Github issues are for debate and cooking the concept, but look like here only proposals are accepted.

The problem is so large that it needs a clear design for IL language which is impacted most and not syntax, Syntax isn't an issue here at all. what proposal is expected for such scenarios? Svelte already paved out the technical difficulty and all it takes out for other framework is just to reproduce it.

with this new architecture svelte with javascript is achieving higher performance than rust, so it was very ignorant to close the issue while the benefit could be tremendous.

YairHalberstadt commented 4 years ago

@mhamri At the very least write a brief overview explaining, what the problem it's trying to solve is, what are current solutions, what solution is svelte taking, and what language/runtime changes does that require.

It didn't have to be detailed or complete, but it has to be something.

CyrusNajmabadi commented 4 years ago

Thanks, @CyrusNajmabadi, do you mind letting me know where the right place for this is?

if it's asking to watch a video, or let people know about something you think is cool, then a personal blog would likely be best.

The Github issues are for debate and cooking the concept, but look like here only proposals are accepted.

Issues can be about ideas, but they need to be more than just "please watch this". It really needs to put forth clear information about what's being asked for, what the value is, what problems there are, etc. etc.

The problem is so large that it needs a clear design for IL language which is impacted most

C# as a language is independent from IL. So if this is about designing an IL language, then this def isn't the place :)

with this new architecture svelte with javascript is achieving higher performance than rust,

If you can provide a proposal for what changes you'd like to see in C# then we can reopen this. But there isn't enough informaiton here to proceed with this.

so it was very ignorant to close the issue while the benefit could be tremendous.

Issues will be closed if they're not appropriately written for the repo. I'm happy to reopen this if you can flesh this out sufficiently. Thanks!

theunrepentantgeek commented 4 years ago

With due apologies because this is slightly off topic ...

a 45-minute talk describes it clearly and you want to read it?

@mhamri Why would I want to spend 45 minutes to find out something I can read in 10 minutes or less?

For the english language, most people speak at around 120 words per minute, conference speakers are usually slower than this, around 100 wpm. The average person reads at 250 wpm. It's my understanding that the average in the IT industry is 450-750 wpm.

Video is a spectacularly inefficient use of time.

CyrusNajmabadi commented 4 years ago

Ok. I watched the video. This does not seem to be something that needs language support for. This is much more of a framework-oriented system.

mhamri commented 4 years ago

@theunrepentantgeek because the original article by Paul Stovell is written in 2010 and no one picked it up yet (2020). many skimmed through the article and ignored its power. to demonstrate how powerful it is I needed to refer to a working example. my proposal would be the same as another blog post at some website that would be ignored by those that could make a difference. and as a matter of fact, svelte is around for three years with tones of article and blog post and videos around it. I am sure we don't need more blog post to read. maybe something that shows how things are working is a better idea?

@CyrusNajmabadi do you suggest to move this to Dotnet repo?

YairHalberstadt commented 4 years ago

@mhamri

Dotnet doesn't usually accept issues for creations of frameworks - they tend to be driven by internal decisions.

I would instead suggest creating a proof of concept framework to start off with. If it proves popular, other people may join in/ make their own version.

mhamri commented 4 years ago

@YairHalberstadt thanks, svelte already is very famous and popular in JS world, why do we need to have an example in dotnet while the benefit is already proven? and how is it possible to extend language feature without messing around with IL?

YairHalberstadt commented 4 years ago

@mhamri @CyrusNajmabadi thought it didn't require language or IL changes.

I think the main point here is that there are literally thousands upon thousands of cool languages and frameworks. They come out faster then you can learn about them. If Microsoft were to implement every cool framework that existed they would never get any work done.

If you think this is beneficial enough to the C# world to be worth investing time in implementing, then you either have to put a lot of effort into persuading somebody else to do that, or you have to implement it yourself. In my experience, unless you happen to be a software development celebrity, the second is actually a lot less work than the first.

CyrusNajmabadi commented 4 years ago

@YairHalberstadt thanks, svelte already is very famous and popular in JS world, why do we need to have an example in dotnet while the benefit is already proven?

Because being famous is not sufficient. There are lots of famous things. C# does not aim to ape them. If you have specific proposals on what you're asking for (for example, specific language features whose lack thereof makes implementing this difficult), please let us know :)

Right now, this reads more as a "i like svelte, do it" sort of post. It's not really useful or productive. If you can distill down what changes you're actually looking for in C# that would be great :)

CyrusNajmabadi commented 4 years ago

@CyrusNajmabadi do you suggest to move this to Dotnet repo?

Not really. I'm not going to move something that doesn't actually propose anything specific. It's not even clear to to me what you'd want to see out of .net here... Is it a new framework you want? A new language features? New capabilities in the jit for optimizing things? New transformations in asp.net? etc. etc. I really don't know what you're asking for here beyond a generic "i like svelte, do it" type post :-/

mhamri commented 4 years ago

@YairHalberstadt I think there was a miscommunication in here, I didn't expect nor ask to implement what is happening in svelte which it is serving another purpose. I'm asking about the destiny operator which is a language/framework concept. it's a reverse lambda that makes a variable defined by that reactive.

var a = 10;
var b <= a + 1;
Assert.AreEqual(11, b);
a = 20;
Assert.AreEqual(21, b);

though the language implementation in the svelte is different.

var a = 10;
$: b = a + 1;
Assert.AreEqual(11, b);
a = 20;
Assert.AreEqual(21, b);
mhamri commented 4 years ago

@CyrusNajmabadi please have a look at the code example that I've written

YairHalberstadt commented 4 years ago

@mhamri

Now we're getting somewhere.

Can you explain:

a) what are the semantics of this reactive operator (how does it work)? Is it effectively making b a function? Is it eager? Lazy?

b) why can't we do this in C# already? Why do we need a new operator?

c) what is this useful for?

CyrusNajmabadi commented 4 years ago

Given that it's just a lambda, why not just have:

var a = 10;
Func<int> b = () => a + 1;
Assert.AreEqual(11, b());
a = 20;
Assert.AreEqual(21, b());

or just:

var a = 10;
int b() => a + 1;
Assert.AreEqual(11, b());
a = 20;
Assert.AreEqual(21, b());

I'm not really getting the value of <=. unless it's just shorthand for () =>.

Note: C# could benefit here from being able to use var instead of having to mention the Func type. But i think there's a proposal for that already.

mhamri commented 4 years ago

@CyrusNajmabadi because of the reactivity, because we have the rx.net unless you tell me why instead of reactivex don't we use Func<>?

how the b() is being called each time that the a is changed? does the assert method is being called again? that's the reactivity.

var a = 10;
var b <= a + 1;
Console.WriteLine(b);
a = 20;

output should be

11
21

it's a chain of event that is being invalidated because of the "destiny operator" telling that the destiny of that operator is changed.

maybe make sense to read the original article by paul stovel in here

and again at the start, it sounds not a clever idea, code will be harder to read and some stuff like that, I think that's why it took 10 years for someone to pick it up. that's why I give a link right away to a successful implementation with detail explanation of how it works under the hood.

YairHalberstadt commented 4 years ago

@mhamri It would be really useful if you explain how this is meant to work from a high level perspective. Does b magically know a is changed? If so how? Or is b recalculated on demand? If so is the result cached or not?

mhamri commented 4 years ago

@YairHalberstadt yes, b and any usage of b will be called again.

under the hood, the compiler is tracking the building blocks of the b which is in here is a. then on each new assignment to a, the compiler will call whatever dependency that is build based on a (which is b).

when b recalculated, any usage of the b will be calculated/generated again.

YairHalberstadt commented 4 years ago

Ok I see. What is the advantage of doing that over simply making b a func?

CyrusNajmabadi commented 4 years ago

when b recalculated, any usage of the b will be calculated/generated again.

I'm struggling to understand what this would mean. for example, you are printing to the console. Why should changing a variable have any cause to update the console again. If i wrote 'b' to a file, would i expect 'b' to now be written to that file another time? Why is a changing value causing IO to happen?

mhamri commented 4 years ago

simply, you don't need to recall any usage of b on any change to a. and in an application, b depends on a, c depends on b, d depends on a and list can go on, you can imagine a tree that can be created on any usage of destiny operator, one change will update the whole tree. this is the implicit implementation of the observable pattern.

I think if you read any article about rx.net or reactive programming you can learn more about the benefits or in here https://github.com/dotnet/reactive

if I want to create something like this out of C# I need to create an event and delegate for everything. make everything listen to each other event. everything becomes a function.

but with this approach, we don't need the complexity of rx.net and at the same time, we have the power of reactive programming baked into the language.

CyrusNajmabadi commented 4 years ago

but with this approach, we don't need the complexity of rx.net and at the same time, we have the power of reactive programming baked into the language.

Moving complexity around doesn't make things less complex :)

Can you explain how this would work? i.e. what mechanism are you using to make it so that mutating 'a' changes 'b' and that chnage to 'b' causes externally visible effects (like console IO) to happen.

YairHalberstadt commented 4 years ago

@mhamri

The magic has to happen somewhere. Adding an operator can't change that -> an operator is just a syntax sugar for a function.

Making an operator won't make implementing the engine any easier.

So I think the first thing to do is create a working engine for this, without any syntax sugar. If that proves popular then it's worth looking at what language changes could make using this engine easier to use. TBH I imagine that its going to be the standard trick of building a state machine to represent working with a monad.

CyrusNajmabadi commented 4 years ago

I think if you read any article about rx.net or reactive programming you can learn more about the benefits or in here https://github.com/dotnet/reactive

I'm familiar with reactive programming. But i'm not actually understanding what you're proposing the language do here or how it would work :) Can you provide a clearer proposal? One thing that would help would be if you show what you would like to write and what it would compile down to.

CyrusNajmabadi commented 4 years ago

Going to call tihs out explicitly so it is seen:

One thing that would help would be if you show what you would like to write and what it would compile down to.

That will help demonstrate the semantics you are asking for. It would also help actually show how this would actually work based on existing constructs that people already understand well.

Thanks!

mhamri commented 4 years ago

@CyrusNajmabadi

I'm familiar with reactive programming. But I'm not actually understanding what you're proposing the language do here or how it would work :) Can you provide a clearer proposal? One thing that would help would be if you show what you would like to write and what it would compile down to.

well, I assumed everyone here is on the same page, but look like we are discussing what is reactive programming and what are the benefits. if you refer to the video that I shared (which was only 45 minutes but we are discussing it for 6 hours and I am quoting it bit by bit) the topic of the video is "rethinking reactivity". it's suggesting a better model than the reactivex, but talking about the better when we didn't establish a common understanding is not appropriate. most of your questions like how this one should be implemented or how will it look like after implementation, all is answered in the video that I shared at the start.

but let start with reactivex, for creating those 4 lines of code, with the current state of reactive programming in dotnet we need to write something like this.


using System;
using System.Reactive.Disposables;
using System.Reactive.Subjects;

namespace SomeNamespace 
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var a = new A();
            var b = new B(a);
            b.Subscribe(b => Console.WriteLine(b));
            a.Value = 10;
            a.Value = 20;

        }
    }

    internal class A : IObservable<int>
    {
        private readonly Subject<int> _subject = new Subject<int>();
        private int _value;

        public int Value
        {
            get => _value;
            set
            {
                _value = value;
                _subject.OnNext(value);
            }
        }

        public IDisposable Subscribe(IObserver<int> observer)
        {
            _subject.Subscribe(observer.OnNext);
            return Disposable.Empty;
        }
    }

    internal class B : IObservable<int>
    {
        private readonly Subject<int> _subject = new Subject<int>();

        public B(IObservable<int> a)
        {
            a.Subscribe(newA => _subject.OnNext(newA));
        }

        public IDisposable Subscribe(IObserver<int> observer)
        {
            _subject.Subscribe(i => observer.OnNext(i + 1));
            return Disposable.Empty;
        }
    }
}

the output is:

image

as you can see, there is a lot of code that really does nothing other than connecting stuff together and very unreadable code like this:

var a = new A();
var b = new B(a);
b.Subscribe(b => Console.WriteLine(b));
a.Value = 10;
a.Value = 20;

compare to the below code that could result in the same but in more clear & concise syntax.

var a = 10;
var b <= a + 1;
Console.WriteLine(b);
a = 20;

as you can see @YairHalberstadt it's not a sugar syntax. the usage can go much more complicated. I just gave a 4 line example in here and this can be scattered through the application.

How svelte implemented it? it's clearly explained in the video. How dotnet should implement it? open for discussion, but to be frank the svelte implementation is very clever and performant.

orthoxerox commented 4 years ago

@mhamri I'll try to be more explicit that others in explaining what's wrong with your current proposal.

It's a neat idea, but you're expected to do much more legwork before it will be taken seriously.

  1. What are the existing approaches to achieving reactivity in .Net?
  2. Why are the existing approaches insufficient?
  3. What does the new operator work on? (Locals? Fields? Properties?)
  4. What are the semantics of the new operator?
  5. How do you propose to implement it? (Svelte is not a .Net language, and the implementation might end up completely different)
  6. How will it interact with the existing approaches?

Neat ideas by themselves are rarely compelling enough to be taken seriously. A movie director might hear a dozen neat movie ideas from random strangers every day, but an idea is not enough to make a movie. Even a printed and bound script is almost never enough. The real question is "why should the C# team implement this feature instead of literally hundreds of others?"

mhamri commented 4 years ago

@orthoxerox thanks, most of these already is answered but I make a summary of those questions you've asked

What are the existing approaches to achieving reactivity in .Net?

https://github.com/dotnet/reactive

If I discussed this somewhere other than dotnet repo I would make a full explanation, but sadly, I didn't expect the call maker on this repo has no idea about another repo under the same account or something exist under the System namespace.

Why are the existing approaches insufficient?

too much boilerplate, unreadable code, not easy to learn and implement and debug.

with the current state:

using System;
using System.Reactive.Disposables;
using System.Reactive.Subjects;

namespace SomeNamespace 
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            var a = new A();
            var b = new B(a);
            b.Subscribe(b => Console.WriteLine(b));
            a.Value = 10;
            a.Value = 20;

        }
    }

    internal class A : IObservable<int>
    {
        private readonly Subject<int> _subject = new Subject<int>();
        private int _value;

        public int Value
        {
            get => _value;
            set
            {
                _value = value;
                _subject.OnNext(value);
            }
        }

        public IDisposable Subscribe(IObserver<int> observer)
        {
            _subject.Subscribe(observer.OnNext);
            return Disposable.Empty;
        }
    }

    internal class B : IObservable<int>
    {
        private readonly Subject<int> _subject = new Subject<int>();

        public B(IObservable<int> a)
        {
            a.Subscribe(newA => _subject.OnNext(newA));
        }

        public IDisposable Subscribe(IObserver<int> observer)
        {
            _subject.Subscribe(i => observer.OnNext(i + 1));
            return Disposable.Empty;
        }
    }
}

could be written like this

var a = 10;
var b <= a + 1;
Console.WriteLine(b);
a = 20;

What are the semantics of the new operator?

it's a reversed lambda <= for assignment. for fields we can use the same thing, for the property we can use a type destiny. it works the same as delegate.

What does the new operator work on? (Locals? Fields? Properties?)

everything.

How do you propose to implement it?

I wouldn't dare to suggest anything in here, all I can do is referring that another good implementation in another domain exists. for this one, we need to engage your neighbour on the reactive team and discuss it, but sadly @333fred didn't have patient nor the knowledge to know what we are discussing about, and just wanted to win the gold prize of the fastest clicking person on the net.

I don't want another implementation like int.TryParse() inside the dotnet where it's thought and implemented poorly, just imagine if we had tuple on early days (where existed in other language at that point of time), we didn't need out the result, then we didn't even need to introduce another mistake on top of that mistake like out var as a feature into the language.

here I am just quoting what the svelte is doing and I'm discussing against this code:

var a = 10;
var b <= a + 1;
Console.WriteLine(b);
a = 20;

1- b<=a+1 : when compiler faces a line that defines a variable/property/field using destiny operator

2- a=20: each new assignment to a tracked variable will cause something similar to INotifyPropertyChanged to be called.

some pseduo code demonstrating what will happen inside the change notify:

[NotifyValueChangedInvocator]
protected virtual void OnVariableChanged([CallerMemberName] string propertyName = null){
    //this part will be called on first call
    if (propertyName == nameof(a))
    {
        Invalidate(0, b => a+1);
    }

    //this will be called on second call because on first call we tell the b is changed
    if (propertyName == nameof(b))
    {
        Invalidate(1, b => Console.WriteLine(b));
    }
}

invalidate will collect all the changes and order them and apply the value change. the whole tree will be called again. in C# we have the option to use events/delegate which is up to the team to decide on the approach.

How will it interact with the existing approaches?

everything is wrapped inside an anonymous function, everything works as currently is.

A movie director might hear a dozen neat movie ideas from random strangers every day, but an idea is not enough to make a movie. Even a printed and bound script is almost never enough. The real question is "why should the C# team implement this feature instead of literally hundreds of others?"

you made a very controversial argument here, I would answer "the same reason the rocky idea rejected by many directors". ๐Ÿ˜„

the paul stovell's article was there for 10 good years and no one picked it up until someone else noticed it. http://paulstovell.com/blog/reactive-programming

unfortunately, the set of questions under this topic gave me a hint that no one in csharp team really knows reactive programming. it's like 10 years of history, but in short, it's proven, it's performant, now part of the official System namespace. just imagine a world that you didn't need to await your async calls. there are tens of thousands of books and article and video out there why reactive programming is important.

why this new approach is better?

because javascript which by no means is performant is biting rust now ๐Ÿ’ช . soon will be C# turn.

image

333fred commented 4 years ago

unfortunately, the set of questions under this topic gave me a hint that no one in csharp team really knows reactive programming.

On the contrary, I have used reactive programming for several apps, including ReactiveUI and RX.NET, and as Cyrus has mentioned he is familiar with reactive development as well. The reason I closed your issue has been very adequately explained: there are literally nearly 2000 language ideas on this repository. We do not have time to implement all of them, nor do we have time to watch every video on reactive frameworks or read every blog post and reverse engineer what you thought would be a neat language feature. If you want to go back and edit your original post to put the actual details of the language feature you are proposing, I'm happy to reopen this issue. But you cannot expect others to do the leg work for you here. There are simply far too many other ideas we could be working on in that time. If you do edit your original post feel free to ping me or Cyrus and we can reopen.

333fred commented 4 years ago

I will also further point out that there are a bunch of reactive frameworks for .NET, which your code samples for "today's state" do not make use of. When I have worked with reactive, there was really very little boilerplate needed. We also generally try to not enshrine any particular implementation of a type in the language: see the async pattern, or the foreach pattern, or most other patterns in the language. Reactive actually makes very good use of this by making their observable type task-like, so that it can be awaited and you can very easily move between Task and Observable. So when making a proposal, be sure to consider how you can make it generally applicable and not just limited to a specific library.

mhamri commented 4 years ago

@333fred thanks for reply,

On the contrary, I have used reactive programming for several apps, including ReactiveUI and RX.NET, and as Cyrus has mentioned he is familiar with reactive development as well.

That's what I was thinking in the first place, too! The first 15 minutes of the talk would be enough to applaud and clap for the idea for anyone who knows reactive programming. anyone that is familiar with the concept will see the value without even a single line of code/demo/explanation. as it demonstrates really "rethinking reactivity" as a much better method. but look like it wasn't obvious as I was thinking.

there are a bunch of reactive frameworks for .NET, which your code samples for "today's state" do not make use of

I beg to differ, most of those libs were written before the reactivex become a foundation. almost all of the implementation of the observable pattern rather than the official one is dropped or not maintained or doesn't have a big user group. there is one main implementation atm and almost all of the other libs mimic the same pattern.

When I have worked with reactive, there was really very little boilerplate needed.

this would be the case if you use & memorize almost 100 built-in functions. but still, you need to subscribe to your custom classes and it's not supporting something as simple as sum of two integers! I don't think any code could be simpler than that. and even if you use and memorize all the functions, still you are not 100% reactive.

So when making a proposal, be sure to consider how you can make it generally applicable and not just limited to a specific library.

as I mentioned it's not about a single library or any. it's about supporting reactivity (not rx.net) as the first-class citizen by implementing "destiny operator". my proposal is the operator, reactivity is a side effect. still, the best place for the idea is Paul Stovell article

If you do edit your original post feel free to ping me or Cyrus and we can reopen.

sure, I will compile what is discussed here and re-edit the first post. tq

CyrusNajmabadi commented 4 years ago

That's what I was thinking in the first place, too! The first 15 minutes of the talk would be enough to applaud and clap for the idea for anyone who knows reactive programming

I know reactive programming :) I don't necessarily think we need specific language features like this to support it. Furthermore, i think this could be actively confusing and problematic for our ecosystem and community and how they think about code and data flow.

For example, i absolutely do not like the idea that you just have implicit global-state affecting IO fallout as a consequence of your design. i.e. if i change a value somewhere, i would not expect IO that captured that value to rerun. This actively does not feel like a good thing.

and it's not supporting something as simple as sum of two integers!

You are conflating many forms of 'simplicity'. Being less verbose doesn't necessarily make things 'simpler'. On the contrary, it can be much less simple because of hte lack of clarity around what the impact now is between data and control flow.

CyrusNajmabadi commented 4 years ago

still, the best place for the idea is Paul Stovell article

This is not constructive to the discussion. You are approaching things as if it's a given that these ideas are necessarily positive/appropriate or that it is necessary that they be encoded at hte language level. However, that's not a universal position (nor can we even say if it's shared by the majority or plurality of users).

The objective here is to actually determine both if this is something truly valuable and, if so, what changes would be warranted in the language to support it. Just saying: "go watch X" or "go read Y" isn't helpful. We're aware of this stuff, but that doesn't mean we automatically think it's a good thing, or an important enough thing to encode at the language level.

In particular, you can likely find thousands of random posts with people talking about the changes they would make to their language of choice if they could snap their fingers. Just pointing at these doesn't mean we would do any of this stuff (or even think it was a good idea). The idea needs to be fleshed out and discussed fully in the context of this language, it's community and the surrounding ecosystem to determine where to go with it. :)

Thanks!

mhamri commented 4 years ago

if I change a value somewhere, I would not expect IO that captured that value to rerun. This actively does not feel like a good thing.

then why do you want to write it reactive at first place? reactive means, no pull, it's all about push. still, you have ability to get the value of something without hooking into its chain of the upcoming values.

You are approaching things as if it's a given that these ideas are necessarily positive/appropriate or that it is necessary that they are encoded at the language level.

not really, if you write the reactive programming long enough, you will recognize a better approach on a single glance. I come across tones of article/video and content on a daily basis but I won't bother to create an issue and spend the whole day ping-ponging comment to prove my point. how much I'm persistent about this hope shows how sincere I am about the benefit we can get from this addition.

it can be much less simple because of hte lack of clarity around what the impact now is between data and control flow.

that's the backbone of reactive programming. you code what you meant not what you think! I quote the Paul Stovell example here again

var a = 10;
var b = a + 1;
a = 11;
b = a + 1;

here the programmer meant that b always is one more than a, hence he wrote it twice or could call a function to tell it again. so he needs to tell it again and again what he meant. even he put a while around it to tell what he meant. but we are getting back into the discussion if reactive programming is good or not, instead, let focus on "destiny operator" for the sake of the argument. I think we can discuss if reactive programming's good or not in another venue.

The idea needs to be fleshed out and discussed fully in the context of this language, it's community and the surrounding ecosystem to determine where to go with it.

couldn't agree more, and it's the purpose of this issue. needs much more to discuss to bake the idea.

tq

HaloFour commented 4 years ago

Reminds me of those Excel spreadsheets where updating a value in a single cell triggers minutes worth of unexpected recalculations. IMO, there's way too much "voodoo" in the suggested operator and not a lot of apparent benefit. There doesn't seem to be much interest from the language designers in putting that into C#.

CyrusNajmabadi commented 4 years ago

then why do you want to write it reactive at first place?

I don't know if i woudl. It was your example. So it needs to be compelling and something i'd want to do. :)

not really, if you write the reactive programming long enough, you will recognize a better approach on a single glance.

That's not an argument. It's simply falling back on: this is better because i say so.

All of the language designers here are polyglots, familiar with a large number of languages, patterns, frameworks, etc. There's also a lot of knowledge about the history behind lots of this stuff. Reactive has it's place. But it's one of many systems out there with varying pros and cons. It's not the case that anyone thinks it just a better approach.

CyrusNajmabadi commented 4 years ago

here the programmer meant that b always is one more than a, hence he wrote it twice

But that's not how i would wirte that. i would just be explicit about that: B => A + 1. There. Done. 'B' is a computed value who will always be one more than 'A'.

CyrusNajmabadi commented 4 years ago

let focus on "destiny operator" for the sake of the argument.

Sure. Can you explain how you would expect this to work?

mhamri commented 4 years ago

That's not an argument. It's simply falling back on: this is better because i say so.

well, you need to see the svelte user group and hype then decide about this, I'm very insignificant particle in this movement.

But that's not how i would write that. i would just be explicit about that: B => A + 1. There. Done. 'B' is a computed value who will always be one more than 'A'.

but how many time do you need to tell B() after each time you redefine the a? and does it call the Console.WriteLine or any other line that is affected?

CyrusNajmabadi commented 4 years ago

but how many time do you need to tell B() after each time you redefine the a

you could never call it. or you could call it a thousand times. You call it if you need it.

and does it call the Console.WriteLine

Ideally no. Because that's external IO that i would not expect to ever rerun.

or any other line that is affected?

Define 'affected'. Why is the console affected just because at one point in the past i decided to log the current state of a value? If i wrote 'b' to a file... then what? it writes again? where? to the end of the file? to some random point in the middle? What does it mean to redo external IO automatically when a value changes? Why would i want that?

CyrusNajmabadi commented 4 years ago

well, you need to see the svelte user group and hype then decide about this

Do you understand why that's not a compelling case? :)

You are calling it hype, and you're telling me you can't adequately explain why it's important for C# to adopt this :-/ It's not really working to sell me on why i would want this instead of just using the facilities the language already has.

mhamri commented 4 years ago

you could never call it. or you could call it a thousand times. You call it if you need it.

well, that's the whole concept of reactive programming. we don't need to call a method a thousand times, because instead of pulling the data, the data can be pushed to you. and it's proven that is much more efficient than the older methods. but again, it falls back into the argument that I should sell you the idea of the reactive programming. it shouldn't be the case. that's the job of the books and academic articles. same as when I write an academic article and refer to a well known and acclaimed source should be enough to back my words, here also, I shouldn't sell a programming concept that is battle-tested and proven and I can refer back to those articles. if you do not agree that it is a useful way of writing code, then it becomes a personal opinion and I respect that. but let's not bring that opinion to the decision table because there are tens of thousands of books and article that are claiming the otherwise.

You are calling it hype

I'm calling it hype because this way of writing is new (not the observable pattern), just three years! the concept lived a good 10 years but only 3 years for someone to put it into the code and damn, it's working very well. and the observable pattern is living around for good 20 years. maybe I should look for another word that doesn't raise an alarm ๐Ÿ˜„

CyrusNajmabadi commented 4 years ago

well, that's the whole concept of reactive programming. we don't need to call a method a thousand times, because instead of pulling the data, the data can be pushed to you. and it's proven that is much more efficient than the older methods.

I don't see why your approach is any more efficient here. if you push and hte value isn't needed, then you've cost more than me simply not pulling.

it shouldn't be the case.

Sorry, that's not how it works. You're asking the language to change. If you don't convince the people who work on hte language that this is a good idea, then it's not going to happen.

There are thousands of issues asking for changes. We're going to make the changes we think are best for the language, community and ecosystem. If you don't spend the time showing why this is valuable, then it's not going to happen.

maybe I should look for another word that doesn't raise an alarm ๐Ÿ˜„

It has nothing to do with alarms.

I don't think you're getting what i'm saying. I'm saying that I (and others here) are familiar with this. But that doesn't mean that we're then just going to rubber stamp changes to the language around this area. You have to make a compelling argument that this is worthwhile for C# to adopt (along with explaining what the actual changes are and how they would work). Just pointing and saying: "see, there are books and articles on this" does not cut it.

I'm not sure how much more plainly i can state this. You, and thousands of others, have proposed we change the language. Dropping that proposal here and saying that we should now do all this research and jsut do this because you would like it will not happen. LDM members champion proposals when they believe that they're valuable and would be a good improvement to the language. So that's your primary challenge right now :) Convince me that this is a good thing. Don't just say that "that's the job of the books and academic articles". That's your job :)

CyrusNajmabadi commented 4 years ago

Honestly, my recommendation at this point is to just start with a new proposal. I've laid out what's necessary for a proposal to be taken seriously. But here's another run through

  1. It needs to explain why there's a problem today.
  2. It needs to propose concrete changes to address that problem.
  3. It needs to explain how those changes would work.
  4. It needs to explain why existing solutions are insufficient.

This is a bare minimum for this sort of thing. Otherwise, the default position of hte language is going to tend conservative and respond with:

  1. "If there's no problem, we shouldn't be changing the language unnecessarily"
  2. "We shouldn't change the language if it's not going to actually solve the problem you stated"
  3. "We're not going to change the language if what you're proposing isn't feasible to implement"
  4. "We're not going to change the language if the existing solutions are viable and realistically usable in practice"

This is how all proposals are treated. You're not being singled out unfairly. For anything to make it into a language change the above is the bare minimum that is needed to ensure that the proposal can move anywhere.

Thanks! :)

CyrusNajmabadi commented 4 years ago

Also, i get hte sense that you'd actually rather just talk instead of pushing forth a language proposal. In that case i highly recommend gitter.im/dotnet/csharplang and discord.gg/csharp, as good places for general discussion about the language and the Roslyn project. Thanks! :)

YairHalberstadt commented 4 years ago

To put this into perspective, Graydon Hoare, who is the designer of Rust, and somebody who I'm sure is highly respected by every member on the LDC, occasionally posts to Twitter lists of papers he has read and found interesting on language design .

Just a few days ago he posted 67 papers: https://twitter.com/graydon_pub/status/1252000830758064131?s=19

https://twitter.com/graydon_pub/status/1252005073363718146?s=19

For reference that's ~8 months and ~3500 inputs => ~500 skims => 67 plausibly-interesting-to-my-friends filtering. Hope some of them are gems to some of you! I see several...

If the C# language designers were going to spend time investigating interesting language design ideas, why should they look at your pet idea, rather than the ones that the designer of Rust called out as gems!?

If you want to get past this hurdle you've got to do enough legwork that the amount of research the LDC members have to has to do is so much reduced compared to reading one of Graydon's papers that's it's worth it them looking at your idea instead of his. Given the magnitude and difficulty of what you're proposing I would suggest that would need a minimum of:

A spec for this feature, including syntax, semantics, and code gen.

Example real life programs in C# using your suggested feature that highlight its benefits over current practices

An assessment of the impact on performance of this to show it does not severely regress performance.

mhamri commented 4 years ago

well, look like there is overlap about what is my job and what is your job in here. in this way I let it pass...

now that the mentality of the dotnet team is more clear, I have a better understanding of how the gears engage internally. you are right, let rust develop something first, then the dotnet can copy from them. some other language will pick it up sooner or later, then the C# can copy it from them. most of our talk, unfortunately, went about if the reactive programming is good or not. I suggest you have a talk with the neighbouring repo and ask them why they've merged it under System.Reactive in the first place if it's as bad as you are claiming it is.

Or visiting reactivex.org also gives you a better view of what is reactive programming rather than claiming you are familiar with it. the set of questions that have asked here clearly indicate that there is a lack of understanding on the depth of the matter.

what I faced here was bloated claims about familiarity about reactive programming, but questions and discussion were like I-don't-know-you-tell-me-why kind of questions!

I wonder If there was that level of familiarity, why even this basic question is being asked? we could discuss syntax, the effect on async, loops, but instead, we only discussed if the observable pattern is good or not!?

then I got this "I get the sense that you'd actually rather just talk instead of pushing forth a language proposal", ROFL.

unfortunately, it was a very unproductive discussion, asking me to prove to you that observable pattern is good or not. I laughed hard on that. usually, my junior developers ask me these kinds of questions about the necessity of design patterns. I didn't expect to get down to that basic level in here to prove that design patterns are good or not, at least not in this repo.

no hard feeling. I am already able to do what I want to achieve with C# in the current state and will use it. time will solve all the problems.

Gracias y adiรณs