Skip to content

Instantly share code, notes, and snippets.

@keithrbennett
Last active November 12, 2020 18:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save keithrbennett/39d188b5df78f2b4821e29cc6efde71a to your computer and use it in GitHub Desktop.
Save keithrbennett/39d188b5df78f2b4821e29cc6efde71a to your computer and use it in GitHub Desktop.

Functional Programming in Ruby with Lambdas

Chicago Ruby Meetup, 2020-10-06, presented by Keith Bennett (@keithrbennett)

Notes and Errata:

Some practical application of these concepts can be seen in my "Writing a Command Line Application in Ruby" presentation at Paris.rb Conf in 2018 (https://www.youtube.com/watch?v=zMzzKOecvaA).


The slides use Jetbrains Mono font with ligatures. If you see unfamiliar characters, they are ligatures, which are textual representations of special character sequences. Examples are ->, >=, <=, <>, ||=. (Explained while answering Bryan's question at 11:45.)


3:28 (Slide #13) I said "...all of our coding is at the method level". I should have left it at "most". Coding is also done in lambdas, class definitions (constant definitions, calls to class methods such as attr_accessor), etc.


04:30 (13) I don't remember Matz' exact words, and may be embellishing, but I did not make this up! :)

By the way, it is possible to define a method inside another method, but that method becomes a regular instance method and is not nested or scoped in any way.


5:54 (15) - I said that the number of possible paths of interaction for a 20-method class was 390, but I should have said 380 (20 * (20 - 1)).


13:14 (21) - There are several instances in the presentation where a trivially simple example is used to illustrate usage, etc., but where in that particular case the use of a lambda would be overkill. The "Lambdas and Threads" slide is one of them. For example, it would be fine to use { `uptime` } in the thread code instead of the lambda.


16:10 (22) - I checked, and lambda is a method in the Kernel module, and not a language keyword.


21:46 (28) - I said "Nicole?" but I should have said "Miriam?". Sorry, Nicole and Miriam!


30:20 (31) - I was unclear about the testability of lambdas. The situation where they cannot be tested is when they are local to a method. If they are exposed to be accessible to the test code (e.g. returned by a method or contained in a class constant) then they can be tested. So when I said "if something does need to be testable by itself then it should be a method" was not correct. (Nicole, I apologize for this, I realize that one of your comments later on was based on this misrepresentation.)


38:20 (37) - Regarding Bryan's question "are lambdas hoisted?", I should have pointed out that it's not objects that are hoisted, it's variables. For example, iff a method contains this:

def foo
  if false
    my_lambda = -> { }   # this would behave the same if it were: my_lambda = 333
  end
  p my_lambda
end

...then calling foo will result in the output nil. However, it really doesn't matter what type of object is assigned, since hoisting is done on variables, not the values (or lack thereof) they contain.


41:36 (41) More about lambdas vs. code blocks for passing filters...I did not explain that one of the requirements was to support unfiltered lists. Given that, the code needs a way not to filter messages. In the case of the lambda parameter, we can specify a default argument, a lambda that always returns true. If the caller omits this last parameter, then messages will not be filtered.

In the code that uses code blocks, we can check block_given?, assuming that not passing a block means that no filtering is wanted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment