Re: Clojure list syntax sugar: f(x) notation

2011-12-28 Thread Peter Danenberg
Quoth Louis Yu Lu on Boomtime, the 70th of The Aftermath:
 The proposed syntax sugar apparently pleases my eyes and fingers
 from conventional languages. With some experiments, I found the code
 is more readable for me to use f(x) notation for function call, and
 (op x) for operator.

It sounds like you're interested in M-expressions [1]; anyone care to
implement M-expressions for Clojure as reader macros [2]?

Footnotes: 
[1]  http://en.wikipedia.org/wiki/M-expression

[2]  https://github.com/klutometis/reader-macros

-- 
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 list syntax sugar: f(x) notation

2011-12-28 Thread Peter Danenberg
Since square brackets have been usurped by vectors, angle brackets
could be used to approximate M-expressions.

Quoth Ambrose Bonnaire-Sergeant on Boomtime, the 70th of The Aftermath:
 Why not use fx ?
 
 On Thu, Dec 29, 2011 at 12:49 PM, Louis Yu Lu louisy...@gmail.com wrote:
 
  Instead of using overloaded (), may be f[x] will cause less trouble,
  and more inline with clojure's syntax as [ ] already being used for
  defining the arguments of the function.
 
  Louis
 
  On Dec 27, 5:26 pm, Gert Verhoog m...@gertalot.com wrote:
   On 26/12/2011, at 6:23 PM, Louis Yu Lu wrote:
  
My proposition is enhance Clojure to accept both (f x) and f(x)
  
   Fortunately, I don't see that happening, for several reasons (many of
  which have been mentioned). It adds complexity, causes confusion and
  inconsistent coding styles and it will break everything that parses
  s-expressions (data = code after all). Imagine trying to read lisp code
  that is a mix-n-match of the following:
  
   ;; the following would be equivalent:
   (g (f a b))
   (g f(a b))
   g((f a b))
   g(f(a b))
  
   ;; the following would be equivalent:
   ((f a) b)
   (f(a) b)
   (f a)(b)
   f(a)(b)
  
   FOUR different ways of expressing ((f a) b). How is that helping those
  trying to learn Clojure?
  
   Also, note that (g f(a b)) and (g f (a b)) have very different
  semantics, even though the only difference is the added whitespace between
  two tokens.
  
   If you stick with the elegant simplicity of s-expressions for a few more
  weeks, I promise that you won't even notice it anymore and you'll find that
  it's perfectly readable.
  
   cheers,
   gert
 
  --
  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
 
 
 -- 
 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

-- 
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


Why are body-macros more fashionable than thunks?

2011-12-22 Thread Peter Danenberg
Scheme, for instance, obeys the Law of Macro-Parsimony: don't use
defmacro, namely, where defn will suffice; Clojure, on the other
hand, is macro-liberal.

In other words, everyone seems to prefer e.g. `(defmacro foo [vars 
body] `(do ... ~@body))' where `(defn foo [vars thunk] ... (thunk))' would
suffice; cases in point:

  with-bindings 
  with-bindings* 
  with-in-str 
  with-local-vars 
  with-open 
  with-out-str 
  with-precision 
  with-redefs 

Why?

-- 
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: Why are body-macros more fashionable than thunks?

2011-12-22 Thread Peter Danenberg
Thanks, Cedric: I suspected that convenience was a primary motivation
(and maybe analogy with `defn', etc.); and I realized that macros can
be more efficient than their equivalent function.

It hadn't occurred to me, though, that a shallow stack might come into
play; or {un,}boxing, of all things.

Quoth Cedric Greevey on Sweetmorn, the 64th of The Aftermath:
 On Thu, Dec 22, 2011 at 4:54 PM, Peter Danenberg p...@roxygen.org wrote:
  Scheme, for instance, obeys the Law of Macro-Parsimony: don't use
  defmacro, namely, where defn will suffice; Clojure, on the other
  hand, is macro-liberal.
 
  In other words, everyone seems to prefer e.g. `(defmacro foo [vars 
  body] `(do ... ~@body))' where `(defn foo [vars thunk] ... (thunk))' would
  suffice; cases in point:
 
   with-bindings
   with-bindings*
   with-in-str
   with-local-vars
   with-open
   with-out-str
   with-precision
   with-redefs
 
  Why?
 
 Syntax convenience. Less need for #(...) lambdas cluttering the code.
 Particularly helpful when nested, since the #(...) lambda syntax
 doesn't nest and you'd start needing (fn [x y] ...)s as well.
 
 Also, if the macro isn't implemented with a thunk passed to a helper
 function under the hood, the macro saves a couple of stack frames, and
 on the JVM stack can run out relatively easily. With chained lazy
 functions (e.g. (map (filter (map (... (partition 3 some-seq)) and
 recursion this becomes even more significant.
 
 Lastly, in some cases avoiding function calls may save having to box
 and unbox primitives, though less so with 1.3 than with previous
 versions of Clojure.
 
 -- 
 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
 

-- 
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: Why are body-macros more fashionable than thunks?

2011-12-22 Thread Peter Danenberg
Quoth Kevin Downey on Sweetmorn, the 64th of The Aftermath:
 Why do you care?

SICP-forged neural pathways, basically; I'll end up writing e.g.:

  (defn with-input-from-file [file thunk] ...)

only to censor myself: shit, we don't do thunks.

At that point, I'll bust out `defmacro' with reluctance.

-- 
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] reader-macros

2011-12-21 Thread Peter Danenberg
Despite Brian Carpenter's warning about torches and pitchforks [1],
I've decided to release a reader-macros package; may Zeus forgive me
for opening this pithos:

  https://github.com/klutometis/reader-macros

Here's a trivial example where we implement a reverse-string reader:

  (use '[clojure.string :only (reverse)])

  (set-macro-character \
   (fn [reader quote]
 (reverse (macro-read-string reader quote

  (println hello, reader macros)
  = sorcam redaer ,olleh

My friend Evan Gamble [2] mentioned that he might use reader macros
for parsing his new language Timeless; in which case, we'd have an
actual use-case.

Until then, we have new toys.


Footnotes: 
[1]  http://briancarper.net/blog/449/

[2]  https://github.com/egamble

-- 
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] reader-macros

2011-12-21 Thread Peter Danenberg
Quoth Aaron Cohen on Setting Orange, the 63rd of The Aftermath:
 Ha, I just looked at the source, it's really weird to see λ in
 clojure code.

That's a little idiosyncrasy of mine: I've been chastised for it in
the past; maybe `lambda' would be more readable?

-- 
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] reader-macros

2011-12-21 Thread Peter Danenberg
Quoth Aaron Cohen on Setting Orange, the 63rd of The Aftermath:
 One thing I'd really want before I even considered using this would
 be some way of restricting the scope of a reader macro to the
 current file. As is, they just have way too much room to interfere
 with your whole world. I'm not sure if that's possible without
 modifying clojure.core though.

That's a great idea; I notice lots of interesting things in LispReader
[1] are static, though. If you could synchronize on read, I suppose,
it might be possible to modify the read-tables; read; and reset the
read-tables.

Footnotes: 
[1]  
https://github.com/clojure/clojure/blob/master/src/jvm/clojure/lang/LispReader.java#L82

-- 
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] reader-macros

2011-12-21 Thread Peter Danenberg
Quoth Aaron Cohen on Setting Orange, the 63rd of The Aftermath:
 Oh excuse me, I was misreading what is going on here with the
 lambda.  I thought it was a reader macro, but you're just pulling
 that alias in from some dependency.

Exactly: `λ' and `defλ' are just vanilla macros that shadow `fn' and
`defn', respectively.

-- 
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: let-else macro

2011-12-07 Thread Peter Danenberg
Thanks, Evan; I had a use-case where the truthiness of nil would have
forced me out of `let-else.' This new predicate-abstraction is
beautiful.

Quoth Evan Gamble on Sweetmorn, the 49th of The Aftermath:
 Thanks for your comment, Sam.
 
 Before you posted the comment, Peter Danenberg had asked if I would
 modify let-else to include the behavior of your let? macro. Your
 comment and his request have spurred me to action.
 
 I've modified the macro to accept optional :when pred and :else
 expr clauses after bindings. The :when clause acts just like
 your :ensure clause.
 It works with just :when or just :else or both, in either order.
 
 I've also renamed my macro to be let?, because with the addition
 of :when, the name let-else doesn't make sense.
 
 The jar is still at https://clojars.org/org.clojars.egamble/let-else
 The code is still at https://github.com/egamble/let-else
 
 - Evan
 
 On Dec 6, 7:13 pm, Sam Ritchie sritchi...@gmail.com wrote:
  I had a pattern that kept popping up in code of:
 
  (let [x (foo)
        y  (bar)]
      (when y
         (let [ ]
             )))
 
  that check jarred me, so I put this 
  together:https://gist.github.com/1347312. On reflection, discomfort with 
  indentation
  levels probably isn't near the top of the to macro or not to macro?
  checklist.
 
  (defmacro let?
  [bindings  body]
   (let [[bind [kwd pred  more]] (split-with (complement #{:ensure})
  bindings)]
  `(let [~@bind]
   ~@(cond (and kwd more) [`(when ~pred (check-let [~@more] ~@body))]
  kwd [`(when ~pred ~@body)]
   :else body
 
  (let? [x 100
  y 300
   :ensure (pos? y)
  z (- y 250)]
   z)
 
  ;; expands to
 
  (let [x 100
  y 300]
   (when (pos? y)
  (let [z (- y 250)]
   z))) ;; = 50
 
  ;; and returns 50. The following returns nil:
 
  (let? [x 100
 
         y 300
 
         :ensure (neg? y)
 
         z (- y 250)]
        z) ;; = nil
 
 
 
 
 
 
 
 
 
  On Tue, Dec 6, 2011 at 11:51 AM, Evan Gamble solar.f...@gmail.com wrote:
   I noticed in my code that I often nest a let inside an if-let, or vice-
   versa, so I wrote a macro let-else that expands into nested lets,
   except where there's an :else expr after a binding, in which case
   that binding expands into an if-let.
 
   E.g.
 
   (let-else
    [foo (f1) :else (e)
     bar (f2)]
    (b1)
    (b2))
 
   expands into
 
   (if-let [foo (f1)]
    (let [bar (f2)]
      (b1)
      (b2))
    (e))
 
   The jar is athttps://clojars.org/org.clojars.egamble/let-else
   The code is athttps://github.com/egamble/let-else
 
   - Evan
 
   --
   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
 
  --
  Sam Ritchie, Twitter Inc
  703.662.1337
  @sritchie09
 
  (Too brief? Here's why!http://emailcharter.org)
 
 -- 
 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
 

-- 
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: on lisp and scheme macros

2011-12-03 Thread Peter Danenberg
This talk of Scheme macros is a little weird: are we talking syntax-case, 
explicit-renaming, or unhygienic defmacro? Scheme has them all.

There are also implementation-specific mechanisms for writing reader macros: 
what's left?


On Dec 3, 2011, at 14:57, Stuart Sierra the.stuart.sie...@gmail.com wrote:

 I think that Common Lisp macros are, strictly speaking, more powerful than 
 Scheme macros, but I don't have a citation.
 
 -S
 
 -- 
 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

-- 
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: stack overflow vs scheme

2011-12-02 Thread Peter Danenberg
Quoth john.holland on Sweetmorn, the 44th of The Aftermath:
 It seems to me that as general solutions to stack overflow,
 trampoline and recur are very valuable. I had gotten the mistaken
 idea that Scheme was somehow immune to the problem.

Trampoline and recur are a poor man's tail-call-optimization; and, if
by the problem, you mean that a call-stack grows linearly with its
recursive depth: yeah, even Scheme is susceptible to stack-growth if
your calls aren't properly tail-recursive.

See R5RS s. 3.5 [1], Proper tail recursion:

  A tail call is a procedure call that occurs in a tail context;
  e.g. the last expression within the body of a lambda expression.

William Clinger wrote a paper that formalizes proper tail recursion in
more depth [2].

Suffice to say, the naïve recursive implementation of quick sort
contains at least one non-tail-call; and, just for kicks, here's an
implementation of quicksort in Joy (a so-called concatenative
language):

  [small] [] [uncons [] split] [swapd cons concat] binrec

Joy, too, implements recursion (through `binrec') without growing the
call-stack.

Footnotes: 
[1]  
http://www.schemers.org/Documents/Standards/R5RS/HTML/r5rs-Z-H-6.html#%_sec_3.5
[2]  ftp://ftp.ccs.neu.edu/pub/people/will/tail.pdf

-- 
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: cadr: `car', ..., `cddddr' in Clojure

2011-12-01 Thread Peter Danenberg
This is fantastic, Alan; I haven't gotten around to LoL yet, but maybe
I should.

Quoth Alan Malloy on Setting Orange, the 43rd of The Aftermath:
 LoL lets you write:
 
 (with-cxrs
   (blah (foo (bar (cadddar x)
 
 ie, it looks in your source, sees what you need defined, and makes a
 letfn.
 
 This looked fun, so I banged out an implementation:
 
 (defn cxr-impl [name]
   (when-let [op (second (re-matches #c([ad]+)r name))]
 `(comp ~@(map {\a `first \d `rest} op
 
 (defmacro with-cxrs [ body]
   (let [symbols (remove coll? (tree-seq coll? seq body))]
 `(let [~@(for [sym symbols
:let [impl (cxr-impl (name sym))]
:when impl
thing [sym impl]]
thing)]
~@body)))
 
 user (macroexpand-1 '(with-cxrs (inc (caadaaddadr x
 (let [caadaaddadr (comp first first rest first first rest rest first
 rest)]
   (inc (caadaaddadr x)))
 
 On Nov 30, 11:27 pm, Tassilo Horn tass...@member.fsf.org wrote:
  Peter Danenberg pe...@factual.com writes:
 
  Hi Peter,
 
   Try as I might, I can't purge these anachronisms; so here are `car' to
   `cr' in all their glory:
 
    http://clojars.org/cadr
 
  Nice. :-)
 
   This implementation uses a Kleene-closure around the alphabet {a, d}
   to generate the names; and a macro to define them:
 
    https://github.com/klutometis/cadr/blob/master/src/cadr/core.clj
 
  Is that inspired by the `cxr' macro (I think, that was its name) in Let
  Over Lambda?  One nice feature that seems missing from your version is a
  macro for defining local functions on demand.  I don't remember the
  exact LoL syntax, but probably it would look something like that:
 
  (with-cxrs [foo caaaddaddr,
              bar car]
    (cons (foo myseq) (bar mysec)))
 
  Bye,
  Tassilo
 
 -- 
 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
 

-- 
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] cadr: `car', ..., `cddddr' in Clojure

2011-11-30 Thread Peter Danenberg
Try as I might, I can't purge these anachronisms; so here are `car' to
`cr' in all their glory:

  http://clojars.org/cadr

This implementation uses a Kleene-closure around the alphabet {a, d}
to generate the names; and a macro to define them:

  https://github.com/klutometis/cadr/blob/master/src/cadr/core.clj

-- 
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