Forums

Ruby like blocks in Cobra?

General discussion about Cobra. Releases and general news will also be posted here.
Feel free to ask questions or just say "Hello".

Ruby like blocks in Cobra?

Postby Csaba » Mon Jul 13, 2009 11:14 am

Hi,
Recently Yehuda Katz: pointed out that one of the two main advantages Ruby has over Python is that Ruby can take blocks of code and that is heavily used in Rails. As far as I know, Cobra don’t have Ruby like blocks. So the suggestion is to introduce some Ruby like blocks, for instance, as shown below.

Code: Select all
class TimingUsingClosureAndBlock

   sig ParameterlessSubOrBlock

   def timeIt(aProc  as ParameterlessSubOrBlock) is shared
      startTime= DateTime.now
      print 'Start    [ startTime]'
      aProc.invoke
      print 'Cobra elapsed time is [DateTime.now.subtract(startTime)] seconds'
      print

   def main
   
      timeThis as ParameterlessSubOrBlock = do
         # could be many statements here
         for i in 0:1_000_000
            x = Math.sin(Math.pi*i/2_000_000)
   
      # This is legal Cobra code but requires that the code is in a closure
      .timeIt( timeThis )
      
      # v1 Suggested Ruby like block to achieve the same result
      .timeIt.do
         # could be many statements here
         for i in 0:1_000_000
            x = Math.sin(Math.pi*i/2_000_000)

      # v2  Alternative Ruby like block
      .timeIt(do
         # could be many statements here
         for i in 0:1_000_000
            x = Math.sin(Math.pi*i/2_000_000)

In v1 suggested example, ‘do’ appears in a different context (as in Ruby) but for the same purpose as when used in a closure or lambda. In v2 suggested example do is a “normal” "multi-line statement lamdbda".
It seems like VB 10 will get "multi-line statement lambdas" similar to Ruby blocks but slightly clumsier:

Code: Select all
animal.DoTrick(Sub()
      animal.LegsOnGround = 0
      Console.WriteLine("I'm Jumping now!")
      animal.LegsOnGround = 4
   End Sub)

I hope it is possible to implement some version of blocks in Cobra. (The other main Ruby advantage over Python is simpler meta programming.)
Regards
Csaba
Last edited by Csaba on Mon Jul 13, 2009 1:49 pm, edited 1 time in total.
Csaba
 
Posts: 42

Re: Ruby like blocks in Cobra?

Postby Charles » Mon Jul 13, 2009 12:42 pm

This is a good question and I have a great answer. Cobra already has blocks of code, also called "closures". They are kicked off with the "do" keyword and the code is indented on the next line. See the test cases.

If you know of some shortcoming that should be addressed let me know. Currently, the types of the arguments are not inferred by the compiler, which takes some of the fun out. But they do work.

This points out, of course, that we need a How To.

If you have any questions, let me know.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Ruby like blocks in Cobra?

Postby Csaba » Mon Jul 13, 2009 1:58 pm

Hi,
Fine! So this code actually works:
Code: Select all
      .timeIt(do)
         for i in 0:1_000_000
            x = Math.sin(Math.pi*i/2_000_000)

The only problem is with comments:
Code: Select all
      .timeIt(do)
         # This commnet will give compilation error::  Expecting INDENT, but got "\n" (EOL) instead.´
         for i in 0:1_000_000
            x = Math.sin(Math.pi*i/2_000_000)

Thank you!
Regards
Csaba
Csaba
 
Posts: 42

Re: Ruby like blocks in Cobra?

Postby Charles » Mon Jul 13, 2009 11:57 pm

Thanks for the report. Will fix.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Ruby like blocks in Cobra?

Postby Charles » Thu Jul 16, 2009 12:49 am

Fixed.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Ruby like blocks in Cobra?

Postby Csaba » Fri Jul 17, 2009 1:51 am

Than you! Regards Csaba
Csaba
 
Posts: 42

Re: Ruby like blocks in Cobra?

Postby todd.a » Fri Aug 07, 2009 3:30 pm

I vote for changing the syntax used, i.e. use vertical bars :) (I know how much chuck hates those) but at the same time the parentheses don't seem syntactically pleasing to the eye for this use.
todd.a
Site Admin
 
Posts: 81
Location: Chicago, IL

Re: Ruby like blocks in Cobra?

Postby Charles » Fri Aug 07, 2009 9:05 pm

"do" blocks that don't have arguments take no parens at all. "do" blocks with arguments take them as: do(arg1, arg2)

This is identical to declaring arguments for methods as well as declaring sigs:
sig ComputeResult(a as number, b as number) as number  # 1

class Foo

def bar(s as String) # 2
pass

def baz
# ...
t.sort(do(a as Platform, b as Platform) as int) # 3
return a.name.compareTo(b.name)

I don't plan on changing any of the three.
Charles
 
Posts: 2515
Location: Los Angeles, CA

Re: Ruby like blocks in Cobra?

Postby _Gold_Fish » Thu Jul 01, 2010 3:43 pm

I know this is an old topic, however:
I've been trying to find a way to do something very common in Ruby:
Code: Select all
myArray.delete_if { |value| value == 7 }

This may not be a good example of a portable method, however it does have something I would love to be able to do (or find out how to do), and that is to be be able to pass a whole section of code to a function, and have the function run its own code, be able to execute the passed code when it is told to (like Ruby's "yield" keyword), and be able to supply values to the code block (like "|value|" in the above example.
_Gold_Fish
 
Posts: 18

Re: Ruby like blocks in Cobra?

Postby Charles » Thu Jul 01, 2010 6:37 pm

This should help:
extend IList<of T>

def printAll(pred as Predicate<of T>)
for item in this
if pred(item)
print 'found:', item


class Program

def main
t = [1, 2, 3, 4, 5, 6]
t.printAll(do(i as int)=i%2==0)

# outputs:
# found: 2
# found: 4
# found: 6

The Predicate type is already available in the .NET standard library. It's for any method that takes an argument and returns a boolean. But if you need something else, you have to declare your own type through "sig".

To call the predicate, or any method reference (called a "delegate" in .NET parlance), you call it with parens: foo(args)

That's pretty similar to invoking other methods except there's nothing to dot (.) because you have the reference already.

And I don't normally structure my code around "print" statements like that, but you can rename .printAll and rewrite it to your purposes.

HTH
Charles
 
Posts: 2515
Location: Los Angeles, CA

Next

Return to Discussion

Who is online

Users browsing this forum: No registered users and 66 guests