Re: Cheap way to find function (defn) name using a macro?

2012-03-28 Thread Ram Krishnan
Did you just need the name of the function? something like this?

88

(def ^{:dynamic true} *myself* nil)

(defmacro defn* [name args  body]
  `(defn ~name ~args
 (binding [*myself* '~name]
   ~@body)))

(defn* foo [a b] [*myself* (+ a b)])

88

This is, of course, quite ugly and grossly oversimplified, but would work for a 
limited use case.

Cheers,

-ram 


On Wednesday, March 28, 2012 at 8:02 AM, Shantanu Kumar wrote:

 Hi,
 
 Is it possible to write a macro that when used in a top-level function
 (created using defn) can find out the name of the immediate top-level
 function? I know *ns* returns the namespace and it's possible to walk
 the current thread's stack trace to find out the function name, but I
 am looking for a computationally cheap way to do it.
 
 Thanks,
 Shantanu
 
 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com 
 (mailto:clojure@googlegroups.com)
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com 
 (mailto:clojure+unsubscr...@googlegroups.com)
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 
 


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

Re: Cheap way to find function (defn) name using a macro?

2012-03-28 Thread Ram Krishnan
On Wednesday, March 28, 2012 at 9:15 AM, Shantanu Kumar wrote:
 
 
 On Mar 28, 8:57 pm, Ram Krishnan kriyat...@gmail.com (http://gmail.com) 
 wrote:
  Did you just need the name of the function? something like this?
 
 
 Sorry, I should explained using code what I am looking for:
 
 (defmacro find-name []
 ;; some magic here
 ..)
 
 (defn foo []
 ..
 (println (find-name)) ; should print foo
 ..)
 
 I am looking for a way to write the `find-name` macro. So, you can see
 I want to use it with regular functions defined using `defn`.
 
 

If you can't use a specialized `defn` you could try something like the 
following, assuming that you need this for just a temporary while (say during 
development):

88

(def ^{:dynamic true} *myself* nil)
(defn find-name [] *myself*)

(defmacro trace [sym]
  `(let [old# ~sym]
 (def ~sym (fn [ args#]
 (binding [*myself* '~sym]
   (apply old# args#))

(defn foo [a b] [(find-name) (+ a b)])

(foo 1 2) = [nil 3]

(trace foo)

(foo 1 2) = [foo 3]

88

It requires you explicitly `trace` the functions within which you want to call 
`find-name`, otherwise the name will just be `nil`.
 
 Shantanu
 
 -- 
 You received this message because you are subscribed to the Google
 Groups Clojure group.
 To post to this group, send email to clojure@googlegroups.com 
 (mailto:clojure@googlegroups.com)
 Note that posts from new members are moderated - please be patient with your 
 first post.
 To unsubscribe from this group, send email to
 clojure+unsubscr...@googlegroups.com 
 (mailto:clojure+unsubscr...@googlegroups.com)
 For more options, visit this group at
 http://groups.google.com/group/clojure?hl=en
 
 


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

Re: ANN: clojurejs -- a Clojure (subset) to Javascript translator

2011-01-12 Thread Ram Krishnan

On Jan 12, 5:56 am, Daniel Werner daniel.d.wer...@googlemail.com
wrote:
 On Jan 11, 4:20 pm, Ram  Krishnan kriyat...@gmail.com wrote:

   * Mozilla's JS 1.7 supports a let statement[1] with lexical scoping,
   ...
  That's an interesting idea, although I'm not too keen on specializing
  for any one browser. The other problem is I don't see any reasonable
  way of providing the alternates from a web server without some form of
  user-agent sniffing.

 You're right, any potential benefits could only be reaped under very
 specific circumstances. Making the codebase more complex to optimize
 for these limited cases doesn't make sense.

 I've taken a deeper look yesterday and am positively surprised how
 much easier to understand the implementation is than expected. Very
 cool. A few design decisions caught my eye though, and could IMO be
 improved:

Glad you found the code readable, which is always a concern with Lisp
code that has evolved over the course of its author discovering the
problem he's setting out to solve :)


 Using a ref won't actually improve your concurrency experience with
 *macros* (provided I understand your code correctly). Since the
 parsing and emitting is written in an inherently linear style, there
 will only ever be one transaction altering *macros*. More problematic
 though is the case where two threads happen to concurrently translate
 completely independent (js ...) expressions. Since *macros* is global,
 both threads would share the same macro definitions even if totally
 different code bases are being translated! This problem could be
 mitigated by using thread local bindings for *macros*. Refs or atoms
 are not neccessary in this case; even plain old (set!) would do.

I agree. Funnily enough, I started out with a thread local binding
implementation, and switched to a ref because I needed macro
definitions to persist across multiple requests. Consider something
like the following:

(defroutes my-routes
  (GET /js/app.js {:content-type text/javascript
 :body (tojs
(resources-path boot.cljs)
(resources-path app.cljs))})
  (GET /login login-form-handler))

/js/app.js would load and compile the boot.cljs and app.cljs scripts
and return the resulting Javascript in one request. If all the
Javascript were done this way, there would be no issue with just
thread local bindings for *macros*. However, if you had some inline
Javascript elsewhere in a different request handler:

(defun login-form-handler []
  (let [id (gensym)]
(html
 [:div {:id id :title login}
  [:form {:id login-form}
   (text-field login-email email)
   (password-field login-password password)]
  [:p {:id login-message :class message error} ]
  (jq-let [dlg-id (str # id)]
(defn login []
  (.text ($ #login-message) login submit))
(defn do-close []
  (.dialog ($ this) close))
(.dialog ($ dlg-id)
 {:autoOpen false
  :modal true
  :height 230
  :buttons {login login
close do-close}}))])))

The issue is that the clojurejs script within the `jq-let' wouldn't
see any of the macros unless they're loaded again, which can get
expensive on each request. Ideally, the macro definitions would
persist across requests, but in independent namespaces to avoid the
collision issue you brought up. I'd like to think a cheap namespace
implementation would be a way around this (basically, macro expanders
would be kept in a global *namespaces* map with the namespace name as
key). This would have to introduce a `ns' top level form, with at
least support for :use. Or I'm open to other suggestions ...


 Another thing that strikes me as a potentially bad idea is the
 reliance on imperative behaviour to generate output, i.e. emitting
 or printing generated code to a stream instead of returning the
 pieces in a functional way and combining them afterwards. This
 imperative style could hamper your code's composability in the
 future. ... What do others think?

I completely agree. This is one of the bad side-effects (no pun
intended) of the ad-hoc origin of this library. Ideally, there should
be an intermediate representation which captures all of the Javascript
idiosyncracies, and a much simpler emitter. I made the mistake of
assuming the s-expression parse tree *was* that representation
... live and learn. The other factor is that I'm a Common Lisp hack
still getting used to writing idiomatic Clojure :)

 With all that said -- it's actually quite pleasant to work with right
 now. If you're interested in patches, I've done some small
 refactorings to remove duplicate code, added basic docstring support
 and other small fixes. Please see my fork at:

 https://github.com/danwerner/clojurejs

 Daniel

Thanks very much. I'm glad you were able to use and improve the
code. I like the refactoring you did, as well

Re: ANN: clojurejs -- a Clojure (subset) to Javascript translator

2011-01-11 Thread Ram Krishnan
On Jan 11, 3:55 am, Daniel Werner daniel.d.wer...@googlemail.com
wrote:
 Hi Ram,

 your take on Clojure to JS translation seems very interesting to say
 the least. Thanks for sharing your work.

You're very welcome, and thanks for the quick feedback.

 A few points I tripped over while reading the example:
 * Why are functions being defined as join = function (...) instead
 of function join (...)? Does this make a semantic difference?

This stems from my misunderstanding of Clojure's `defn' form. I had
started implementing Scheme like scoping for functions where,

(defn test1 []
  (defn test2 [] (+ 1 1))
  (= (test2) 2))

would generate:

var test1 = function () {
  var test2 = function () { return 1 + 1; };
  return test2() == 2;
};

This effectively would hide `test2' from the toplevel, but this isn't
the behavior of `defn' as I discovered. So, by dropping the leading
`var' in the generated Javascript, I could make all the inner
functions exposed at the top level as well. I believe there's no
scoping semantics difference between the `x = function () {...}' and
`function x () {...}' forms, unless `x' is declared somewhere in the
scope as a local var. Of course, the scoping semantics completely
change with the explicit introduction of `var x = function () {...}'.

 * if { ... } else { ...} break; is probably missing a semicolon
 before break. Don't trust JS' implicit semicolon-adding ;-)

You're absolutely right. I'll add a test case and fix that today.

 * The whole function body is being wrapped in a return function()
 { ...}(). Is this done in order to support implicit return? My guess
 is that deeply nesting such constructs could become quite performance-
 heavy due to the many additional function calls.

You're probably right. As I worked on the let/loop forms I suspected
they were probably going to have performance issues in the long run,
but I really really wanted to have consistent scoping rules. I traded
off the performance issue in the expectation that with the race to
build the fastest Javascript JIT compiler, Google, Mozilla, or Apple
will eventually solve these crazy performance gotchas in Javascript.

 * Mozilla's JS 1.7 supports a let statement[1] with lexical scoping,
 though implementation support outside of Firefox is scarce. Depending
 on your target audience and performance requirements it could be
 worthwhile to implement this as an optimization instead of using the
 function(){...}() trick, but only if allowed by some flag,
 like :features #{:let} or similar.

That's an interesting idea, although I'm not too keen on specializing
for any one browser. The other problem is I don't see any reasonable
way of providing the alternates from a web server without some form of
user-agent sniffing.


 I'm going to take a deeper look into this once I have the time.

 [1]https://developer.mozilla.org/en/New_in_JavaScript_1.7#Block_scope_wi...

 Daniel

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


ANN: clojurejs -- a Clojure (subset) to Javascript translator

2011-01-10 Thread Ram Krishnan
Hi all,

I've just released a stable version of `clojurejs' -- an
unimaginatively named Clojure library for translating a Clojure subset
language to Javascript.

clojurejs is something I've been working on for a few weeks as part of
a larger web app in Clojure. The code's a bit crufty (reflects my
incremental discovery of the inconsistencies in Javascript), but
functional and I wanted put something out there for people to check
out. I welcome bug reports and feedback. It's been useful for my
specific needs, and I'd be happy if it's even marginally useful to
others.

I realize there are a number of other efforts to compile/translate
Clojure (or other Lisp subset) to Javascript, but nothing quite fit my
requirements, which prompted me to build clojurejs. Some useful
aspects of clojurejs are:

* Consistent scoping in let and loop/recur forms
* Macros
* Implicit return
* loop/recur translates to Javascript for loops
* Translates Clojure vectors, strings, keywords, symbols and maps to
Javascript equivalents
* dot form access to methods and properties
* Adds a couple of Clojure incompatible special forms for Javascript
specific behavior

If this seems interesting I've posted a more detailed entry on my blog
(http://cynojure.posterous.com/clojurejs-a-clojure-subset-to-
javascript-tran).

Oh, and the github link: http://github.com/kriyative/clojurejs

Look forward to feedback.

Cheers,

-ram

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


Re: clojure-contrib on Windows

2010-02-18 Thread Ram
I was considering doing that, but I didn't know if people were aware
of the compilation issue on Windows so I posted it.

On Feb 17, 9:50 pm, kkw kevin.k@gmail.com wrote:
 Hi Ram,

     If you all you want is the latest .jar file, and don't feel the
 need to compile, consider bypassing the compilation and grab the
 latest successfully compiled .jar from build.clojure.org. This is what
 I now do.

 Kev

 On Feb 17, 9:51 am, Ram rve...@gmail.com wrote:

  I'm having an issue compilingclojure-contrib onWindows.

  I downloaded the code from the git repository and when I run Maven,
  after compilation it runs through the test suite fails in test-io:

  FAIL in (test-as-url) (run-test5405918110152723544.clj:47)
  expected: (= (URL. file:/foo) (as-url (File. /foo)))
    actual: (not (= #URL file:/foo #URL file:/C:/foo))

  I'm guessing someone expected UNIX style filenames in this test case
  and notWindowsfilenames, but that is besides the issue. The issue is
  that the jars aren't actually generating themselves. Am I missing
  something? If I am, its probably something really dumb.

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


clojure-contrib on Windows

2010-02-16 Thread Ram
I'm having an issue compiling clojure-contrib on Windows.

I downloaded the code from the git repository and when I run Maven,
after compilation it runs through the test suite fails in test-io:

FAIL in (test-as-url) (run-test5405918110152723544.clj:47)
expected: (= (URL. file:/foo) (as-url (File. /foo)))
  actual: (not (= #URL file:/foo #URL file:/C:/foo))

I'm guessing someone expected UNIX style filenames in this test case
and not Windows filenames, but that is besides the issue. The issue is
that the jars aren't actually generating themselves. Am I missing
something? If I am, its probably something really dumb.

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


Re: Emacs clojure-mode home?

2009-07-02 Thread Ram Krishnan

Hi Phil,

I'd sent this to jochu earlier, but perhaps you can help commit this
minor patch to clojure-mode.

I found a small bug in the regexp used in `swank-clojure-find-
package'. The head version incorrectly parses `ns' forms of the
following kind:

(ns compojure.server.jetty
 Clojure interface to start an embedded Jetty server.
 (:use compojure.control)
 (:use compojure.server.common)
 (:import org.mortbay.jetty.Server)
 (:import org.mortbay.jetty.servlet.Context)
 (:import org.mortbay.jetty.servlet.ServletHolder)
 (:import org.mortbay.jetty.security.SslSocketConnector))

and returns the package name as:

compojure.server.jetty
 Clojure interface to start an embedded Jetty server.

The following patch modifies the regexp in `swank-clojure-find-
package' to fix this:

diff --git a/swank-clojure.el b/swank-clojure.el
index 96dc91e..9e4174b 100644
--- a/swank-clojure.el
+++ b/swank-clojure.el
@@ -80,7 +80,7 @@ swank-clojure-java-path) if non-nil.
file (format %s encoding

 (defun swank-clojure-find-package ()
-  (let ((regexp ^(\\(clojure.core/\\)?\\(in-\\)?ns\\s-+[:']?\\([^()]+
)))
+  (let ((regexp ^(\\(clojure.core/\\)?\\(in-\\)?ns\\s-+[:']?\\([^()
\ \t\n]+)))
 (save-excursion
   (when (or (re-search-backward regexp nil t)
 (re-search-forward regexp nil t))

Thanks.

-ram

--
http://cynojure.posterous.com


On Jul 1, 3:47 pm, Phil Hagelberg p...@hagelb.org wrote:
 Chris Dean ctd...@sokitomi.com writes:
  Where's the current home for the Emacs clojure-mode source? I have a one
  line patch I'd like to make, but don't know where to send it!

  Is ithttp://github.com/technomancy/clojure-mode/tree/master ?

 That's my repository. Technically the canonical one is 
 athttp://github.com/jochu/clojure-mode/but I have commit access there, so
 I can take care of it. Patches here on the mailing list are welcome.

  Anyway I'll include the patch to add a local-abbrev-table here since it
  is so small.

 It looks like your patch might be incomplete; I get a void-variable:
 clojure-mode-abbrev-table when I run that.

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



Another javadoc + clojure/slime integration

2009-06-22 Thread Ram Krishnan

Hi all,

Long time reader, first time poster. Thanks to Rich and the other
contributors for all the great work on Clojure.

I recently had a chance to use Clojure on a non-trivial project, which
required integrating with a number of Java libraries. In the course of
that I was getting tired of switching back and forth between
developing in Emacs, and viewing Javadocs in Firefox. After looking at
the other javadoc integration hacks, I decided I was looking for
something else and built another one.

Ideally, I wanted to be able able to put the cursor on any java class
symbol in a clojure-mode buffer in emacs, execute M-x slime-javadoc,
and have the api documentation popup in an adjacent emacs window. With
the help of clojure, slime, and emacs/w3m, I was able to achieve
nirvana.

Anyway, I blogged about my approach (http://cynojure.posterous.com),
and put up the code on github (http://github.com/kriyative/cynojure-
swank/tree/master). Suggestions and comments are most welcome.

-ram

--
cynojure
http://cynojure.posterous.com

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



Another javadoc + clojure/slime integration

2009-06-22 Thread Ram Krishnan

Hi all,

Long time reader, first time poster. Thanks to Rich and the other
contributors for all the great work on Clojure.

I recently had a chance to use Clojure on a non-trivial project, which
required integrating with a number of Java libraries. In the course of
that I was getting tired of switching back and forth between
developing in Emacs, and viewing Javadocs in Firefox. After looking at
the other javadoc integration hacks, I decided I was looking for
something else and built another one.

Ideally, I wanted to be able able to put the cursor on any java class
symbol in a clojure-mode buffer in emacs, execute M-x slime-javadoc,
and have the api documentation popup in an adjacent emacs window. With
the help of clojure, slime, and emacs/w3m, I was able to achieve
nirvana.

Anyway, I blogged about my approach (http://cynojure.posterous.com/
clojure-emacs-and-javadocs), and put up the code on github (http://
github.com/kriyative/cynojure-swank/tree/master). Suggestions and
comments are most welcome.

-ram

--
cynojure
http://cynojure.posterous.com

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