« first day (1592 days earlier)      last day (1588 days later) » 

10:00 PM
I'm taking off now, but just realize that it's literally a nameless function.
Write a few simple examples with delegates and named function implementations, then switch them to lambdas.
Write some Linq with lambdas (I think you do that some, right? NVM if you don't), then switch the lambdas out to be functions.
 
It's shown under Rubberduck.Parsing.Grammar.VBAParser.startRule which doesn't exist
At least I can't find it in the solution explorer.
 
Please go on, since this seems to be very educational. However, considering the issue that triggered this, I would like suggest to @IvenBach to first fix #3332 since it basically encompasses everything you have to do after you have the module annotations.
 
Now that think i about it again, that would require a UI. So, the issue at hand might actually be less inolved.
Anyway, there should be some shared logic between the commands.
 
I've no problem doing both.
I'm just trying to educate myself as to what needs to be used for the parsing, re-write etc... and to do it properly.
 
10:06 PM
> Previously, we statucally cached serialized declarations we loadedfrom file in tests to avoid loading several MB of text files multiple times in different tests. This is no longer sensible because we derserialize ComProjects now and generate the declarations based on them.
 
I'm stuck on the magical use of t => t.startRule.
 
Cool, using the commit message format @Vogel612 linked to a while back, single commit PRs get their title and description automatically.
 
@Hosch250 These I'd done before. For simple ones I can write the function implementation and the anonymous function via delegate/lambda combo.
It's locating VBAParser that I can't figure out.
I'm just frustrated as it's obvious to everyone but me.
 
@IvenBach follow execution from Parse to ParseInternal; follow the function/delegate parameter until it's invoked
/driving, bbl
 
10:23 PM
[rubberduck-vba/Rubberduck] build for commit 05419605 on unknown branch: AppVeyor build succeeded
> # [Codecov](https://codecov.io/gh/rubberduck-vba/Rubberduck/pull/4441?src=pr&el=h1) Report
> Merging [#4441](https://codecov.io/gh/rubberduck-vba/Rubberduck/pull/4441?src=pr&el=desc) into [next](https://codecov.io/gh/rubberduck-vba/Rubberduck/commit/de6f99412db1492eb938dd94fa9ce43044716e5a?src=pr&el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `100%`.


```diff
@@ Coverage Diff @@
## next #4441 +/- ##
=========================
[rubberduck-vba/Rubberduck] build for commit 05419605 on unknown branch: 63.75% (target 0%)
> # [Codecov](https://codecov.io/gh/rubberduck-vba/Rubberduck/pull/4441?src=pr&el=h1) Report
> Merging [#4441](https://codecov.io/gh/rubberduck-vba/Rubberduck/pull/4441?src=pr&el=desc) into [next](https://codecov.io/gh/rubberduck-vba/Rubberduck/commit/de6f99412db1492eb938dd94fa9ce43044716e5a?src=pr&el=desc) will **decrease** coverage by `0.01%`.
> The diff coverage is `100%`.


```diff
@@ Coverage Diff @@
## next #4441 +/- ##
=========================
 
I see where it's invoked.
the parameter parser in supplied to ParseInternal github.com/rubberduck-vba/Rubberduck/blob/… as the 4th argument which comes from ParserStartRule startRule as the second parameter of Parse.
It's the lamdba usage of t => t.startRule() and where it's magically coming from.
@Hosch250 Fixed with the correct implementation.
Hovering over t it shows me where it's located.
F12 to navigate to startRule take me the member of that class.
Right clicking on the tab>Open Containing Folder takes me to the automagically generated file.
...\Rubberduck\Rubberduck.Parsing\obj\Debug contains VBAParser.cs
 
11:03 PM
@IvenBach there is no magic... remember ParseInternal is receiving a function as a parameter, not the result of that function.
 
where is the function coming from?
That's my disconnect.
VBAParser isn't static, nor is startRule so I don't see how it can be use unless its explicitly provided.
 
It's inlined,the lambda is the function
 
I feel dumb that I'm not getting it.
I went through them and with a lambda it is explicitly providing 4.375 as the value.
MathAction ma3 = s => s * s * s;
double cube = ma3(4.375);
MathAction is the delegate which takes in a double and returns a double delegate double MathAction(double num);
 
Yes.
 
ma3 is an instance of the delegate defined by the lambda.
 
11:08 PM
Now imagine you passed ma3 to another function.
 
when it's invoked it is provided 4.375.
 
That function would have to provide that value, right?
 
Imagine there's an actual method that takes a VBAParser parameter and returns an IParseTree by invoking startRule() against that VBAParser parameter.
 
So you can do MyFunction(ma3).
 
@IvenBach Remember when we were talking about delegates in the context of events?
 
11:08 PM
You could just as well pass that function instead of the lambda
 
Now MyFunction has to call ma3(4.375).
 
Yep. I see nowhere that an argument is provided.
 
Well, keep tracing the usages.
You are in Parse, right?
 
@IvenBach it's provided when the function is invoked
 
s is the argument in the signature s => s * s * s
 
11:09 PM
It's used as return ParseInternal(ParserMode.Sll, parser, tokenStream, startRule);.
 
we're passing the function itself.
 
Notice that once again, it's passed deeper.
We check ParseInternal.
> var tree = startRule.Invoke(parser);
There we have it.
Note that we don't really need the Invoke.
 
That I get.
 
You can just view that as startRule(parser).
That's where our parser is coming from.
It's not coming from where we define the lambda, it's coming from where the lambda is called.
 
Just think of it as shorthand. ma3 = s => s * s * s is the same as ma3(double s) { return s * s * s; }
Take a look at the VB.NET examples:
Dim increment1 = Function(x) x + 1
Dim increment2 = Function(x)
                     Return x + 2
                 End Function

' Write the value 2.
Console.WriteLine(increment1(1))

' Write the value 4.
Console.WriteLine(increment2(2))
They're a PITA to work with, but they're a bit more obvious as to what is going on.
 
11:13 PM
@Hosch250 This may be what I was missing.
 
apologies to everyone who had to look at the VB.NET "lambdas"
2
 
var tree = startRule.Invoke(parser); the invocation is provided parser as t => t.startRule?
 
Yes.
t is really that parser when it gets called.
 
FMITA github.com/rubberduck-vba/Rubberduck/blob/… is where it's newed up.
It's my fault for not kindergarten-coloring myself a diagram...
 
I actually quoted that line above.
1 hour ago, by Hosch250
var parser = new VBAParser(tokenStream);
 
11:18 PM
For some reason it got into my mind that ParserStartRule startRule was the VBAParser parser and I couldn't get my mind to unsee it.
1 hour ago, by IvenBach
It is not your lack of explanation. It's my inability to see the obvious.
Sweet jeebus I feel smort.
 
Well, you learned them a heck of a lot faster than me.
What, 3 hours instead of 2-3 months?
 
LAFF! I read about delegates a year ago and have been trying to understand them since.
 
Once again, you just need practice with the different notations (lambdas, delegates, normal functions, etc.).
Like, let's say I have a sequence of integers represented as strings, and I want them back as integers.
 
Yes. My only experience with them comes from RD.
 
As in: IEnumerable<string> sequence.
I can do sequence.Select(int.Parse).
That's a static method I pass in.
I could also have done sequence.Select(s => int.Parse(s)). Same thing.
Or I could do:
sequence.Select(s => {
    if (int.TryParse(s, out var i))
    {
        return i;
    }
    return 0;
})
Anyway, have fun. I'm taking off now.
 
11:23 PM
A simpler example would be .Where in Linq. It takes a function that returns a boolean as an argument.
 
@Hosch250 This is allowed since docs.microsoft.com/en-us/dotnet/api/… is an extension method taking in the IEnumerable and the Func portion is represented a delegate which is substituted for docs.microsoft.com/en-us/dotnet/api/…?
 
Correct.
 
The omission of the variable is only allowed if it's singular?
 
So, UserDeclarations.Where(x => x.DeclarationType == DeclarationType.Variable); is calling the delegate function bool anon(x) { return x.DeclarationType == DeclarationType.Variable; } to selection what members to return.
 
I remember having read that but not fully understanding it implication.
^^ That is how I was understanding them before today.
 
11:26 PM
@IvenBach Yes. If you have a Func<Type> where Type is the single parameter, you can omit it.
 
The omission messes with me really really bad.
 
You can always explicitly pass it if it helps.
 
I will until I am very comfortable with them.
 
@IvenBach What omission?
Omit as in how?
 
Of the variable.
 
11:27 PM
Give me an example.
 
foo.Where(Bar)
 
@Hosch250 I see no temporary x or t etc... variable
 
bool Bar(x as WhateverFooIs)
 
The lack of it throws me off entirely.
 
Oh, nope.
You can omit all variables as long as they have the same signature.
You have to have them all in, or leave them all out.
It is NOT like F# where you only need to provide some of them and get a new function with a new signature.
 
11:29 PM
I can't leave them out and fully understand what's going on.
 
So, don't even worry about that yet. That is very confusing to learn, and awesome once you get it.
 
I'll get there given enough time.
 
Then, as I said, this is the same thing as the one you just pointed to:
sequence.Select(s => int.Parse(s))
 
^ That I understand.
 
Notice that it's basically a wrapper around int.Parse, and the arguments are in the same order.
(Which comes as a given because you can't reorder one item.)
 
11:30 PM
Wait...
 
So that function has the same signature as int.Parse, so you can just skip that wrapper and go right to int.Parse if you like.
 
If you had static Foo(int a, string b, double c) and provided it to something else with the same type and order of the parameters you could omit all the variables?
 
Yes.
You have to omit ALL of them or NONE of them.
Oh, and the return type counts too.
The return type and parameters all have to match what is expected.
 
Bar.Example(x, y, z => Foo(x, y, z)) would be equivalent to Bar.Example(Foo)?
The entire signature of arguments and return type.
 
It doesn't matter if it's defined in timbuctoo or inline or anywhere else.
Yes.
 
11:32 PM
@IvenBach ParserStartRule is defined as an explicit delegate - it's entirely equivalent to Func<VBAParser,IParseTree>... and should probably have been exactly that. There's seldom a need to declare an actual delegate in modern C#
 
Yep. delegate is basically dead since C# 3.
 
public delegate string MyDelegate(int foo);
^^ matches any function that takes an int and returns a string
 
I'm all good with that.
 
i.e. a Func<int,string>
Cool
 
So, I think you've got it now.
TTYL.
 
11:34 PM
Seeing Func<int, string> takes me a while to think it through. It's still not second nature.
 
now a Func<T,bool> like you see a lot in LINQ, also has a named delegate type, Predicate<T>
i.e. a predicate (of T) is any function that takes a T and returns a bool
 
Yep.
The predicate determines whether or not it belongs to the set.
 
Awesome. You're doing great!
 
~.~ I'm just regurgitating what I remembered from the C9 video.
 
play with delegates. declare your own, match them, use various notations for them, learn to recognize them, you'll love them
 
11:37 PM
The simple ones I use.
 
then we'll talk about events & multicast delegates =)
bbl
 
Now to return back to VBACodeStringParser.Parse to figure out about the tuple stuff.
 
11:50 PM
        [Test]
        public void PlacesCaretBetweenOpeningAndClosingChars_NestedPair()
        {
            var pair = new SelfClosingPair('"', '"');
            var input = pair.OpeningChar;
            var original = "MsgBox (|)".ToCodeString();
            var expected = "MsgBox (\"|\")".ToCodeString();

            var result = Run(pair, original, input);
            Assert.AreEqual(expected, result);
        }
ugh
test passes
ooh I think I know what's going on
I must have forgotten to set e.Handled = true somewhere
 
Is it tunnelling or bubbling?
 
lol it's not WPF
 
There I go exposing my ignorance again...
 
e is AutoCompleteEventArgs
@IvenBach no, the mechanics are the same really
 
RE: public static (IParseTree parseTree, TokenStreamRewriter rewriter) Parse will I want to work with the parseTree or rewriter to get the @Folder annotation?
 
11:54 PM
I think that discussion was beneficial for understanding delegates - for the feature proper IMO you should heed @M.Doerner's advice
 
2 hours ago, by M.Doerner
Please go on, since this seems to be very educational. However, considering the issue that triggered this, I would like suggest to @IvenBach to first fix #3332 since it basically encompasses everything you have to do after you have the module annotations.
Fixing 3332 first?
 
Yo what's up
 

« first day (1592 days earlier)      last day (1588 days later) »