11

I was just watching a video on MSDN Channel 9 which can be found here, about some of the new features in Visual Basic 10. Now I like most of the new features, some of which have been long awaited(auto properties and Collection Initializers), one that caught my eye was the multiline lambdas like in C#.

In the video he used an example like this:

Dim scores = {10,20,30,40,50}
Dim thread as new Threading.Thread(Sub()
                                   For Each o in scores
                                     console.writeline(o)
                                     Next
                                   End Sub)

Now I like VB in all it verbosity but I'm just a bit worried that writing sub...end sub inline could get a bit messy, I can see some merit in inlining when you are writing C# when you only have to use something like c => {....} and you can cut out a lot of code.

What are your throughts of multiline lambdas in VB?

Would you find them useful and where?

MPelletier
  • 15,130
  • 14
  • 79
  • 128
Nathan W
  • 50,657
  • 24
  • 92
  • 142
  • Just wrote my first one. Love them. I'm almost exclusively a VB.NET but I would prefer the shorter x => f(x) in C# but I will take what I can get. I'm not switching to C# anytime soon! – Tim Murphy Jul 07 '10 at 01:42

7 Answers7

14

Personally, I think that VB's syntax for delegates and lambdas is completely bogus. I mean, come on, AddressOf! This was fine in VB6. It is definitely not fine in a language such as VB.NET where functions should be treated as first-class citizens (although they really aren't, of course) and where conversion from method groups to delegates is more or less transparent.

Now the introduction of inline functions is horribly verbose. I actually believe that the C# approach – x => f(x) would fare very well in VB because it shows exactly what it does. At the current state, I prefer C# for any functional programming work, which is a pity because I generally favour VB.

Now, I really rejoice that VB finally gets multiline lambdas and statement lambdas because they're still useful sometimes (take the case of Parallel.For). But the syntax is messed up. The same goes for iterators, by the way (if they should make it into VB10).

Konrad Rudolph
  • 482,603
  • 120
  • 884
  • 1,141
  • I would say I have to totally agree with you, I like writing in VB, but I just wish they would make it a little bit more short hand. – Nathan W Oct 30 '08 at 08:27
  • 1
    +1 from me. I am more excited that F# is now a first class citizen in Visual Studio. – Jim Burger Jun 16 '09 at 00:38
  • What's the problem with `AddressOf`? Parenthesis are easy to overlook (and, unfortunately, not even required in VB.NET), so I think `MySub(AddressOf MyFunction)` is much clearer to read than `MySub(MyFunction)`, which is easy to confuse with `MySub(MyFunction())`. – Heinzi Nov 28 '09 at 12:50
  • 4
    First off, `AddressOf` is complete bogus. We don’t take an address of a function, we’re converting a function group to a delegate (although technically, `AddressOf` doesn’t even do that, it just disambiguates syntactically). Secondly, that is a completely uninteresting implementation detail. What we *want* to do here is treating a function as any old object. And this may rub some VB programmers the wrong way but that’s just too bad. No sympathy from me. I want to use a powerful language, not one catering to people who are afraid of useful and fundamental concepts. – Konrad Rudolph Nov 28 '09 at 13:25
  • Addressing your readability concerns: In theory you could be right. In practice, however, this is simply not an issue in other languages, other things being equal. Parentheses are certainly *not* easy to overlook. – If they were, most modern programming just languages wouldn’t work. – Konrad Rudolph Nov 28 '09 at 13:28
  • 1
    @Konrad: Nobody asked for sympathy. ;-) Anyway, thanks for the clarification. Of course, `AddressOf` doesn't *take* the address of a function, it (figuratively) *returns* a handle to the function (as an analogy. Of course, under the hood, it's different, but -- as you correctly point out -- that's an implementation detail). I still think that some kind of `quote` keyword eases reading, be it `AddressOf`, `'` (like in Lisp) or something else, to easily differentiate this case from the "more common case" of a function call. But I guess that's just a matter of taste... – Heinzi Nov 28 '09 at 16:12
  • 1
    PS: Remember that one of VBs goals is to be easy to understand for beginners. Of course, experiences computer scientists like us are familiar with the concept of functions being first-class citizens from lots of other languages. For a beginner who forgot about the '()' and has no clue that passing functions is even possible, the error message `Cannot convert Func(Of Integer) to Integer` might be a bit hard to interpret. – Heinzi Nov 28 '09 at 16:19
  • @Heinzi: True, but being beginner friendly is no longer the aim of VB, according to Microsoft. And if a language is beginners friendly *at the expense of* professional programmers, then it’s simply no longer apt for professional programmers – which would be a pity for me, since I really like VB. – Konrad Rudolph Nov 28 '09 at 16:41
  • I actually think AddressOf serves a very valuable role: it makes explicit that you want to get a pointer to a function and not invoke it. In C# you have to use parentheses for this. (x = SomeMethod gets a pointer, while x = SomeMethod() actually calls the function.) IMO, the vast majority of the time, you want to call a function, not pass it around as a variable, so in C#, in a million places you have to do this: x = MethodA().MethodB().MethodC(), where VB lets you ignore the parentheses. Compounding this, you MUST omit parens if the method is actually a property, even though there is – Joshua Frank May 10 '12 at 15:02
  • continued: often no way to know when a method is actually a property in disguise, or vice versa. So in C#, I am CONSTANTLY guessing wrong about this, and getting a compiler error. I find this VERY annoying, and would much prefer to ignore parens EXCEPT when I explicitly want to treat a function as a variable, and this is what AddressOf does, essentially. Likewise, I wish the method/property distinction could be made in a less annoying way. – Joshua Frank May 10 '12 at 15:05
  • @JoshuaFrank There’s just one flaw in the reasoning: .NET doesn’t have pointers to functions. And if you omit the parentheses in a call in VB, the IDE will allow this but not me (if I am to peer-review your code). I think they are important enough for understanding to distinguish a call from a non-call object. – Konrad Rudolph May 10 '12 at 15:12
  • I was being sloppy. I meant the difference between a function as an object vs. the result of calling that function. I agree that this distinction is important, but I think it's made much more clear using AddressOf X than using the very subtle difference between X and X(), especially since X can also be a property, whose semantics are often identical to method semantics, and yet C# forces you to treat them as you would a method. Consider a statement like: var y = MyObject.X;, you simply can't tell if you are getting the method X or the *value* of property X. This is REALLY confusing. – Joshua Frank May 10 '12 at 15:59
  • @Joshua OK but this still leaves the point that once you have a delegate, this difference vanishes anyway. For a delegate `x`, `foo = x` doesn’t perform a call, `foo = x()` does. The uniform access principle postulates (with good reasons) that similar interfaces should act alike, and this is a very important point when treating functions / delegates as [first-class](http://en.wikipedia.org/wiki/First-class_function) citizens. – Konrad Rudolph May 10 '12 at 16:09
  • @KonradRudolph: But (1) most of the time you invoke functions and don't carry them around as delegate variables, so I'd rather relax the parentheses requirement for that more common use case, and require syntax like x.Invoke for the delegate situation. (2) property access and function invocation are VERY similar interfaces, but C# forces them NOT to act alike, since you must do x = obj.func() but x = obj.prop. And I often make an extension method on a class that I didn't write, and treat this as a property when it's in fact a function: x = obj.IsXXX(). This seems like a much worse violation. – Joshua Frank May 10 '12 at 16:32
  • @Joshua About properties vs. methods: C# intentionally models this differently. Properties are like fields, not like methods. Yes, this breaks down at some point but it’s a closer match than properties and methods (even if code is called in the background – that’s an implementation detail). – Konrad Rudolph May 10 '12 at 22:31
  • 1
    @KonradRudolph: My point is that IMO, VB handles this better by allowing functions and properties to be called in the same way, and this is ultimately because there's never chance for confusion between call and non-call, because VB doesn't rely on parentheses for this distinction, using, instead, the explicit AddressOf keyword. It's fashionable to lampoon VB as a toy language because of syntax like this, but I think this kind of explicitness makes it much clearer what the programmer's intention is, and that's critical. – Joshua Frank May 14 '12 at 02:37
4

By preference I'm a C# developer, but have been using VB 9 almost exclusively for about a year now. The #1 thing about VB 9 that breaks my heart is the limited lambdas. Lambdas in VB 9 are limited in the following ways:

  • Only one statement.
  • They must return a value.

So the ForEach method on collections will not work with lambdas, and only the very simplest of operations will work. So most of the time you have to move your logic to some other method and use AddressOf. Many times this cleaves the readability of the code in a dramatic and heartbreaking way.

It's something that I feel many would not pick up on unless they've used anonymous methods fluently in another language that fully supports them (C#, JavaScript, etc.), rather than the crippled support they have in VB 9.

I'm extremely relieved that they're fixing lambdas in VB 10.

pettys
  • 2,150
  • 22
  • 34
2

I can think of two reasons off the top of my head why I love it! Been waiting too long for this.

First:

 Private Sub SomeMethod()
     Dim SomeVariable as String = "Some text."

     AddHandler SomeButton.Click, Sub()
                                      SomeVariable += " Some more text"
                                      MessageBox.Show(SomeVariable)
                                  End Sub

Second:

 Private Sub SomeMethodRunningInAnotherThread()
     Me.Dispatcher.Invoke(Normal, Sub()
                                      'Do some other stuff '
                                      SomeTextBox.Text = "Test"
                                  End Sub)
 End Sub
MarkJ
  • 29,252
  • 4
  • 60
  • 104
2

Same here, I love vb. Most of the time you are thinking and not actually writing code anyway, so the verbosity argument fails in my opinion, as you are usually staring at code or editing it, and imagine The time you are saving understanding your code when you read it in its verbosity in vb? Much easier and less error and bug prone as opposed to c#.

Also, c# still has no with clause, and vb has had this even prior to the .net days.

With obj.class.methods

   .property = 1

   .attribute = 2

End with

Imagine this with 10 things that need to be set? In c# you'd have to create a reference to obj.class.methods and use that for shorthand expressing, which is wasted memory and inefficient, so in that respect vb does use less memory and you are not punished for using less memory unlike with c# .

And the "using" keyword argument fails since using doesn't work with most objects or objects that don't implement idisposable which is absolutely annoying.

Then, think of all the explicit castings you have to do in c# as opposed to vb. C#errs will argue that is encourages better coding but that is nonsense, as any good developer doesn't need to explicitly cast something 500 times a day to understand that if he didn't an implicit casting would take place (as it does in vb).

Most c#errs use it because they come from a c background, which is fine, but I find a lot of them started with it because it contains the letter c and they think its cooler because it lacks the language innovation that vb has, making it harder for the developer, and that makes them feel smarter and cooler and above everyone else - lol, they don't understand that hiding complexity at 0 cost is the ultimate goal, which is what vb can do for you. Notice the at zero cost part, as it would not be a good thing if it was at above zero cost.

Siddharth Rout
  • 137,434
  • 15
  • 189
  • 237
Erx_VB.NExT.Coder
  • 4,723
  • 8
  • 52
  • 90
0

There are no easy ways to manage this:

Convert C# statement body lambda to VB

without multiline lambdas.

sigh

So yes, I'm anxious for this to be fully released.

-Adam

Community
  • 1
  • 1
Adam Davis
  • 87,598
  • 55
  • 254
  • 328
0

Full anonymous method support in VB means you can start taking a more functional style with things. If the Sub() End Sub need to go on separate lines... that hurts. I'd hope they'd allow single-line anonymous methods, so long there was only one statement.

MichaelGG
  • 9,862
  • 1
  • 37
  • 80
0

You are going to need multi-line once we get the ParallelFX library.

For example, lets say you wanted to make this loop parallel:

For i = 0 to 100
  '12 lines of code'
Next

The parallel version would be:

Parallel.For( 0, 100, sub(i)
  '12 lines of code'
  End Sub )

It works by turning the guts of the loop into a brand new sub. That new sub is called by N threads, N usually being the number of available cores.

Konrad Rudolph
  • 482,603
  • 120
  • 884
  • 1,141
Jonathan Allen
  • 63,625
  • 65
  • 234
  • 426