1. Ruby, C#, Objective C and Lisp Lambda Expressions

    I just started to lear Ruby. I’m not quite sure what’s the best way to learn a new language. With C#, Python and Objective-C I just started up with a project and learned the language in process. I have one start-up idea, which I’m starting implementing in Ruby, but also I want to refresh some of other languages knowledge. So, here’s some examples of useful things in different programming languages.

    C#

    Since most of the time I was writing software in C#, i will start with a C# examples. So, we write a small custom class for ourselves, that will be passed by reference, unlike immutable strings and all the value-types.
    class MyCustomClass {
    	public string StrVal { get; set; }
    	public int IntVal {get;set; }		
    }
    
    Now, we create an lambda-expressions test itself. So, let’s create a wrapper over the Generic List of MyCustomClass, that will give us a possibility to pass our delegates. It’s pretty much useless, since I could have used List directly, but heck, let’s have another level of abstraction.
    class LambdaExpressionTest {
    	private List<MyCustomClass> list;
    	
    	public LambdaExpressionTest ()
    	{
    		list = new List<MyCustomClass>();
    	}
    	
    	public void AddValue (MyCustomClass val)
    	{
    		list.Add (val);
    	}
    	
    	public void ProcessEach (Action<MyCustomClass> action)
    	{
    		list.ForEach (action);
    	}
    }
    
    And let’s use the code we just wrote. Basic syntax is () => {}. Left part - is what comes in, right part - is what we do with the left part. So, here’s a piece of code that fills up list with some values, than changes them, and writes new values to strings.
    LambdaExpressionTest expressionTest = new LambdaExpressionTest();
    expressionTest.AddValue (new MyCustomClass { StrVal = "value1", IntVal = 1} );
    expressionTest.AddValue (new MyCustomClass { StrVal = "value2", IntVal = 11} );
    
    expressionTest.ProcessEach ((c) => { c.StrVal += "1"; c.IntVal += 10; });
    expressionTest.ProcessEach ((c) => { Console.WriteLine (String.Format ("{0}, {1}", c.StrVal, c.IntVal)); });
    
    Such a fortune for C# developers that syntax for such a useful as lambda expressions is that easy. Generics make life lot easier too. But when we talk of dynamically-typed languages, this point is not relevant anymore. So, we can move on.

    Ruby

    Same thing: we create MyCustomClass, and create an initializer.
    class MyCustomClass 
      attr_accessor :str_val, :int_val
      def initialize (str, int)
        @str_val = str
        @int_val = int
      end
    end
    
    Now we create a wrapper for Array. Actually I loved the syntax of “«” rather than .Add, and for some reason Ruby way seems easier for me to read.
    class LambdaExpressionTest
      attr_accessor :list
      def initialize
        @list = Array.new
      end
      def add_value (val)
        @list << val
      end
      def process_each (action)
        @list.each do |val| action.call(val) end
      end
    end
    
    And use both of the mentioned. I’m not sure about the “Ruby Way” to write custom delegates, whether people prefer to keep them all in one line or separate, how they usually put tabs around. Anyways, any comments welcomed.
    expressionTest = LambdaExpressionTest.new
    
    expressionTest.add_value(MyCustomClass.new("value1", 1))
    expressionTest.add_value(MyCustomClass.new("value2", 11))
    
    expressionTest.process_each(Proc.new{ 
      |val| 
      val.str_val = val.str_val + "1" 
      val.int_val = val.int_val + 10 })
      
    expressionTest.process_each(Proc.new{ 
      |val| 
      print "%s\n" % val.str_val
      print "%d\n" % val.int_val })
    
    Syntax is clear and understandable even for a newbie like me. There’s a difference between “Proc.new” and “lambda”. You can read it up somewhere else. BUT, for some reason @list.each do action end did not work for me, when action is being passed as an argument. It worked thou in a test project, where i didn’t pass it as an argument to the method, just declared it a couple lines above the call. I’d suspect it’s some Ruby mystery and dig into it a bit later.

    Objective C

    At first, Objective C’s lambda (blocks) syntax is the worst of all described. I really want to check out Lisp sytax. Some people say it’s great. So, let’s move on. Here you’ll see way more code, since ObjC has also header files.

    MyCustomClass.h

    @interface MyCustomClass : NSObject {
        NSString *StrVal;
        int IntVal;
    }
    
    @property (readwrite, retain) NSString *StrVal;
    @property (readwrite) int IntVal;
    
    + (MyCustomClass *)createInstanceForStrVal:(NSString *)aStrVal andIntVal:(int)aIntVal;
    - (MyCustomClass *)initWithStrVal:(NSString *)aStrVal andIntVal:(int)aIntVal;
    @end

    MyCustomClass.m

    @implementation MyCustomClass
    
    @synthesize StrVal;
    @synthesize IntVal;
    
    + (MyCustomClass *)createInstanceForStrVal:(NSString *)aStrVal andIntVal:(int)aIntVal {
        return [[[MyCustomClass alloc] initWithStrVal:aStrVal andIntVal:aIntVal] autorelease];
    }
    
    - (MyCustomClass *)initWithStrVal:(NSString *)aStrVal andIntVal:(int)aIntVal {
        self = [super init];
        if (self) {
            self.StrVal = aStrVal;
            self.IntVal = aIntVal;
        }
        return self;
    }
    
    @end

    LambdaExpressionsTest.h

    @interface LambdaExpressionTest : NSObject {
        @private
        NSMutableArray *list;
    }
    
    @property(readwrite, retain) NSMutableArray *list; 
    - (LambdaExpressionTest *)init;
    - (void)addValue: (MyCustomClass *)aMyCustomClass;
    - (void)processEach: (void (^)(MyCustomClass *val))aAction;
    @end
    

    LambdaExpressionTest.m

    @implementation LambdaExpressionTest
    @synthesize list;
    
    - (LambdaExpressionTest *)init {
        self = [super init];
        if (self) {
            self.list = [[[NSMutableArray alloc] init] autorelease];
        }
        return self;
    }
    
    - (void)addValue: (MyCustomClass *)aMyCustomClass {
        [self.list addObject:aMyCustomClass];
    }
    
    - (void)processEach:(void (^)(MyCustomClass *val))aAction {
        for (MyCustomClass *el in self.list) {
            aAction (el);
        }
    }
    @end
    Usage:
    MyCustomClass *class1 = [MyCustomClass createInstanceForStrVal:@"value1" andIntVal:1];
    MyCustomClass *class2 = [MyCustomClass createInstanceForStrVal:@"value2" andIntVal:2];
    
    LambdaExpressionTest *let = [[LambdaExpressionTest alloc] init];
    [let addValue:class1];
    [let addValue:class2];
    [let processEach:^(MyCustomClass *aVal) { aVal.StrVal = [aVal.StrVal stringByAppendingString:@"1"]; aVal.IntVal += 10; }];
    [let processEach:^(MyCustomClass *aVal) { NSLog(@"%@ %d", aVal.StrVal, aVal.IntVal); }];
    
    I have a lot to tell about Objective C in that case. Most likely, since i didn’t have tons of hours worked with that language, some of my points won’t be adequate.
    • Great thing is that you can specify your property’s access level extremely easily. You can tell whether you want people to have access to the variable, or it will be copied when accessed.
    • Blocks declaration syntax is “NO-GO”. Worst syntax i’ve seen so far. Call to a block seems to be contradicting with a regular method calls (using brackets instead of square brackets), but for me, having a .NET background it’s even better at some point.
    • 10.5 SDK does not support blocks. So, you rather install 10.6 or look for a custom hacky solution. Did people invent lambdas just recently? Or there was another implementation before in ObjC? Does OCBlock sound any familiar to anyone?
    • There seems to be a better option than iterating through all the elements, but “do” described here didn’t work for me (since they applied some OCBlock science) and this code kinda convinced me that i might be right.

    Lisp

    Ok, here’s something new, at least for me. In order to store the list, i will define the global variable *list*. I will also create an accessor function add-value and create-custom-set, first to add values, second one to create the item for list in required format (with strVal and intVal inside).
    (defvar *list* nil)
    
    (defun add-value (val)
      (push val *list*))
    
    (defun create-custom-set (strVal intVal)
      (list :strVal strVal :intVal intVal))
    In order to go through all the items in list and call a custom passed action (lambda-expression), i define a process-each function.
    (defun process-each (action)
     (dolist (cd *list*)
      (funcall action cd)))
    I will also define 2 helper functions to concatenate strings and integers. For integers it’s not a best name, but you still see a pattern. They will shorten lambda expressions a bit.
    (defmethod concat ((s1 string) (s2 string))(concatenate 'string s1 s2))
    (defmethod concat ((i1 integer) (i2 integer))(+ i1 i2))
    Now lambda-expressions themselves. First one is responsible for changes, just as in previous implementations, second one just displays the contents.
    (defun first-lambda ()
      (lambda(el) 
    	(setf (getf el :strVal) 
    		  (concat (getf el :strVal) "1") )
    	(setf (getf el :intVal) 
    		  (concat (getf el :intVal) 10) )
    	))
    
    (defun second-lambda ()
      (lambda(el) (format t ":: ~a ~%" el) ))
    Now we fill up a lise with values:
    (add-value (create-custom-set "Value1" 1))
    (add-value (create-custom-set "Value2" 11))
    And make calls to lambda expressions on each item in list:
    (process-each (first-lambda))
    (process-each (second-lambda))
    My bottomline for lisp: i like a strict separation of left and right parts of expressions, and the way they’re being passed. Syntax is extremely easy to write but pretty tough to read because of brackets. Functional programming languages are fun, but tough. Changing a paradigm is always good thou.

     
    1. eartha-edwards reblogged this from ifesdjeen
    2. ifesdjeen posted this
     
blog comments powered by Disqus