raganwald
Thursday, March 15, 2007
  Coming soon...

require "test/unit"

class TestComprehension < Test::Unit::TestCase

def test_simple_cases
with Comprehension::DSL do
assert_equal(
[1, 2, 3],
list { x + 1 }.given(:x => 0..2) )
assert_equal(
[[0, :a], [0, :b], [1, :a], [1, :b]],
list { [x, y] }.given(:x => [0, 1], :y => [:a, :b]) )
assert_equal(
[2, 4, 6, 8, 10],
list { x }.given(:x => 1..10) { x % 2 == 0 } )
end
end

def plus_seven num
num + 7
end

def times_maker num
lambda { x * num }
end

def test_closure_cases
two = 2
triple = times_maker(3)
with Comprehension::DSL do
assert_equal(
[2, 4, 6],
list { x * two }.given(:x => 1..3) )
assert_equal(
[3, 6, 9],
list(&triple).given(:x => 1..3) )
assert_equal(
[8, 9, 10],
list { plus_seven(x) }.given(:x => 1..3) )
end
end

end


March 16, 2007: An Approach to Composing Domain-Specific Languages in Ruby

Labels:

 

Comments on “Coming soon...:
This better be FizzBuzz related, or I'm demanding a complete refund.
 
I presume that you're running the 'value' block, e.g. { [x,y] } with an internal binding that includes variables made from :x, :y. Although this lets you omit the |x,y| noise, won't it stop you from using closure blocks?
 
The very moment you use a modulus operator, someone has to ask about FizzBuzz...

Seriously, I did consider writing a post about how the value of a piece of code lies in what you learned writing it not, in its final form.

So if someone hands you a list comprehensions gem and you write FizzBuzz in it, you learn a little if you have never used comprehensions in languages like Python or Haskell before.

Or if you actually write a comprehensions gem... you learn even more!
 
Steve:

Although this lets you omit the |x,y| noise, won't it stop you from using closure blocks?

Do you mean, won't it stop me from using another variable captured from its surrounding lexical scope?

Or do you mean, won't it stop me from using a block purloined from somewhere else as a first-class value?

Either way, answers coming up very shortly in the form of more unit tests.

Thanks for either question, and if you were actually thinking of another case entirely, please write back, either with a suggested test case or a simple explanation.
 
I was thinking of the first case, imagining that I would like to use a local method within the 'value' block. Looking forward to seeing what you come up with, because this is a neat hack.
 
Steve:

Well, lookitthat! The exact case you suggest works as well as the two cases I thought you might have been suggesting.

Everything works right out of the box so far. The reason why they work is that the blocks for "mapping" and "selecting" the comprehension both have let semantics.

Not let as in Scheme, but the version of let I wrote as part of my DomainSpecificLanguages package handles these cases. The Comprehensions DSL dynamically generates lets. A little like a macro that writes a macro that write lambdas in Lisp.

Only it's more of a kludge than a hack ;-)
 




<< Home
Reg Braithwaite


Recent Writing
Homoiconic Technical Writing / raganwald.posterous.com

Books
What I‘ve Learned From Failure / Kestrels, Quirky Birds, and Hopeless Egocentricity

Share
rewrite_rails / andand / unfold.rb / string_to_proc.rb / dsl_and_let.rb / comprehension.rb / lazy_lists.rb

Beauty
IS-STRICTLY-EQUIVALENT-TO-A / Spaghetti-Western Coding / Golf is a good program spoiled / Programming conventions as signals / Not all functions should be object methods

The Not So Big Software Design / Writing programs for people to read / Why Why Functional Programming Matters Matters / But Y would I want to do a thing like this?

Work
The single most important thing you must do to improve your programming career / The Naïve Approach to Hiring People / No Disrespect / Take control of your interview / Three tips for getting a job through a recruiter / My favourite interview question

Management
Exception Handling in Software Development / What if powerful languages and idioms only work for small teams? / Bricks / Which theory fits the evidence? / Still failing, still learning / What I’ve learned from failure

Notation
The unary ampersand in Ruby / (1..100).inject(&:+) / The challenge of teaching yourself a programming language / The significance of the meta-circular interpreter / Block-Structured Javascript / Haskell, Ruby and Infinity / Closures and Higher-Order Functions

Opinion
Why Apple is more expensive than Amazon / Why we are the biggest obstacles to our own growth / Is software the documentation of business process mistakes? / We have lost control of the apparatus / What I’ve Learned From Sales I, II, III

Whimsey
The Narcissism of Small Code Differences / Billy Martin’s Technique for Managing his Manager / Three stories about The Tao / Programming Language Stories / Why You Need a Degree to Work For BigCo

History
06/04 / 07/04 / 08/04 / 09/04 / 10/04 / 11/04 / 12/04 / 01/05 / 02/05 / 03/05 / 04/05 / 06/05 / 07/05 / 08/05 / 09/05 / 10/05 / 11/05 / 01/06 / 02/06 / 03/06 / 04/06 / 05/06 / 06/06 / 07/06 / 08/06 / 09/06 / 10/06 / 11/06 / 12/06 / 01/07 / 02/07 / 03/07 / 04/07 / 05/07 / 06/07 / 07/07 / 08/07 / 09/07 / 10/07 / 11/07 / 12/07 / 01/08 / 02/08 / 03/08 / 04/08 / 05/08 / 06/08 / 07/08 /