Clojure
Rich Hickey discusses Clojure features and syntax, example code, functional programming, concurrency semantics, transactions, software transactional memory, agents, implementation and pain points.
- Java,
Tracking change and innovation in the enterprise software development community
Posted by Werner Schuster on Jan 15, 2008 08:00 AM
Ruby's Blocks are one of the crucial features that allow to write concise and highly reusable algorithms. If nothing else, it helped to extinguish the venerablefor loop. The concept has many names in other languages and theory:
x = lambda {|x,y| x + y}
doesn't use any free variables (i.e. variables that are unbound; x and y are declared in formal argument list), and hence doesn't require the creation of a closure (lambda (arg) "hello world").[arg| ^"hello world"]. do/end or braces {/}. Eg.
5.times {|x| puts x}
It's convenient, and also allows idioms such as Builder, which allows to create hierarchical data structures very easily by using a nested Blocks. (Tip: An upcoming article here on InfoQ will explain the details of creating a Builder in Ruby - watch out for it in the 2nd half of January). Proc.new {} or lambda {} notations. While not horrible, these options are much more verbose and introduce unwelcome tokens that clutter up the code. (Note: Proc.new {} and lambda {} notations have subtle differences as well, but this is not significant in this context).find (predicate {|x,y| x < y}, predicate{|x,y| x > 20})
The predicate function is nothing more than:def predicate(&b)I.e. returns the Block. Whether this is appropiate or not depends on the specific use case. In this case, the shown code is - arguably - more expressive then the equivalent:
b
end
find (lambda{|x,y| x < y}, lambda {|x,y| x > 20})
lambda leaks implementation details about how this is implemented - with one block argument, no extra keyword would be needed. The predicate solution annotates the code and generates the lambda. To be clear: this is a workaround. x = ->{puts "Hello Lambda"}
The new syntax is shorter and removes the unfamiliar term lambda. To be clear: this is syntactic sugar. It does, however, help to write APIs that yield very readable code. Some of these APIs might be called "internal DSLs", although the definition for those are quite fuzzy. For these, the new lambda definition helps getting rid of the quite obscure term "lambda" in the middle of otherwise purely domain or problem specific code. Explicitly invoking one block from another in Ruby 1.9.0. This method was something I didn't even cover in my previous post, because the parser would simply blow up when parsing |*args, &block|. Here's what it looks like. [..]This code doesn't work in Ruby 1.8.x - it actually fails at the parser stage with:class SandBox
def abc(*args)
yield(*args)
end
define_method :xyz do
|*args, &block|
block.call(*args)
end
end
SandBox.new.abc(1,2,3){|*args| p args} # => [1, 2, 3]
In Ruby 1.9, this works fine.benchmark3.rb:8: syntax error, unexpected ',', expecting '|'
define_method :xyz do |*args, &block|
^
benchmark3.rb:11: syntax error, unexpected kEND, expecting $end
foo = "Outer Scope"In 1.8, the code would print "I'm not local to this block", wheras in 1.9 it prints "Outer Scope". In short, blocks now behave as expected: the block argument shadows the variable of the same name in the outher scope inside the block. (Let's preempt the question "How can I access the variable in the outer scope?". You don't - just choose a different name for the block argument).
[1,2,3].each{|foo|
foo = "I'm not local to this block"
}
puts foo
Succeeding with Agile at Scale Educational eKit from IBM
Evolutionary Design through Agile Development Podcast
Architectural Quality: Design, Development and Testing Rules
Offshore software development: Making it a success with Agile Practices
I thought the lambda word was clear, and makes perfect sense what you are doing. I guess its just taste. the shadowing is nice, and will either break a lot of existing code (which was bad to start with) and/or get rid of a confusing class of bugs.
Note also that 1.9 allows for default parameters to proc's:
z = proc {|x, y = 3| 33 }
Rich Hickey discusses Clojure features and syntax, example code, functional programming, concurrency semantics, transactions, software transactional memory, agents, implementation and pain points.
We introduce the concept of Composite Oriented Programming, and show how it avoids the issues with OOP and reignites the hope of being able to compose domain models with reusable pieces.
Dan Farino talks about the system architecture and the challenges faced when building a very large online community. Dan explains how a .NET product scales on hundreds of servers.
Alan Shalloway, CEO and founder of Net Objectives, presents the Lean software development principles and practices and how they can benefit to Agile practitioners.
Bernd Mathiske discusses Maxine VM, Java compatibility, swapping major VM components, research areas, Object handling, code examples, optimizing compiler, snippets, bytecode generation, JNI and JIT.
Joe Armstrong speaks on various aspects of the Erlang language, presenting its roots, how it compares with other languages and why it has become popular these days.
The java double-check singleton pattern is not thread safe and can’t be fixed. In this article, Dr. Alexey Yakubovich provides an implementation of the Singleton pattern that he claims is thread-safe.
Diana and Jim talk about patterns observed in CTOs' activity. CTOs emerge as real people caring for other people in their organization, and are put under a lot of pressure and constraints.
2 comments
Reply