Ruby blocks are anonymous functions with syntax sugar. You could write
James' with_open method like this:

def with_open(stream, &f)
  f.call(stream)
end

The equivalent in Clojure is effectively the same:

(defn with-open [stream f]
  (f stream))

On Oct 25, 9:31 am, James Reeves <[email protected]> wrote:
> I don't think that's a very good example of what macros can do. As you
> point out, you can do much the same thing in Ruby with blocks:
>
> with_open(MyStream.new) do |stream|
>   stream.write "Hello"
> end
>
> In Clojure, blocks are analogous to anonymous functions. So the
> equivalent Clojure would be:
>
> (with-open (MyStream.)
>   (fn [stream]
>     (.write stream "Hello")))
>
> You could use a macro to make this more concise:
>
> (with-open [stream (MyStream.)]
>   (.write stream "Hello"))
>
> But whilst this is useful, this doesn't really demonstrate why macros
> are so powerful. Macros are useful because they automatically
> rearrange your source code into something else. They're most similar
> to the Ruby 'eval' function, but operate of data structures rather
> than strings.
>
> For example, the macro '->' changes this:
>
> (-> x (foo y) (bar z))
>
> Into this:
>
> (foo (bar x z) y)
>
> - James
>
> On Oct 25, 1:55 pm, Daniel Bush <[email protected]> wrote:
>
>
>
> > hi,
> > I'm new to lisp/clojure
> > in general.  I was reading the free whitepaper from Amit
> > Rathore's 'Clojure in Action' where he gives a simple
> > example on macros.
>
> > In the example on page 9 he shows how you might do an
> > audited connection in java:
>
> > public void addExpense(long userId, Date date, BigDecimal amount) {
> >    AuditLogger.logLookup(userId, AuditCode.ADD_EXPENSES);
> >    ExpensesConnection connection = new ExpensesConnection(userId);
> >    connection.saveNewExpense(date, amount);
> >    connection.flush();
> >    connection.close();
>
> > }
>
> > In clojure he shows a macro (without showing the code[1])
> > that boils it down to:
>
> > (defn add-expense [user-id date amount]
> >   (with-audited-connection [user-id connection]
> >     (save-new-expense connection date amount)))
>
> > So in ruby you can be pretty concise here - in fact
> > I differ with the author who says it isn't as good:
>
> > def add_expense user_id , date , amount
> >   with_audited_connection(user_id,'audit code') do |conn|
> >     conn.save_new_expense date , amount
> >   end
> > end
>
> > where with_audited_connection might be something like:
>
> > def with_audited_connection user_id , audit_code
> >   puts "logging conn for '#{user_id}' (#{audit_code})"
> >   conn = ... # Get a connection.
> >   yield conn # Expose conn in block - see above.
> >   puts "closing conn or whatever"
> > end
>
> > ('puts' just means print to stdout)
>
> > The second function above organises the connection 'conn'
> > and then yields it for use elsewhere in a block (see the
> > do-block in the first function).  After that block finishes,
> > the yield returns and the the 2nd function tidies up and
> > does whatever else it needs to.
>
> > Bear in mind, I'm really new to lisp in general.
> > So is 'connection' in
> >   (with-audited-connection [user-id connection] ... )
> > being filled in by the macro or is the example assuming that
> > 'connection' has already been defined elsewhere?
> > Can clojure do something like the 'yield' in the ruby
> > example above (which I think is one of ruby's strengths
> > coming from smalltalk)?
>
> > I know you might say something like: "go learn some lisp
> > and macros and you'll know what the author is trying to
> > say", but I was hoping for just a quick indication on what is
> > going on here - I'll continue learning clojure in the
> > background anyway so I guess it'll eventually twig.
>
> > Cheers,
> > Daniel Bush
>
> > [1] I know the example is just there to whet the appetite
> > and is not part of a particular lesson or chapter.

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your 
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to