What does ^{} actually translate to?

2014-05-08 Thread Pascal Germroth
Hi,

I'm trying to attach metadata to some values (not the vars holding them).
I thought ^{x} y was the same as (with-meta y {x}), but while it works for 
f2/f4, f1's metadata is nowhere to be found, while f3 works as expected:

(def f1 "doc" ^{:x 1} (partial inc))
(meta f1) ; nil, unexpected
(meta #'f1) ; contains :doc, but not :x, as expected

(def f2 "doc" ^{:x 2} #(inc %))
(meta f2) ; {:x 2}, as expected
(meta #'f2) ; contains :doc, but not :x, as expected

(def f3 "doc" (with-meta (partial inc) {:x 3}))
(meta f3) ; {:x 3}

(def f4 "doc" (with-meta #(inc %) {:x 4}))
(meta f4) ; {:x 4}

Cheers,

-- 
pascal

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Clojure TCP client using Java Socket

2014-05-08 Thread Dylan Gleason
I am trying to write a TCP client in Clojure for a networking assignment. 
While everyone else is using C or C#, I elected to use Clojure and Java 
sockets, but am naturally running into problems and can't figure out for 
the life of me what I am doing wrong.

The goal is to send a message to the instructor's server and process the 
response from the server. The request message must meet the following 
requirements:

   - Request must be encoded as bytes, where the header - the first two 
   bytes - represents a short integer conveying the length of the request 
   (excluding the header itself)
   - Message must be sent in Big Endian byte order
   
The following code shows my TCP client:

*(defn- receive*
*  "Given a socket create a DataInputStream and process the server*
*  response"*
*  [reader socket]*
*  (let [bytes-in  (make-array Byte/TYPE util/max-message-size)*
*info {:type :receive :socket socket :count 
util/max-message-size}]*
*(log info)*
*(.read reader bytes-in 0 util/max-message-size)*
*bytes-in))*

*(defn- transmit*
*  "Given a socket create a DataOutputStream and process the request to*
*  the server"*
*  [writer socket message]*
*  (let [bytes-out   (req/make-request (into {:socket socket} message))*
*begin-info {:type :begin-transmit :socket socket :message 
bytes-out}*
*end-info   {:type :end-transmit :writer writer}]*
*(log begin-info)*
*(.write writer bytes-out 0 (count bytes-out))*
*(log end-info)*
*(.flush writer)))*

*(defn send-request*
*  "Given a create a Socket and process the request"*
*  [msg]*
*  (with-open [socket (java.net.Socket.  (:host-ip msg) (:host-port msg))*
*  writer (DataOutputStream. (.getOutputStream socket))*
*  reader (DataInputStream.  (.getInputStream socket))]*
*(log {:type :client})*
*(transmit writer socket msg)*
*(receive reader socket)))*

And here is the output this produces by calling send-request with some test 
data:

Initializing the TCP client ...

Transmitting request
---
Message Size : 124 bytes
Host IP  : /192.168.xxx.xxx
Host Port: 2605

0 121 124 82 69 81 124 0 0 1 69 -38 63 103 2 124 108 10 75 27 12 99 82 52 
109 107 58 111 16 95 45 13 114 127 3 69 124 71 108 101 97 115 111 110 78 
105 99 107 111 108 105 99 104 68 124 49 57 45 49 53 57 54 124 48 124 47 49 
57 50 46 49 54 56 46 49 46 49 50 51 124 53 52 51 54 50 124 50 49 124 47 49 
57 50 46 49 54 56 46 49 48 49 46 50 49 48 124 50 54 48 53 124 72 101 108 
108 111 32 116 104 101 114 101 124 49

Bytes written: 124 bytes

Receiving response

Maximum Size : 146 bytes
Host IP  : /192.168.xxx.xxx
Host Port: 2605

.

No response from the server. It looks like my byte array is correct (as you 
can see the byte at index 0 is 0, followed by 121 representing the length 
of the request -- though the "bytes written" does appear to be 1 more than 
it should). Also, my understanding is that DataOutputStream sends data in 
Network order by default -- is this correct?

My next step is to try writing an echo server to see if I can at least 
communicate to myself. In the mean time, if anyone has any insight, it 
would be much appreciated!


-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: determining repl environment vs. uberjar environment?

2014-05-08 Thread Dave Tenny
Here's a solution to the problem I was trying to solve.  I'm not happy with
it (the definition of has-repl?), but it's working for now.
It's also Sun/Oracle JVM specific with the sun.java.command clause.

Again, the problem is that I wanted an exit routine I could call that
wouldn't terminate the jvm when I'm running -main from the REPL, but that
otherwise calls System/exit when running as an uberjar.

Other suggestions welcome.

(defn has-repl?
  "Return true if we appear to be running with a REPL, false otherwise."
  []
  ;; *TBD*: Consider looking for some particular repl routine in jvm stack
traces
  ;; Don't care about the clojure.* prop vals, just that the property
exists.
  (if (or (System/getProperty "clojure.debug")
  (System/getProperty "clojure.compile.path")
  (if-let [command (System/getProperty "sun.java.command")]
(.contains command "clojure.main")))
true
false))

(defn- exit [status & [msg]]
  (when msg
(println msg))
  (flush)
  (if (has-repl?)
(throw (ex-info msg {:repl-exit true :status status}))
(System/exit status)))

;; And in (-main)
...
  (catch Exception e
(if-let [m (ex-data e)]
  ;; exception is of type clojure.lang.ExceptionInfo
  (if (:repl-exit m)
(:status m)
(exit 2 (str "Unexpected ex-data:" m "on" e)))
  ;; Caught an exception that wasn't thrown via pseudo-exit
  (if (has-repl?)
(println (str e))   ;print to REPL
(exit 2 (str e  ;print and exit java



On Tue, Apr 22, 2014 at 12:59 PM, Dave Tenny  wrote:

> I have an app I'm building.  It calls System/exit.  That doesn't works so
> well if I'm debugging in the REPL however.
>
> What's the preferred method of determining whether I'm in REPL mode
> interaction vs running as a standalone app?
>
> Also, long as I'm asking and being lazy, does the -main function return
> value translate to a System/exit value if it's numeric?
> Or is System/exit the way to go?
>
> --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/KZJQsmOeiHc/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Tag classes required to be imported?

2014-05-08 Thread Andy Fingerhut
This issue has been discovered before, at least in the context of the
tools.analyzer library, and there was an ensuing discussion on the
clojure-dev email list linked in the comments of this ticket:

http://dev.clojure.org/jira/browse/TANAL-24

I do not recall whether there was a Clojure ticket filed for it or not.

Andy


On Wed, May 7, 2014 at 9:55 PM, Colin Fleming
wrote:

> Hi all,
>
> I just came across a case with AOT compilation that I haven't seen before.
> I have the following code:
>
> (defn clojurescript? [element]
>   (or (.isKindOf (psi/language element)
> (ClojurescriptLanguage/getInstance))
>   (.isKindOf (psi/language element) (CljxLanguage/getInstance
>
> psi/language looks like this:
>
> (defn language ^Language [^PsiElement element]
>   (.getLanguage element))
>
> This gives me the following error when compiling:
>
> Caused by: java.lang.IllegalArgumentException: Unable to resolve
> classname: Language
> at clojure.lang.Compiler$HostExpr.tagToClass(Compiler.java:1060)
> at clojure.lang.Compiler$InvokeExpr.getJavaClass(Compiler.java:3567)
> at clojure.lang.Compiler$InstanceMethodExpr.(Compiler.java:1393)
> at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:952)
> at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
>
> I can get rid of this error importing Language into the original
> namespace. But I didn't expect this - does this mean that an import is
> required for the tag type of any function used in a particular namespace?
> Does this also apply to argument tags?
>
> Thanks,
> Colin
>
> --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Tag classes required to be imported?

2014-05-08 Thread Andy Fingerhut
Forgot to mention, the type tag should work without having to import it
into the require'ing namespace if you fully qualify it where the tag is
used.

Andy


On Thu, May 8, 2014 at 5:47 AM, Andy Fingerhut wrote:

> This issue has been discovered before, at least in the context of the
> tools.analyzer library, and there was an ensuing discussion on the
> clojure-dev email list linked in the comments of this ticket:
>
> http://dev.clojure.org/jira/browse/TANAL-24
>
> I do not recall whether there was a Clojure ticket filed for it or not.
>
> Andy
>
>
> On Wed, May 7, 2014 at 9:55 PM, Colin Fleming  > wrote:
>
>> Hi all,
>>
>> I just came across a case with AOT compilation that I haven't seen
>> before. I have the following code:
>>
>> (defn clojurescript? [element]
>>   (or (.isKindOf (psi/language element)
>> (ClojurescriptLanguage/getInstance))
>>   (.isKindOf (psi/language element) (CljxLanguage/getInstance
>>
>> psi/language looks like this:
>>
>> (defn language ^Language [^PsiElement element]
>>   (.getLanguage element))
>>
>> This gives me the following error when compiling:
>>
>> Caused by: java.lang.IllegalArgumentException: Unable to resolve
>> classname: Language
>> at clojure.lang.Compiler$HostExpr.tagToClass(Compiler.java:1060)
>> at clojure.lang.Compiler$InvokeExpr.getJavaClass(Compiler.java:3567)
>> at clojure.lang.Compiler$InstanceMethodExpr.(Compiler.java:1393)
>> at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:952)
>> at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
>>
>> I can get rid of this error importing Language into the original
>> namespace. But I didn't expect this - does this mean that an import is
>> required for the tag type of any function used in a particular namespace?
>> Does this also apply to argument tags?
>>
>> Thanks,
>> Colin
>>
>> --
>> 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 unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Rethinking Literate Programming

2014-05-08 Thread Gregg Reynolds
The thread on documentation that Val started (
https://groups.google.com/forum/?hl=en#!topic/clojure/oh_bWL9_jI0) is
getting a little long so I'm starting a related one specific to litprog.

I've made a start on rethinking LP at
https://github.com/mobileink/codegenres/wiki/Rethinking-Literate-Programming
.

A few key points:

* Knuth's main early LP tool (WEB) was to a certain extent an attempt to
fix deficiencies in Pascal, as Knuth himself explicitly acknowledged.  Some
aspects of Knuthian LP (KLP) may make sense for imperative languages with
side effects; since it's hard to reason about programs written in such
languages, added commentary is needed.  But if you already know that
functions are side-effect free and data are immutable, you no longer need
that.
* Programming language design has not evolved in the direction of LP, as we
might have expected from some of Knuth's more grandiose pronouncements;
instead they have evolved in the direction of greater expressivity, which
obviates the need for many kinds of documentation.  You can argue that LP
was a fine thing in its day, but the world has moved on.
* KLP is largely based on the personal aesthetic and psychological
preferences of DE Knuth involving issues such as the proper order and mode
of presentation of code.  Those are normative issues, and there is no
reason to take Knuth's preferences as gospel.  In particular there is no
justification for his claim that using LP "methods" leads to "better"
code.  It not only depends on what "better" means, it depends on what other
methods are available.  Just because writing Pascal in LP was better (for
Knuth et al.) than writing plain Pascal does not mean this will always be
the case in all languages.  It doesn't generalize.  (To a hammer,
everything looks like a goto.)
* There is (demonstrably) no reason to think that there is any "natural" or
"best" order of presentation for code; there are only preferences, and
everybody has one, if you catch my drift.  The point again being that Knuth
was not on to some kind of laws of programming.  KLP is all about his
preferred style, not about the Way Things Are.
* KLP is sometimes contrasted with "self-documenting code" To get a grip on
what that is and what we can expect from it we need to examine the notions
of function, algorithm, and code.  Then it looks like code does not in fact
"self-document", if "documentation" is taken to mean explanation.  But it
does express meaning, and sometimes expressivity is preferrable to
explanation.  Maybe that's terminological nit-picking, but sometimes coming
up with the right terminology makes all the difference (see "lambda
abstraction").
* Speaking of which, Knuth himself admitted that his choice of "literate
programming" as the name of his "new method" was tongue in cheek, since it
makes anybody who doesn't use it an "illiterate programmer".  (The citation
is in one of the essays in his book "Literate Programming".)  So maybe we
should stop using it and come up with a more accurate name.  Howsabout
"Knuthian Programming"?
* Knuth's model for program text is the literary essay, read from beginning
to end.  This is obviously in tension with the way code actually works.
Library code usually does not have a beginning or end, for example.  This
is a little ironic, since hypertext has liberated us from the tyranny and
oppression of linear narrative.  A better literary analog to program text
is The Book of Lists, or Commonplace books, whose contents can be read in
any order.
* Finally, a whiff of a hint of a soupcon of a concrete proposal: instead
of supporting some kind of structured markdown-style syntax in comments and
docstrings, add support for the Z specification notation, so that we can
express in clear, concise, formally defined, standard set-theoretic
notation the exact meaning of code.  That's the general idea, I don't have
a concrete suggestion yet.

There's more stuff on the
wiki,
and more to be said, but I'll stop here.

Cheers,

Gregg

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Rethinking Literate Programming

2014-05-08 Thread Gregg Reynolds
PS. Just to be clear, my purpose is neither to attack nor to defend LP,
just to get clear about exactly what it is, what its presuppositions are,
what its implications are, etc.

-G


On Thu, May 8, 2014 at 7:57 AM, Gregg Reynolds  wrote:

> The thread on documentation that Val started (
> https://groups.google.com/forum/?hl=en#!topic/clojure/oh_bWL9_jI0) is
> getting a little long so I'm starting a related one specific to litprog.
>
> I've made a start on rethinking LP at
> https://github.com/mobileink/codegenres/wiki/Rethinking-Literate-Programming
> .
>
> A few key points:
>
> * Knuth's main early LP tool (WEB) was to a certain extent an attempt to
> fix deficiencies in Pascal, as Knuth himself explicitly acknowledged.  Some
> aspects of Knuthian LP (KLP) may make sense for imperative languages with
> side effects; since it's hard to reason about programs written in such
> languages, added commentary is needed.  But if you already know that
> functions are side-effect free and data are immutable, you no longer need
> that.
> * Programming language design has not evolved in the direction of LP, as
> we might have expected from some of Knuth's more grandiose pronouncements;
> instead they have evolved in the direction of greater expressivity, which
> obviates the need for many kinds of documentation.  You can argue that LP
> was a fine thing in its day, but the world has moved on.
> * KLP is largely based on the personal aesthetic and psychological
> preferences of DE Knuth involving issues such as the proper order and mode
> of presentation of code.  Those are normative issues, and there is no
> reason to take Knuth's preferences as gospel.  In particular there is no
> justification for his claim that using LP "methods" leads to "better"
> code.  It not only depends on what "better" means, it depends on what other
> methods are available.  Just because writing Pascal in LP was better (for
> Knuth et al.) than writing plain Pascal does not mean this will always be
> the case in all languages.  It doesn't generalize.  (To a hammer,
> everything looks like a goto.)
> * There is (demonstrably) no reason to think that there is any "natural"
> or "best" order of presentation for code; there are only preferences, and
> everybody has one, if you catch my drift.  The point again being that Knuth
> was not on to some kind of laws of programming.  KLP is all about his
> preferred style, not about the Way Things Are.
> * KLP is sometimes contrasted with "self-documenting code" To get a grip
> on what that is and what we can expect from it we need to examine the
> notions of function, algorithm, and code.  Then it looks like code does not
> in fact "self-document", if "documentation" is taken to mean explanation.
> But it does express meaning, and sometimes expressivity is preferrable to
> explanation.  Maybe that's terminological nit-picking, but sometimes coming
> up with the right terminology makes all the difference (see "lambda
> abstraction").
> * Speaking of which, Knuth himself admitted that his choice of "literate
> programming" as the name of his "new method" was tongue in cheek, since it
> makes anybody who doesn't use it an "illiterate programmer".  (The citation
> is in one of the essays in his book "Literate Programming".)  So maybe we
> should stop using it and come up with a more accurate name.  Howsabout
> "Knuthian Programming"?
> * Knuth's model for program text is the literary essay, read from
> beginning to end.  This is obviously in tension with the way code actually
> works.  Library code usually does not have a beginning or end, for
> example.  This is a little ironic, since hypertext has liberated us from
> the tyranny and oppression of linear narrative.  A better literary analog
> to program text is The Book of Lists, or Commonplace books, whose contents
> can be read in any order.
> * Finally, a whiff of a hint of a soupcon of a concrete proposal: instead
> of supporting some kind of structured markdown-style syntax in comments and
> docstrings, add support for the Z specification notation, so that we can
> express in clear, concise, formally defined, standard set-theoretic
> notation the exact meaning of code.  That's the general idea, I don't have
> a concrete suggestion yet.
>
> There's more stuff on the 
> wiki,
> and more to be said, but I'll stop here.
>
> Cheers,
>
> Gregg
>
>
>
>

-- 
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 unsubscribe from this 

Re: determining repl environment vs. uberjar environment?

2014-05-08 Thread James Reeves
Having your application call System/exit directly is often indicative of
some unnecessary coupling in your code.

Under what circumstances does your application need to exit?

- James


On 22 April 2014 17:59, Dave Tenny  wrote:

> I have an app I'm building.  It calls System/exit.  That doesn't works so
> well if I'm debugging in the REPL however.
>
> What's the preferred method of determining whether I'm in REPL mode
> interaction vs running as a standalone app?
>
> Also, long as I'm asking and being lazy, does the -main function return
> value translate to a System/exit value if it's numeric?
> Or is System/exit the way to go?
>
> --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: determining repl environment vs. uberjar environment?

2014-05-08 Thread Dave Tenny
When running as an uberjar, i.e. "java -jar myapp.jar [args]"
the return code of the process to the shell is very important.  System/exit
is how that return code is sent.


On Thu, May 8, 2014 at 9:20 AM, James Reeves  wrote:

> Having your application call System/exit directly is often indicative of
> some unnecessary coupling in your code.
>
> Under what circumstances does your application need to exit?
>
> - James
>
>
> On 22 April 2014 17:59, Dave Tenny  wrote:
>
>> I have an app I'm building.  It calls System/exit.  That doesn't works so
>> well if I'm debugging in the REPL however.
>>
>> What's the preferred method of determining whether I'm in REPL mode
>> interaction vs running as a standalone app?
>>
>> Also, long as I'm asking and being lazy, does the -main function return
>> value translate to a System/exit value if it's numeric?
>> Or is System/exit the way to go?
>>
>> --
>> 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 unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/KZJQsmOeiHc/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: What does ^{} actually translate to?

2014-05-08 Thread guns
On Thu  8 May 2014 at 05:34:19AM -0700, Pascal Germroth wrote:

> (def f1 "doc" ^{:x 1} (partial inc))
> (meta f1) ; nil, unexpected
> (meta #'f1) ; contains :doc, but not :x, as expected

The definition of partial is:

(defn partial
  ([f] f)
  ([f arg1]
   (fn [& args] (apply f arg1 args)))
  …)

So it just calls out to fn. fn is a macro, and returns metadata on
&form, i.e. the metadata on the literal (fn) form itself. Your ^{:x 1}
therefore is lost.

> (def f2 "doc" ^{:x 2} #(inc %))
> (meta f2) ; {:x 2}, as expected
> (meta #'f2) ; contains :doc, but not :x, as expected

#() returns an instance of FnReader at read-time, so metadata can be
attached as usual.

> (def f3 "doc" (with-meta (partial inc) {:x 3}))
> (meta f3) ; {:x 3}

> (def f4 "doc" (with-meta #(inc %) {:x 4}))
> (meta f4) ; {:x 4}

with-meta calls .withMeta on its argument at runtime, so everything that
implements IObj works.

What's interesting is that

(meta ^:x inc) ; -> nil

does not work. I suppose this is because the reader cannot know if the
symbol `inc` represents an object that implements IMeta.

Hope this is accurate.

guns


pgpAjaltFssRA.pgp
Description: PGP signature


Re: determining repl environment vs. uberjar environment?

2014-05-08 Thread David Powell
There are some hacky possibilities - eg testing for *1, but I don't think
there is a definitive way; there are many repls too (the clojure.main repl,
lein repl, lighttable), and a technique might not work on all of them.

Probably best to have some helper function you call from the repl, and have
that return the status code.  Then make your -main call that, followed by
System/exit with the return value.




On Thu, May 8, 2014 at 2:23 PM, Dave Tenny  wrote:

> When running as an uberjar, i.e. "java -jar myapp.jar [args]"
> the return code of the process to the shell is very important.
> System/exit is how that return code is sent.
>
>
> On Thu, May 8, 2014 at 9:20 AM, James Reeves wrote:
>
>> Having your application call System/exit directly is often indicative of
>> some unnecessary coupling in your code.
>>
>> Under what circumstances does your application need to exit?
>>
>> - James
>>
>>
>> On 22 April 2014 17:59, Dave Tenny  wrote:
>>
>>> I have an app I'm building.  It calls System/exit.  That doesn't works
>>> so well if I'm debugging in the REPL however.
>>>
>>> What's the preferred method of determining whether I'm in REPL mode
>>> interaction vs running as a standalone app?
>>>
>>> Also, long as I'm asking and being lazy, does the -main function return
>>> value translate to a System/exit value if it's numeric?
>>> Or is System/exit the way to go?
>>>
>>> --
>>> 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 unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
>> 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 a topic in the
>> Google Groups "Clojure" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/clojure/KZJQsmOeiHc/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> clojure+unsubscr...@googlegroups.com.
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: determining repl environment vs. uberjar environment?

2014-05-08 Thread James Reeves
Sure, but those return codes correspond to some ending state of your
application, which can occur via a normal function return, or through an
exception. In both cases, your -main function can map state to exit code.

For instance, let's assume that your application will return or except. In
example below I'm using Slingshot to handle the exceptions:

(defn -main [& args]
  (try+
(apply app args) (System/exit 0)
(catch [:exit :app/bad-data] _ (System/exit 1))
(catch [:exit :app/connect-failed] _ (System/exit 2


Alternatively, if the app function returns the status rather than excepts:

(defn -main [& args]
  (System/exit
   (case (apply app args)
 :app/ok 0
 :app/bad-data 1
 :app/connect-failed 2)))


- James



On 8 May 2014 14:23, Dave Tenny  wrote:

> When running as an uberjar, i.e. "java -jar myapp.jar [args]"
> the return code of the process to the shell is very important.
> System/exit is how that return code is sent.
>
>
> On Thu, May 8, 2014 at 9:20 AM, James Reeves wrote:
>
>> Having your application call System/exit directly is often indicative of
>> some unnecessary coupling in your code.
>>
>> Under what circumstances does your application need to exit?
>>
>> - James
>>
>>
>> On 22 April 2014 17:59, Dave Tenny  wrote:
>>
>>> I have an app I'm building.  It calls System/exit.  That doesn't works
>>> so well if I'm debugging in the REPL however.
>>>
>>> What's the preferred method of determining whether I'm in REPL mode
>>> interaction vs running as a standalone app?
>>>
>>> Also, long as I'm asking and being lazy, does the -main function return
>>> value translate to a System/exit value if it's numeric?
>>> Or is System/exit the way to go?
>>>
>>> --
>>> 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 unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
>> 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 a topic in the
>> Google Groups "Clojure" group.
>> To unsubscribe from this topic, visit
>> https://groups.google.com/d/topic/clojure/KZJQsmOeiHc/unsubscribe.
>> To unsubscribe from this group and all its topics, send an email to
>> clojure+unsubscr...@googlegroups.com.
>>
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: What does ^{} actually translate to?

2014-05-08 Thread James Reeves
^x attaches the metadata to a form *before* it is evaluated. The with-meta
function attaches the metadata to a form *after* it's been evaluated.

Generally speaking, the ^x form is used for attaching metadata used by
macros and the Clojure compiler, whereas with-meta is used to attach
run-time metadata to Clojure data structures.

- James


On 8 May 2014 13:34, Pascal Germroth  wrote:

> Hi,
>
> I'm trying to attach metadata to some values (not the vars holding them).
> I thought ^{x} y was the same as (with-meta y {x}), but while it works for
> f2/f4, f1's metadata is nowhere to be found, while f3 works as expected:
>
> (def f1 "doc" ^{:x 1} (partial inc))
> (meta f1) ; nil, unexpected
> (meta #'f1) ; contains :doc, but not :x, as expected
>
> (def f2 "doc" ^{:x 2} #(inc %))
> (meta f2) ; {:x 2}, as expected
> (meta #'f2) ; contains :doc, but not :x, as expected
>
> (def f3 "doc" (with-meta (partial inc) {:x 3}))
> (meta f3) ; {:x 3}
>
> (def f4 "doc" (with-meta #(inc %) {:x 4}))
> (meta f4) ; {:x 4}
>
> Cheers,
>
> --
> pascal
>
> --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: data.xml namespace aware?

2014-05-08 Thread Herwig Hochleitner
Hi,

I'm the guy working on the newer proposal, which is almost done (TM). It
seems you have found the way to emulate namespacing with the current
data.xml impl: by taking care of xmlns attributes and prefixes yourself. I
definitely want to keep compatibility with that representation. Feel free
to check out my proposal branch here https://github.com/bendlas/data.xml

cheers


2014-05-06 21:53 GMT+02:00 Timothy Washington :

> Ok, scratch that. I got it working, lol :)
>
> Sorry for the false alarm. For future reference, this:
>
> (def e4 (xml/sexp-as-element
>  [:thing:first {:xmlns:thing "http://thing"}
>  [:thing:second {}]]))
>
>
> ...gives you this:
>
> user> (process/print-esequel process/e4)
>
> 
> http://thing";>
>   
> 
>
>
>
> Tim Washington
> Interruptsoftware.com 
>
>
> On Tue, May 6, 2014 at 3:45 PM, Timothy Washington wrote:
>
>> Got a bit further here. I want to be able to get tag namespaces without a
>> :root tag (that includes the namespace definition). Assume the below code
>> has (require '[clojure.data.xml :as xml]).
>>
>>
>> Working with attributes is fine.
>>
>> (def e1 (xml/element :use {:xmlns:xlink "http://testing";,
>>:xlink:href "#whiskers",
>>:transform "scale(-1 1) translate(-140 0)"}))
>>
>>
>> Namespace prefixes is possible with tags; however, I had to add the
>> unwanted :root tag (that includes ns definition)
>>
>> (def e2 (xml/element :root {:xmlns:thing "http://thing"}
>>  (xml/element :thing:use {})))
>>
>> (def e3 (xml/element :root {:xmlns:thing "http://thing"}
>>  (xml/sexp-as-element
>>   [:thing:first {}
>>[:thing:second {}]])))
>>
>> (defn print-esequel [elem]
>>   (println (xml/indent-str elem)))
>>
>>
>>
>> The resulting XML is close. But we want the tag namespaces, without the
>> root node
>>
>> user> (print-esequel process/e2)
>>
>> 
>> http://thing";>
>>   
>> 
>>
>> user> (print-esequel process/e3)
>>
>> 
>> http://thing";>
>>   
>> 
>>   
>> 
>>
>>
>>
>> Tim Washington
>> Interruptsoftware.com 
>>
>>
>> On Tue, May 6, 2014 at 3:24 PM, Timothy Washington wrote:
>>
>>> Hi there,
>>>
>>>
>>> *A)* I'm just writing some SOAP XML, trying to use 
>>> data.xml.
>>> This SO 
>>> thread
>>>  outlines
>>> how to write out namespace aware XML. But the example is for a namespace on
>>> an attribute. I'm combing through the code now, but does anyone know how to
>>> set this up?
>>>
>>>
>>> *B)* There's actually this Fuller XML 
>>> Supportproposal 
>>> (referring to this
>>> thread),
>>> and this Namespaced 
>>> XMLproposal. But I 
>>> don't see that namespaces are fully implemented in any of
>>> the core libs.
>>>
>>> I only see this ArmageDOM lib, 
>>> which supports namespaces. Anything else out there that I've missed?
>>>
>>>
>>> Thanks
>>>
>>> Tim Washington
>>> Interruptsoftware.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
> ---
> You received this message because you are subscribed to the Google Groups
> "Clojure" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: determining repl environment vs. uberjar environment?

2014-05-08 Thread Dave Tenny
James, All well and good, but you still need to know if you're running in a
REPL environment, and make sure you do NOT call System/exit for any
(typical) reason in that environment.  The idea is to test your (-main)
function from the REPL, without having to restart the lisp every time.


On Thu, May 8, 2014 at 10:28 AM, James Reeves  wrote:

> Sure, but those return codes correspond to some ending state of your
> application, which can occur via a normal function return, or through an
> exception. In both cases, your -main function can map state to exit code.
>
> For instance, let's assume that your application will return or except. In
> example below I'm using Slingshot to handle the exceptions:
>
> (defn -main [& args]
>   (try+
> (apply app args) (System/exit 0)
> (catch [:exit :app/bad-data] _ (System/exit 1))
> (catch [:exit :app/connect-failed] _ (System/exit 2
>
>
> Alternatively, if the app function returns the status rather than excepts:
>
> (defn -main [& args]
>   (System/exit
>(case (apply app args)
>  :app/ok 0
>  :app/bad-data 1
>  :app/connect-failed 2)))
>
>
> - James
>
>
>
> On 8 May 2014 14:23, Dave Tenny  wrote:
>
>> When running as an uberjar, i.e. "java -jar myapp.jar [args]"
>> the return code of the process to the shell is very important.
>> System/exit is how that return code is sent.
>>
>>
>> On Thu, May 8, 2014 at 9:20 AM, James Reeves wrote:
>>
>>> Having your application call System/exit directly is often indicative of
>>> some unnecessary coupling in your code.
>>>
>>> Under what circumstances does your application need to exit?
>>>
>>> - James
>>>
>>>
>>> On 22 April 2014 17:59, Dave Tenny  wrote:
>>>
 I have an app I'm building.  It calls System/exit.  That doesn't works
 so well if I'm debugging in the REPL however.

 What's the preferred method of determining whether I'm in REPL mode
 interaction vs running as a standalone app?

 Also, long as I'm asking and being lazy, does the -main function return
 value translate to a System/exit value if it's numeric?
 Or is System/exit the way to go?

 --
 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 unsubscribe from this group and stop receiving emails from it, send
 an email to clojure+unsubscr...@googlegroups.com.

 For more options, visit https://groups.google.com/d/optout.

>>>
>>>  --
>>> 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 a topic in the
>>> Google Groups "Clojure" group.
>>> To unsubscribe from this topic, visit
>>> https://groups.google.com/d/topic/clojure/KZJQsmOeiHc/unsubscribe.
>>> To unsubscribe from this group and all its topics, send an email to
>>> clojure+unsubscr...@googlegroups.com.
>>>
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>  --
>> 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 unsubscribe from this group and stop receiving emails from it, send an
>> email to clojure+unsubscr...@googlegroups.com.
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>  --
> 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

Re: determining repl environment vs. uberjar environment?

2014-05-08 Thread Ray Miller
On 8 May 2014 16:22, Dave Tenny  wrote:
> James, All well and good, but you still need to know if you're running in a
> REPL environment, and make sure you do NOT call System/exit for any
> (typical) reason in that environment.  The idea is to test your (-main)
> function from the REPL, without having to restart the lisp every time.

I think James's point was that, if your -main function is a thin
wrapper that calls (app ...), then it's (app ...) you'd test at the
REPL (apologies if I'm putting words into your mouth, James).

Ray.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: determining repl environment vs. uberjar environment?

2014-05-08 Thread Dave Tenny
Gotcha. I suppose that makes sense as long as I undo some poor design and
make sure that the 'exit' wrapper I have never attempts to call System/exit
directly and always throws some suitable exception for interpretation at
the top level.  Right now my exit wrapper calls exit immediately if we're
not in a REPL environment.  Very few applications would care about the
distinction
(including mine) between unwinding a thread then calling exit, vs calling
exit without unwinding.

Independent of my exit situation, I can still think of situations in which
people may want to perform logic only when it was known to be a REPL
environment. Of course in the worst case you can always add a -D flag to
the JVM on startup indicating some 'interactive" mode desires.  I'm not
sure how that goes with repls from cider in emacs and such.

Meanwhile I'm set with a workaround, and the points made on (app) vs.
(-main (app)) are good if you always throw and never call exit down the
stack.


On Thu, May 8, 2014 at 12:14 PM, Ray Miller  wrote:

> On 8 May 2014 16:22, Dave Tenny  wrote:
> > James, All well and good, but you still need to know if you're running
> in a
> > REPL environment, and make sure you do NOT call System/exit for any
> > (typical) reason in that environment.  The idea is to test your (-main)
> > function from the REPL, without having to restart the lisp every time.
>
> I think James's point was that, if your -main function is a thin
> wrapper that calls (app ...), then it's (app ...) you'd test at the
> REPL (apologies if I'm putting words into your mouth, James).
>
> Ray.
>
> --
> 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 a topic in the
> Google Groups "Clojure" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/clojure/KZJQsmOeiHc/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to
> clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: What does ^{} actually translate to?

2014-05-08 Thread Stephen Gilardi

On May 8, 2014, at 8:34 AM, Pascal Germroth  wrote:

> I'm trying to attach metadata to some values (not the vars holding them).
> I thought ^{x} y was the same as (with-meta y {x}),

There was a recent thread about this here. 
https://groups.google.com/forum/#!searchin/clojure/metadata$20reader/clojure/iyYwwWPgv2U/xh-4SonzudkJ

^ is a reader macro that applies metadata to a target. The target is the result 
of reading the form that immediately follows the metadata form. ^ operates at 
read time, after the target form is read, but before it is evaluated. There are 
some subtleties in your example that make exactly what's happening not obvious. 
As a tool for understanding, read-string on a string can help by giving you 
visibility into the reader's operation alone. This is in contrast to the REPL 
where the result you see is after both read and eval have completed.

> but while it works for f2/f4, f1's metadata is nowhere to be found, while f3 
> works as expected:
> 
> (def f1 "doc" ^{:x 1} (partial inc))
> (meta f1) ; nil, unexpected
> (meta #'f1) ; contains :doc, but not :x, as expected

The target form in this case is "(partial inc)". Checking (read-string 
"(partial inc)") confirms that the reader returns a list containing two 
symbols. The reader macro ^ applied the metadata to that list. The evaluator 
then evaluated that list by invoking the function bound to the var 
clojure.core/partial. That function has no access to the metadata on the list 
that the reader read. After evaluation there is no longer any reference to that 
list or its metadata. They are both dropped.

> (def f2 "doc" ^{:x 2} #(inc %))
> (meta f2) ; {:x 2}, as expected
> (meta #'f2) ; contains :doc, but not :x, as expected

The target form in this case is "#(inc %)". (read-string "#(inc %)") shows that 
the reader returns a list like this (containing a symbol, a vector, and a list):

(fn* [p1__1925#] (inc p1__1925#))

The name fn* is an implementation detail, you can think of it as fn.

Because fn is a special form, it does have access to the list that was returned 
by the reader and the metadata on it. One thing fn does is transfer the 
metadata on that list to the function object it creates. That's why (meta f2) 
works as you expected.

There was no metadata applied to the symbol f2. If there had been it would have 
been transferred by the special form def to the var it created. Your 
expectation here is probably based on the action of the defn macro which 
transfers metadata in a defn form to the var it creates.

> (def f3 "doc" (with-meta (partial inc) {:x 3}))
> (meta f3) ; {:x 3}

with-meta operates after (partial inc) is evaluated so it applies the metadata 
to the function object returned by partial.

> (def f4 "doc" (with-meta #(inc %) {:x 4}))
> (meta f4) ; {:x 4}

same here.

--Steve

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Rethinking Literate Programming

2014-05-08 Thread Mark Engelberg
Greg,

I can tell by the amount of work you've put into this document that this is
an earnest attempt at analysis and not trolling, so I'm going to give you
my earnest response:  you are wrong on so many levels.

First, you seem to have several misconceptions about literate programming
in general, and Knuth-style literate programming specifically, which makes
me wonder whether you've ever actually read Knuth's code.  For example, you
say, "Knuth's model for program text is the literary essay, read from
beginning to end.  This is obviously in tension with the way code actually
works."  Yes, it is true that one goal of literate programming is to free
the programmer to choose an order to describe the code that is independent
of the order and structure that the compiler needs to see it.  But a
Knuth-style literate program is far more than a linear essay.  Although you
*can* often read a literate program from beginning to end in order to
understand the full system, the detailed hyperlinking and indexing makes
reading code almost more like a choose-your-own-adventure story, making it
easy to understand the parts of code you care about and understand how the
different parts relate to one another.  I suggest you sit down and read
some actual Knuth code if you want to try to understand what that approach
does and does not accomplish.

Second, you repeatedly make the case that programming expressiveness (and
presumably Clojure's expressiveness specifically) is far better than in
Knuth's time.  This is nonsense.  LISP is one of the oldest languages, and
Clojure isn't profoundly different in its expressiveness.  In fact, Clojure
has a number of features that actively hurt its expressiveness relative to
other modern languages:

1. Definitions must precede their usage.  Can usually work around this with
forward-declarations, but even that small extra burden causes programmers
to tend towards a bottom-up style of writing Clojure code, even if that is
not desirable for a certain program.
2. Very strict limitations on ways that different files/namespaces relate
to one another (e.g., no cyclic dependencies), so very often, things need
to be organized for the convenience of the compiler rather than for
understanding.
3. Limited convenient notation for expressing that a function is merely a
"helper function" (only defn has a convenient notation for this, defn-).
4. The tooling convention of having tests in separate files places even
more obstacles in the way of using things like defn- in order to express
the distinction between primary and secondary functions.
5. Clojure's inability to handle local recursive references (i.e., no
letrec) provides obstacles for clearly expressing that certain things are
merely local functions/data for another function.  Some things have to be
made global that conceptually aren't.
6. The "sea of sameness" problem -- no visual distinction between
functions, macros, variables, control constructs.

You state that functional programs are so much easier to comprehend than
mutable ones, they don't really require explanation.  This also is silly.

I challenge you to buy this book:
http://www.amazon.com/Pearls-Functional-Algorithm-Design-Richard/dp/0521513383,
a collection of literate programs (in the academic article sense of the
word, not really in the Knuth sense) written in Haskell, arguably the "most
functional language".  Most of the chapters conclude with the entire source
of the program under discussion.  I challenge you to pick any one of those
chapters and look just at the final program, then try to figure out how and
why it works.  Good luck!

There is a reason why academic computer science journals are not just books
of raw source code.  Innovative code and complex code require explanation.
I would argue that Clojure would not exist were it not for a long tradition
of code-embedded-in-detailed-explanation.  Clojure is founded on the use of
cutting-edge functional data structures, and I would wager that Rich Hickey
would likely not have understood these structures well enough to implement
them so successfully had he not been able to read articles explaining their
construction and why they work.

So this notion that the world is trending away from literate programs just
isn't true.  We see them all the time in the form of articles and blog
posts designed to elucidate, we see them all the time in the context of
real-world large, complex systems designed to outlive the people who
created them, and in the context of literate programs written to teach and
influence a new generation of programmers.  For example, did you know that
the book/literate program "Physically Based Rendering" recently won a
Scientific and Technical Academy Award?  (Yes, that's right, a literate
program won an Academy Award -- the "Hollywood movie" kind.)

"Physically based rendering has transformed computer graphics lighting by
more accurately simulating materials and lights, allowing digital artists
to focus on cinematogra

Re: Rethinking Literate Programming

2014-05-08 Thread u1204
> PS. Just to be clear, my purpose is neither to attack nor to defend LP,
> just to get clear about exactly what it is, what its presuppositions are,
> what its implications are, etc.

I also do not want to get into defending LP yet again. But I do think
you might have missed the key point by focusing on presentation rather
than communication. 




> * Knuth's main early LP tool (WEB) was to a certain extent an attempt to
> fix deficiencies in Pascal, as Knuth himself explicitly acknowledged.  Some
> aspects of Knuthian LP (KLP) may make sense for imperative languages with
> side effects; since it's hard to reason about programs written in such
> languages, added commentary is needed.  But if you already know that
> functions are side-effect free and data are immutable, you no longer need
> that.

Having worked in string-free Pascal, the only real way to "fix it" would
be to take it outside and burn it. :-)




> * Programming language design has not evolved in the direction of LP, as we
> might have expected from some of Knuth's more grandiose pronouncements;
> instead they have evolved in the direction of greater expressivity, which
> obviates the need for many kinds of documentation.  You can argue that LP
> was a fine thing in its day, but the world has moved on.

 "The nature of functional programming is to build, Russian doll-style,
 functions that use functions that use functions etc. But without
 something like a literate style, your efforts are quickly lost in the
 details. You do stuff -- and unless you have a phenomenal memory,
 you've simply dug a nice, deep tunnel that is, at the same time,
 collapsing behind you. YOU may know what you've done, but how to make
 others aware and get them involved? All they see is some collapsed
 tunnel with a sales pitch about how you should go re-dig that very same
 tunnel." -- Lawrence Bottorff, February 2014



> * KLP is largely based on the personal aesthetic and psychological
> preferences of DE Knuth involving issues such as the proper order and mode
> of presentation of code.  Those are normative issues, and there is no
> reason to take Knuth's preferences as gospel.  In particular there is no
> justification for his claim that using LP "methods" leads to "better"
> code.  It not only depends on what "better" means, it depends on what other
> methods are available.  Just because writing Pascal in LP was better (for
> Knuth et al.) than writing plain Pascal does not mean this will always be
> the case in all languages.  It doesn't generalize.  (To a hammer,
> everything looks like a goto.)

While the "proper order and mode of presentation" is a matter of
personal preference it is not really germaine to the problem.

When code is written and decorated with comments about what it does
we feel we have communicated the important part. 

The problem is that we missed the "why". Sure, we have immutable, log32,
red-black trees (ILRB trees). Yes, we documented what the arguments mean.
But you'll notice that nowhere in the github tree is there any answer to
"why?".

A "literate programming style" isn't really the issue. The loss of 
"why?" is the issue. Answering "why?" means that you have to 
build up the background problem so people can understand "why?" the
code is a solution. In other words, you need to communicate the ideas
in some linear fashion so they have a common background understanding.




> * There is (demonstrably) no reason to think that there is any "natural" or
> "best" order of presentation for code; there are only preferences, and
> everybody has one, if you catch my drift.  The point again being that Knuth
> was not on to some kind of laws of programming.  KLP is all about his
> preferred style, not about the Way Things Are.

As an author I agree that there is no "natural" or "best" order of
presentation. But there are clear preferences. Pick up any "book" which
is a collection of conference papers and you can see that presentation
choice is vital. Random, unorganized piles of ideas is not
communication.


The real focus of literate programming is actually about communication
from one person to another. "Ideas" are missing from "The Way Things
Are". At best we document what something does but not why we want to use
it.

If you look at the mailing list, a lot of the answers are of the form
"this is why you should write it this way".

Rich has been pretty good about communicating his ideas and his videos
can be found on the web, assuming you know where to look and what you
are looking for. Which video would I watch to get the ILRB tree concept?
Which one would I watch to get the ideas behind "conj vs cons"? Or the
details of software transactional memory? Where is the explanation of
that long block of code I posted last week?

And how do those ideas relate to the code? After all, I end up staring
at the code. 




> * KLP is sometimes contrasted with "self-documenting code" To get a grip on
> what that is and what we can expect from it we need 

Re: Rethinking Literate Programming

2014-05-08 Thread u1204
>   For example, did you know that
> the book/literate program "Physically Based Rendering" recently won a
> Scientific and Technical Academy Award?  (Yes, that's right, a literate
> program won an Academy Award -- the "Hollywood movie" kind.)

An awesome book, by the way. I WISH I could write such a literate
program. Like "Lisp in Small Pieces", they wrote a masterpiece. 

I hope it shows the next generation of programmers what beautifully
written programs look like.

Tim

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-08 Thread Alexandru Nedelcu
On Wed, May 7, 2014 at 6:31 AM, Alex Miller  wrote:

It does matter with regard to visibility across threads - your example does
> not use a synchronization mechanism and there is no guarantee that other
> threads will ever see those changes (so don't ever ever do that :). But if
> you stick to the normal Clojure apis, all is good. I'd highly recommend
> reading JCIP to dive into the details.
>
> Final field freeze is particularly weird and it baked my noodle when I
> first encountered it - here's a blog I wrote about it approx 697 years ago
> in internet time (and Brian Goetz backs me up in the comments :)
> http://tech.puredanger.com/2008/11/26/jmm-and-final-field-freeze/
>
 I believe that while JCIP is useful, it is also confusing, because it is
trying to explain Java’s memory model in layman’s terms. I recently
experienced “enlightenment”, by making an effort to understand how things
work at a lower level.

Happens-before relationships / ordering guarantees are given by the
compiler, in combination with the CPU, with the rules being implied by
usage of memory fences (barriers). Without ordering guarantees, several
things can happen - the compiler could optimize the code by reordering or
eliminating instructions, the CPU might optimize the code by reordering or
eliminating instructions and - what bits beginners the most - today’s
multi-core CPUs are tricky, as each CPU has a store buffer that’s local to
each core (i.e. other cores cannot see it) and published values only become
visible to other cores when the store buffer gets flushed to the L1 cache.
And you have no guarantee that this flush will *ever* happen, or even after
it happens, you have no guarantee that other processors that already have a
cached value will make an effort to read the more up-to-date value … unless
ordering semantics are enforced. And actually thinking in terms of flushes
to memory is dangerous, as nothing you do guarantees a flush - everything
being relative, specified in terms of happens-before relationships, implied
by memory barriers.

And memory barriers are tricky beasts, as they come in multiple shapes and
sizes. The JSR 133 Cookbook
is a useful document
for shedding some light on how they work. In
particular, for final fields, you get a guarantee for a *StoreStore* memory
barrier, like so:

x.finalField = v; *StoreStore*; sharedRef = x;

This guarantee basically says that the finalFields’ value will always be
stored before the write sharedRef = x happens. Or in other words, once the
constructor of x is finished and the value stored inside a sharedRef, the
finals are already fully initialized. And this extends to whatever writes
that happened in the object stored in that final field too. This assumes
that this didn’t escape during construction - in which case the above
guarantee becomes meaningless for threads that already saw object x. As an
aside, a StoreStore fence on X86 is a no-op, as stores on X86 are ordered,
but for other processors this is not true and the compiler can and does
reorder instructions by itself.

Also consider doing something like:

 final int[] field = new int[] {1,2,3,4}

Even though that array is not immutable, the array and the values in it
will be visible once the final field itself becomes visible, again because
of the store ordering guarantee. But this doesn’t hold if that array
reference has been seen before, so this doesn’t work as people might think:

final int[] field;
public Constructor(int[] arr) { field = arr }

My initial impression was that a final field store behaves like a volatile
write. That’s not true. A volatile write is *preceded* by a StoreStore,
while a final write is succeeded by one. Also, a volatile write followed by
a volatile read guarantees a Store/Load memory barrier between the two
actions for ordering previous stores with subsequent loads - this is the
rule that says that once a volatile is stored, then subsequent reads are
ordered after that store (so the volatile read is basically monitor enter
and the volatile write is basically monitor exit … the similarity with
acquiring locks is not accidental at all) and so threads don’t get stale
data. Finals don’t get the same treatment, even though there are
similarities between the two … this is also why it is important for this to
not escape during construction or for why the array reference received from
the outside in the above won’t necessarily be up-to-date when the final
will be observed by other threads - again, ordering guarantees are relative.

In other words, for finals to work properly, this mustn’t escape during
construction and care must be taken when storing references to mutable
things received from the outside.
-- 
Alexandru Nedelcu
www.bionicspirit.com

PGP Public Key:
https://bionicspirit.com/key.aexpk

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure@googlegroups.co

Re: Rethinking Literate Programming

2014-05-08 Thread Mark Engelberg
On Thu, May 8, 2014 at 11:02 AM, Mark Engelberg wrote:

> In fact, Clojure has a number of features that actively hurt its
> expressiveness relative to other modern languages:
>

BTW, that list was by no means exhaustive.  In the past couple of hours
I've thought of a couple more, I'm sure others could easily add to the list:

7. Use of infix notation means that math formulas look dramatically
different in Clojure than in math form, and therefore, it is difficult to
determine at a glance whether a formula as implemented in Clojure matches.
8. Arrays in many domains are more naturally expressed as 1-based, but in
Clojure, they are 0-based.  I've encountered a lot of code that was
confusing because of lots of increments/decrements to shift back and forth
between the problem as specified with 1-based implementation and the
0-based implementation imposed by Clojure.  Lots of opportunities for
off-by-one errors and/or later confusion when other readers try to make
sense out of the code.
9. Clojure's ease of functional composition can result in deeply nested
calls that are far easier to write than they are to read.
10. Unlike most other languages, every time you give names to local
variables with let, you add a level of indentation.  Especially with
alternations of let and if/cond, you can easily end up with "rightward
drift" that makes code harder to read.

These are things we learn to live with.  If these were show-stoppers, I'd
be using another language, but they are not, so on balance I prefer Clojure
with its other many strengths.  My only point is that by no means is
Clojure a pinnacle of expressiveness where all code is miraculously obvious.

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Immutable or Effectively Immutable?

2014-05-08 Thread Alexandru Nedelcu
On Wed, May 7, 2014 at 5:57 PM, Phillip Lord
wrote:

> In general, though, if I write some code like
>
> (if (instance? Cons x)
> (pass-to-another-thread-without-synchronisation x))
>
> I cannot guarantee the result of this because although I know that
> the head of x is fixed, I cannot guarantee that for the tail. If I know
> how x is constructed, of course, then I can make this guarantee.
>

On the other hand, that's not the concern of the piece of code you
outlined. Because if "x" wasn't constructed properly and the "latest" data
in it is not visible, there's absolutely nothing you can do about it ;-)
Visibility is (or should be) the concern of the producer, not of the
consumer.


> You get the a related problem in Java.
>
> List l = Collections.unmodifiedableList(l);
>
> Is l now unmodifiable? Well maybe, depending on what happened to it
> before.
>

What happened to it "before" is not relevant, because again, there's
nothing you can do about it at this point and actually from this consumer's
perspective "before" doesn't exist ... there's only "now" with the only
question being if there are or there will be pending changes that may or
may not be published in the future (where "future" is kind of thread-local).

Concurrency is hard, but it's greatly simplified if you keep the concerns
for atomicity and visibility on the producer's side. And if some
third-party module or function or class or whatever doesn't respect this
rule by delegating such concerns to the consumer, then simply scrap it from
the code-base if it's such a big deal - Date is mutable and that's a
problem? Use Joda, etc... Java libraries also document when something is
thread-safe and if that's left unspecified, it means that it isn't.

That's how people working with C++ also keep their sanity in regards to
memory management - i.e. when a producer passes along a pointer or
reference of something to a consumer, the sanest thing to do is to consider
deallocation or other life cycle issues as the responsibility of the
producer, unless it's very explicit in the exposed API that the consumer
should handle it.

-- 
Alexandru Nedelcu
www.bionicspirit.com

PGP Public Key:
https://bionicspirit.com/key.aexpk

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


executing conditional if like iif from other languages

2014-05-08 Thread Don Hill
I am trying to get a couple of edge cases to past and since I am very new 
to clojure/lisp (2 days total) I thought I would ask.


I am using defmacro like the following. I have 2 edge case which are 
failing. I would like to be able to process these cases where there are 
extra bits and as you probably guessed the last 2 entries have keys with 
not value. I don't thinks the :keys will work for these cases.

Any ideas on how I could destruct this so all the cases would pass?

(defmacro iif [expr & {:keys [then, else]}] 
`(if ~expr ~then ~else))

(println(iif (> 3 1))) ;nil
(println(iif (> 3 1) :then 'ok)) ;ok
(println(iif (< 5 3) :else 'ok)) ;ok
(println(iif (> 3 1) :else 'oops)) ;nil

(println(iif (> 3 1) :else 'oops :then 'ok));ok
;;(println(iif (> 3 1) :then )) ;nil
;;(println(multi-if (> 3 1) :else 'oops :then (println'hi) 'ok)) ;;hi ok

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Assuring dealing with PersistentVector for associative accesses

2014-05-08 Thread Joseph Rollins
I am confused about the best way to assure that I am dealing with a vector 
when dealing with core library functions that often return seq where I then 
lose my ability to access it using associative accesses (get-in 
specifically).

My particular use case is as follows:

I am modeling a matrix as nested vectors

[[0 0 0] [0 1 1] [0 1 1]]

represents

0 0 0
0 1 1
0 1 1

I know matrix libraries exist, but for the sake of learning am rolling my 
own functionality.  I have several functions that operate on this:

(defn transpose [piece]
  (apply mapv vector piece))

(defn translate-block
  ([mm]   (let [one? #(if (= 1 %) true false)]
(translate-block mm one?)))
  ([mm f] (map #(map f %) mm)))

(defn rotate-left [b]
  (->> b
   transpose
   reverse))

The problem I am running into is that these do not output nested vectors, 
but nested seqs (due to all of the map operations). I am using these 
matrices to program Tetris, and I am writing a function that takes a Tetris 
block, a Tetris board (both represented as matrices) and a position of the 
block inside the board. The function is supposed to determine if the 
placement of the block is valid (not overlapping already placed blocks:

(defn is-valid?
  "Determine if a game state is valid (is current piece place-able)."
  [{board :board {:keys [piece pos]} :piece}]
  (let [[x y] pos
coords (for [rows (range (count piece))
 cols (range (count (first piece)))]
 [[rows cols] [(+ y rows) (+ x cols)]])]
(map (fn [[c cc]]
   (and (get-in board cc) (get-in piece c)))
 coords)))

The matrices hold true and false values for if occupied. When testing this 
function I realized get-in was just returning nil because it wouldnt get in 
a seq (non-associative).  What is the best way to assure that when I need 
associative guarantees that they haven't been thrown away through previous 
transformations of the board or piece matrices?

The two choices I see are making sure every function that operates on the 
matrices explicitly outputs nested vectors again, or transforming the input 
to functions that need the guarantees to nested vectors explicitly. Am I 
missing something here, or, if not, what is the idiomatic way to solve this 
problem?

Thanks

-Joseph

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Assuring dealing with PersistentVector for associative accesses

2014-05-08 Thread Jason Ozias
Take a look at mapv.  If you aren't dealing with lazy sequence, it'll map 
the function across and convert the output to a vector.

On Thursday, May 8, 2014 7:28:47 PM UTC-4, Joseph Rollins wrote:
>
> I am confused about the best way to assure that I am dealing with a vector 
> when dealing with core library functions that often return seq where I then 
> lose my ability to access it using associative accesses (get-in 
> specifically).
>
> My particular use case is as follows:
>
> I am modeling a matrix as nested vectors
>
> [[0 0 0] [0 1 1] [0 1 1]]
>
> represents
>
> 0 0 0
> 0 1 1
> 0 1 1
>
> I know matrix libraries exist, but for the sake of learning am rolling my 
> own functionality.  I have several functions that operate on this:
>
> (defn transpose [piece]
>   (apply mapv vector piece))
>
> (defn translate-block
>   ([mm]   (let [one? #(if (= 1 %) true false)]
> (translate-block mm one?)))
>   ([mm f] (map #(map f %) mm)))
>
> (defn rotate-left [b]
>   (->> b
>transpose
>reverse))
>
> The problem I am running into is that these do not output nested vectors, 
> but nested seqs (due to all of the map operations). I am using these 
> matrices to program Tetris, and I am writing a function that takes a Tetris 
> block, a Tetris board (both represented as matrices) and a position of the 
> block inside the board. The function is supposed to determine if the 
> placement of the block is valid (not overlapping already placed blocks:
>
> (defn is-valid?
>   "Determine if a game state is valid (is current piece place-able)."
>   [{board :board {:keys [piece pos]} :piece}]
>   (let [[x y] pos
> coords (for [rows (range (count piece))
>  cols (range (count (first piece)))]
>  [[rows cols] [(+ y rows) (+ x cols)]])]
> (map (fn [[c cc]]
>(and (get-in board cc) (get-in piece c)))
>  coords)))
>
> The matrices hold true and false values for if occupied. When testing this 
> function I realized get-in was just returning nil because it wouldnt get in 
> a seq (non-associative).  What is the best way to assure that when I need 
> associative guarantees that they haven't been thrown away through previous 
> transformations of the board or piece matrices?
>
> The two choices I see are making sure every function that operates on the 
> matrices explicitly outputs nested vectors again, or transforming the input 
> to functions that need the guarantees to nested vectors explicitly. Am I 
> missing something here, or, if not, what is the idiomatic way to solve this 
> problem?
>
> Thanks
>
> -Joseph
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Assuring dealing with PersistentVector for associative accesses

2014-05-08 Thread Joseph Rollins
This works for all cases were I transform the matrix using map, but I also 
transform it using reverse and assoc.

On Thursday, May 8, 2014 8:02:03 PM UTC-4, Jason Ozias wrote:
>
> Take a look at mapv.  If you aren't dealing with lazy sequence, it'll map 
> the function across and convert the output to a vector.
>
> On Thursday, May 8, 2014 7:28:47 PM UTC-4, Joseph Rollins wrote:
>>
>> I am confused about the best way to assure that I am dealing with a 
>> vector when dealing with core library functions that often return seq where 
>> I then lose my ability to access it using associative accesses (get-in 
>> specifically).
>>
>> My particular use case is as follows:
>>
>> I am modeling a matrix as nested vectors
>>
>> [[0 0 0] [0 1 1] [0 1 1]]
>>
>> represents
>>
>> 0 0 0
>> 0 1 1
>> 0 1 1
>>
>> I know matrix libraries exist, but for the sake of learning am rolling my 
>> own functionality.  I have several functions that operate on this:
>>
>> (defn transpose [piece]
>>   (apply mapv vector piece))
>>
>> (defn translate-block
>>   ([mm]   (let [one? #(if (= 1 %) true false)]
>> (translate-block mm one?)))
>>   ([mm f] (map #(map f %) mm)))
>>
>> (defn rotate-left [b]
>>   (->> b
>>transpose
>>reverse))
>>
>> The problem I am running into is that these do not output nested vectors, 
>> but nested seqs (due to all of the map operations). I am using these 
>> matrices to program Tetris, and I am writing a function that takes a Tetris 
>> block, a Tetris board (both represented as matrices) and a position of the 
>> block inside the board. The function is supposed to determine if the 
>> placement of the block is valid (not overlapping already placed blocks:
>>
>> (defn is-valid?
>>   "Determine if a game state is valid (is current piece place-able)."
>>   [{board :board {:keys [piece pos]} :piece}]
>>   (let [[x y] pos
>> coords (for [rows (range (count piece))
>>  cols (range (count (first piece)))]
>>  [[rows cols] [(+ y rows) (+ x cols)]])]
>> (map (fn [[c cc]]
>>(and (get-in board cc) (get-in piece c)))
>>  coords)))
>>
>> The matrices hold true and false values for if occupied. When testing 
>> this function I realized get-in was just returning nil because it wouldnt 
>> get in a seq (non-associative).  What is the best way to assure that when I 
>> need associative guarantees that they haven't been thrown away through 
>> previous transformations of the board or piece matrices?
>>
>> The two choices I see are making sure every function that operates on the 
>> matrices explicitly outputs nested vectors again, or transforming the input 
>> to functions that need the guarantees to nested vectors explicitly. Am I 
>> missing something here, or, if not, what is the idiomatic way to solve this 
>> problem?
>>
>> Thanks
>>
>> -Joseph
>>
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Assuring dealing with PersistentVector for associative accesses

2014-05-08 Thread James Reeves
If you're representing a matrix with vectors, then any public function that
operates on a matrix should return vectors.

You may want to consider a function like:

(defn matrix? [m]
  (and (vector? m)
   (every? vector m)
   (apply = (count m) (map count m)))

Then add it as a pre and post condition:

(defn transpose [m]
  {:pre [(matrix? m)] :post [(matrix? %)]}
  (apply mapv vector m))

That'll provide some type guarantees.

- James


On 9 May 2014 00:28, Joseph Rollins  wrote:

> I am confused about the best way to assure that I am dealing with a vector
> when dealing with core library functions that often return seq where I then
> lose my ability to access it using associative accesses (get-in
> specifically).
>
> My particular use case is as follows:
>
> I am modeling a matrix as nested vectors
>
> [[0 0 0] [0 1 1] [0 1 1]]
>
> represents
>
> 0 0 0
> 0 1 1
> 0 1 1
>
> I know matrix libraries exist, but for the sake of learning am rolling my
> own functionality.  I have several functions that operate on this:
>
> (defn transpose [piece]
>   (apply mapv vector piece))
>
> (defn translate-block
>   ([mm]   (let [one? #(if (= 1 %) true false)]
> (translate-block mm one?)))
>   ([mm f] (map #(map f %) mm)))
>
> (defn rotate-left [b]
>   (->> b
>transpose
>reverse))
>
> The problem I am running into is that these do not output nested vectors,
> but nested seqs (due to all of the map operations). I am using these
> matrices to program Tetris, and I am writing a function that takes a Tetris
> block, a Tetris board (both represented as matrices) and a position of the
> block inside the board. The function is supposed to determine if the
> placement of the block is valid (not overlapping already placed blocks:
>
> (defn is-valid?
>   "Determine if a game state is valid (is current piece place-able)."
>   [{board :board {:keys [piece pos]} :piece}]
>   (let [[x y] pos
> coords (for [rows (range (count piece))
>  cols (range (count (first piece)))]
>  [[rows cols] [(+ y rows) (+ x cols)]])]
> (map (fn [[c cc]]
>(and (get-in board cc) (get-in piece c)))
>  coords)))
>
> The matrices hold true and false values for if occupied. When testing this
> function I realized get-in was just returning nil because it wouldnt get in
> a seq (non-associative).  What is the best way to assure that when I need
> associative guarantees that they haven't been thrown away through previous
> transformations of the board or piece matrices?
>
> The two choices I see are making sure every function that operates on the
> matrices explicitly outputs nested vectors again, or transforming the input
> to functions that need the guarantees to nested vectors explicitly. Am I
> missing something here, or, if not, what is the idiomatic way to solve this
> problem?
>
> Thanks
>
> -Joseph
>
> --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Tag classes required to be imported?

2014-05-08 Thread Colin Fleming
Thanks Andy. Actually it looks like
CLJ-1232is the exact
problem in Clojure (linked from
TANAL-24 ).


On 9 May 2014 00:48, Andy Fingerhut  wrote:

> Forgot to mention, the type tag should work without having to import it
> into the require'ing namespace if you fully qualify it where the tag is
> used.
>
> Andy
>
>
> On Thu, May 8, 2014 at 5:47 AM, Andy Fingerhut 
> wrote:
>
>> This issue has been discovered before, at least in the context of the
>> tools.analyzer library, and there was an ensuing discussion on the
>> clojure-dev email list linked in the comments of this ticket:
>>
>> http://dev.clojure.org/jira/browse/TANAL-24
>>
>> I do not recall whether there was a Clojure ticket filed for it or not.
>>
>> Andy
>>
>>
>> On Wed, May 7, 2014 at 9:55 PM, Colin Fleming <
>> colin.mailingl...@gmail.com> wrote:
>>
>>> Hi all,
>>>
>>> I just came across a case with AOT compilation that I haven't seen
>>> before. I have the following code:
>>>
>>> (defn clojurescript? [element]
>>>   (or (.isKindOf (psi/language element)
>>> (ClojurescriptLanguage/getInstance))
>>>   (.isKindOf (psi/language element) (CljxLanguage/getInstance
>>>
>>> psi/language looks like this:
>>>
>>> (defn language ^Language [^PsiElement element]
>>>   (.getLanguage element))
>>>
>>> This gives me the following error when compiling:
>>>
>>> Caused by: java.lang.IllegalArgumentException: Unable to resolve
>>> classname: Language
>>> at clojure.lang.Compiler$HostExpr.tagToClass(Compiler.java:1060)
>>> at clojure.lang.Compiler$InvokeExpr.getJavaClass(Compiler.java:3567)
>>> at
>>> clojure.lang.Compiler$InstanceMethodExpr.(Compiler.java:1393)
>>> at clojure.lang.Compiler$HostExpr$Parser.parse(Compiler.java:952)
>>> at clojure.lang.Compiler.analyzeSeq(Compiler.java:6560)
>>>
>>> I can get rid of this error importing Language into the original
>>> namespace. But I didn't expect this - does this mean that an import is
>>> required for the tag type of any function used in a particular namespace?
>>> Does this also apply to argument tags?
>>>
>>> Thanks,
>>> Colin
>>>
>>> --
>>> 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 unsubscribe from this group and stop receiving emails from it, send
>>> an email to clojure+unsubscr...@googlegroups.com.
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
>>
>  --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: Assuring dealing with PersistentVector for associative accesses

2014-05-08 Thread Joseph Rollins
Thanks, I haven't used pre and post conditions before but this seems like a 
good place to start.

On Thursday, May 8, 2014 8:17:53 PM UTC-4, James Reeves wrote:
>
> If you're representing a matrix with vectors, then any public function 
> that operates on a matrix should return vectors.
>
> You may want to consider a function like:
>
> (defn matrix? [m]
>   (and (vector? m)
>(every? vector m)
>(apply = (count m) (map count m)))
>
> Then add it as a pre and post condition:
>
> (defn transpose [m]
>   {:pre [(matrix? m)] :post [(matrix? %)]}
>   (apply mapv vector m))
>  
> That'll provide some type guarantees.
>
> - James
>
>
> On 9 May 2014 00:28, Joseph Rollins >wrote:
>
>> I am confused about the best way to assure that I am dealing with a 
>> vector when dealing with core library functions that often return seq where 
>> I then lose my ability to access it using associative accesses (get-in 
>> specifically).
>>
>> My particular use case is as follows:
>>
>> I am modeling a matrix as nested vectors
>>
>> [[0 0 0] [0 1 1] [0 1 1]]
>>
>> represents
>>
>>  0 0 0
>> 0 1 1
>> 0 1 1
>>
>> I know matrix libraries exist, but for the sake of learning am rolling my 
>> own functionality.  I have several functions that operate on this:
>>
>> (defn transpose [piece]
>>   (apply mapv vector piece))
>>
>> (defn translate-block
>>   ([mm]   (let [one? #(if (= 1 %) true false)]
>> (translate-block mm one?)))
>>   ([mm f] (map #(map f %) mm)))
>>
>> (defn rotate-left [b]
>>   (->> b
>>transpose
>>reverse))
>>
>> The problem I am running into is that these do not output nested vectors, 
>> but nested seqs (due to all of the map operations). I am using these 
>> matrices to program Tetris, and I am writing a function that takes a Tetris 
>> block, a Tetris board (both represented as matrices) and a position of the 
>> block inside the board. The function is supposed to determine if the 
>> placement of the block is valid (not overlapping already placed blocks:
>>
>> (defn is-valid?
>>   "Determine if a game state is valid (is current piece place-able)."
>>   [{board :board {:keys [piece pos]} :piece}]
>>   (let [[x y] pos
>>  coords (for [rows (range (count piece))
>>  cols (range (count (first piece)))]
>>  [[rows cols] [(+ y rows) (+ x cols)]])]
>> (map (fn [[c cc]]
>>(and (get-in board cc) (get-in piece c)))
>>  coords)))
>>
>> The matrices hold true and false values for if occupied. When testing 
>> this function I realized get-in was just returning nil because it wouldnt 
>> get in a seq (non-associative).  What is the best way to assure that when I 
>> need associative guarantees that they haven't been thrown away through 
>> previous transformations of the board or piece matrices?
>>
>> The two choices I see are making sure every function that operates on the 
>> matrices explicitly outputs nested vectors again, or transforming the input 
>> to functions that need the guarantees to nested vectors explicitly. Am I 
>> missing something here, or, if not, what is the idiomatic way to solve this 
>> problem?
>>
>> Thanks
>>
>> -Joseph
>>
>> -- 
>> You received this message because you are subscribed to the Google
>> Groups "Clojure" group.
>> To post to this group, send email to clo...@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+u...@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 unsubscribe from this group and stop receiving emails from it, send an 
>> email to clojure+u...@googlegroups.com .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
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 unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: executing conditional if like iif from other languages

2014-05-08 Thread Atamert Ölçgen
On Fri, May 9, 2014 at 5:44 AM, Don Hill  wrote:

> I am trying to get a couple of edge cases to past and since I am very new
> to clojure/lisp (2 days total) I thought I would ask.
>
>
> I am using defmacro like the following. I have 2 edge case which are
> failing. I would like to be able to process these cases where there are
> extra bits and as you probably guessed the last 2 entries have keys with
> not value. I don't thinks the :keys will work for these cases.
>
> Any ideas on how I could destruct this so all the cases would pass?
>
> (defmacro iif [expr & {:keys [then, else]}]
> `(if ~expr ~then ~else))
>
> (println(iif (> 3 1))) ;nil
> (println(iif (> 3 1) :then 'ok)) ;ok
> (println(iif (< 5 3) :else 'ok)) ;ok
> (println(iif (> 3 1) :else 'oops)) ;nil
>
> (println(iif (> 3 1) :else 'oops :then 'ok));ok
> ;;(println(iif (> 3 1) :then )) ;nil
>

Why do you want to support odd number of params after `expr`?

How would you expect this to work:

(iif expr :then :else) -> ???



> ;;(println(multi-if (> 3 1) :else 'oops :then (println'hi) 'ok)) ;;hi ok
>

I don't know what the implementation of multi-if looks like but the odd
number of args after expr doesn't seem right to me.

One last question; why are the branching code named/as a map? Why not
(defmacro iif [expr then else]) which is equal to if or course?

(if (> 3 1) nil nil) -> nil
(if (< 5 3) nil 'ok) -> 'ok

...and so on.





>
>  --
> 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 unsubscribe from this group and stop receiving emails from it, send an
> email to clojure+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>



-- 
Kind Regards,
Atamert Ölçgen

-+-
--+
+++

www.muhuk.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
--- 
You received this message because you are subscribed to the Google Groups 
"Clojure" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.