Steven E. Harris | 1 Mar 2010 01:16
Picon
Favicon
Gravatar

Re: difference between if/when

Richard Newman <holygoat <at> gmail.com> writes:

> Incidentally, I initially didn't know about `when-not` -- I figured
> that `unless` had simply been omitted -- so I defined:
>
> (defmacro unless [pred & body]
>   `(when (not ~pred) ~ <at> body))

I did the same, and then was frustrated enough to dig through the core
API documentation. Finding `when-not' was nice, but the name still
doesn't work for me. Per your/our macro above, it's not really different
enough from `when' and `not' to warrant another name.

-- 
Steven E. Harris

--

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure <at> 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+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

MarkSwanson | 1 Mar 2010 03:19
Picon

Re: bug: clojure.contrib.json should not default to use keywords.


On Feb 28, 10:34 am, joshua-choi <rbysam... <at> gmail.com> wrote:
> As a small note, according tohttp://clojure.org/reader, Clojure
> keywords and symbols are allowed to contain only alphanumeric
> characters, *, +, !, -, _, and ?. Spaces aren’t allowed, but the
> keyword function allows them anyway because it doesn’t do any checking
> for validity for performance. I’m told that it’s up to the programmer
> to make sure that only valid keywords are created.

Thanks for those details.

> I agree that clojure.contrib.json should default to string keys,
> because keywords are so limited. The thing is, when
> clojure.contrib.json *does* convert JSON keys into Clojure keywords,
> should it check for validity and fail when it cannot create a valid
> keyword?

I personally would really appreciate the check, and fail with a sane
message.

Ultimately, I believe that allowing keywords to be created that
violate the language spec is an error and a meaningful error should be
thrown.
I believe correctness should be more important than speed when core
language functionality is concerned.

The current situation is that I can legally create Clojure structs
that fail to serialize correctly. This is a fundamental component of
the language that simply must work correctly. If not, incidental
complexity is increased.
(Continue reading)

Richard Newman | 1 Mar 2010 03:26
Picon

Re: bug: clojure.contrib.json should not default to use keywords.

> For an example outside of JSON: recently Compojure changed how it
> works so the HTTP request properties are all converted to keywords by
> default. I can see the appeal, but now anyone using Compojure has the
> increased incidental complexity of possible keyword violations.
> Imagine if you were integrating with PayPal or some system that had
> HTTP parameters with characters that were not allowed by the Clojure
> spec. I really don't want to worry about such things when creating
> software with Clojure.

Per RFC2616, HTTP headers are named by "token"s:

   token      = 1*<any CHAR except CTLs or separators>
   CHAR       = <any US-ASCII character (octets 0 - 127)>
   CTL        = <any US-ASCII control character (octets 0 - 31) and  
DEL (127)>
   separators = "(" | ")" | "<" | ">" | " <at> " | "," | ";" | ":" | "\" |  
<"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT

As far as I can see, all valid HTTP headers are thus valid Clojure  
keywords. You don't have to worry.

-R

--

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure <at> 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+unsubscribe <at> googlegroups.com
(Continue reading)

Yaron | 1 Mar 2010 03:36
Picon

Re: newbie question: Please help me stop creating constructors

Richard, I spent quite a bit of time thinking about what you said.

So I rewrote the whole kit and kaboodle. My understanding of your mail
led me to take the approach of defining functions who take as
arguments the invariant values and who output functions that take
variant values. For example:

(defn house-sale-profit
 [house-sales-price house-sale-expenses]
 (fn [m]
  (- (house-sales-price m) (house-sale-expenses m))))

In this example both house-sales-price and house-sale-expenses are
actually themselves functions which I would have had to have called
previously to get their instance functions and passed in as arguments.

To test out this idea I decided to implement all the functions needed
to implement the sell function from my paper. But when I was done and
wanted to actually calculate a sell value I had to write something
like:

(defn sell-calculator
 [{:keys [real-monthly-opportunity-cost months-to-find-tenant months-
in-lease lease-cycles months-to-sell excise-tax
    months-in-loan original-loan-amount monthly-loan-interest other-
sales-fees-0 monthly-inflation-rate
    selling-agent-fee-type selling-agent-fee-number buying-agent-fee-
type buying-agent-fee-number
    house-sales-price-0 loan-month-at-start]}]
 (let [inflate (inflate monthly-inflation-rate)
(Continue reading)

cej38 | 1 Mar 2010 04:23
Picon

Re: newbie code (genetic programming) and questions (dev environments)


>
> - When I run clj (from the most recent ClojureX) on the command line with -i and a source file it runs the file
but then hangs. If I also specify -r then I get a REPL after the file runs, which is nice, but I was hoping that
without -r it would terminate and return to a shell prompt without requiring an interrupt. I don't see any
options to clj or to Clojure's main that force termination, or any quit or exit functions that I could call
myself at the end of my code... Am I missing something here?
>

When I run clojure as a script, I use the following command to
terminate the clojure instance:
(System/exit 0)

--

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure <at> 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+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

David Nolen | 1 Mar 2010 07:14
Picon

Re: newbie code (genetic programming) and questions (dev environments)

On Sun, Feb 28, 2010 at 2:38 PM, Lee Spector <lspector <at> hampshire.edu> wrote:

On the development environment front: Is anyone contemplating creating a Mac OS X "Clojure in a Box"? I would be an enthusiastic user. If it could have roughly the feature set of the old Macintosh Common Lisp IDE then I would be ecstatic. Despite a fair amount of tinkering I don't currently have a functional SLIME setup, and despite the nice screencasts for Eclipse/Counterclockwise (and very nice features it seems to have -- e.g. the namespace browser and integrated documentation... is there any environment that has a debugging environment approximating a Lisp break loop?) that's not really working for me yet either. (A few specifics: In emacs, using a variety of configuration instructions and hints from the web, I get syntax coloring and indentation but not a functional inferior Lisp mode. Eclipse is a bit confusing to me overall, I can't seem to figure out how to get Clojure indenting, and it seems to be re-evaluating my buffers without me asking it to :-(. And saving an awful lot of files to its workspace directory.) I'm not only interested in getting one of these environments working on my own machine -- although that would be nice -- but also in having a simple, repeatable sequence of instructions for getting the environment running on fresh machines. This is because I teach and I may want to use this on classroom machines, student machines, etc., with students who have various levels of expertise. Our students use all sorts of platforms but our teaching environment is Mac OS X (with a linux cluster for compute-intensive stuff).

I just wrote some instructions for setting up Aquamacs with Clojure here http://www.formconstant.net/diagrams/?p=54. While it's not "Clojure in a Box", it's pretty simple and really doesn't take much more than a few minutes to get through.

David

--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure <at> 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+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
reynard | 1 Mar 2010 08:03
Picon

Does/will clojure run on ARM based smartbook?

Anyone has first hand experience?  Thanks.

--

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure <at> 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+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Konrad Hinsen | 1 Mar 2010 08:52
Gravatar

Re: newbie code (genetic programming) and questions (dev environments)

On 28 Feb 2010, at 20:38, Lee Spector wrote:

> that just published a special issue on parallel evolutionary  
> algorithms, so I know of a lot of options there! -- but for now I  
> just want the basic generational algorithm to be expressed as  
> naturally as possible in Clojure. There seem to be many other  
> options for how to do this using Clojure's concurrency concepts...  
> Does what I've done seem to be the natural Clojure approach?

To me, yes. Another option would be to store the programs in each  
generation in a standard vector and run the evaluation and breeding  
functions in a (future ...). Compared to agents, you would gain the  
advantage of controlling the number of threads being used, so you  
could optimize for performance. On the downside, you pretty much have  
to define the number of threads yourself as well, so you might lose in  
simplicity and clarity.

> On the development environment front: Is anyone contemplating  
> creating a Mac OS X "Clojure in a Box"? I would be an enthusiastic  
> user. If it could have roughly the feature set of the old Macintosh  
> Common Lisp IDE

If that's MCLIDE you are talking about, a version with partial Clojure  
support has just been announced:

	http://mclide.in-progress.com/

Konrad.

--

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure <at> 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+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Richard Newman | 1 Mar 2010 08:55
Picon

Re: newbie question: Please help me stop creating constructors

> So I rewrote the whole kit and kaboodle. My understanding of your mail
> led me to take the approach of defining functions who take as
> arguments the invariant values and who output functions that take
> variant values. For example:

I'm not sure how much functional programming experience you have, but  
you've essentially discovered a kind of currying.

http://en.wikipedia.org/wiki/Currying

That is, you're taking a function house-sale-profit, in terms of house- 
sales-price (a function), house-sale-expenses (a function), and m, and  
fixing the first two values, returning a function in terms of m.

This is seamless in Haskell; less so in Clojure. See the built-in  
function `partial`.

When you wrote

   (defn house-sale-profit
     [house-sales-price house-sale-expenses]
     (fn [m]
       (- (house-sales-price m) (house-sale-expenses m))))

and used it like this:

   (let [...
         house-sale-profit-fn (house-sale-profit house-sales-price  
house-sale-expenses)
         ...]
     ...)

you could just as easily have written:

   (defn house-sale-profit
     [house-sales-price house-sale-expenses m]
     (- (house-sales-price m) (house-sale-expenses m)))

and used it like this:

   (let [...
         house-sale-profit-fn (partial house-sale-profit house-sales- 
price house-sale-expenses)
         ...]
     ...)

This makes house-sale-profit a perfectly normal function, but still  
allows you to partially evaluate it to yield a closure.

> In this example both house-sales-price and house-sale-expenses are
> actually themselves functions which I would have had to have called
> previously to get their instance functions and passed in as arguments.

By doing this you're pretty much writing your own interpreter, as you  
figured out :)

> So is this the way you would approach this problem in Clojure?

No. (However, consider that I'm as likely to be wrong as anybody else,  
and also that you're learning a ton by trying different approaches!)

I would do things much more simply: rather than (to take your example)  
defining house-sale-profit in terms of two functions and a month  
value, which is threaded into those functions (providing opportunity  
for breakage should the signature of, say, house-sales-price change),  
I would simply *define house-sale-profit in terms of the sales price  
and expenses*. Rely on the price and the expenses having been  
calculated outside the function.

No nonsense with throw-if-in-seq and all the other complicated  
machinery you have built.

   (defn house-sale-profit
     [house-sales-price house-sale-expenses]
     (- house-sales-price house-sale-expenses))

This is the literal definition of profit; you can write tests for this  
with just two numbers. If your expenses don't care about a number of  
months, or they care about something else, then just pass in a  
different value -- no futzing with functions. It's more efficient, too  
-- no anonymous functions.

For a single invocation you're only using one value of m, with one  
house sales price, and one set of expenses. Just put them in the let!

(let [m <from the user>
       price ...
       expenses ...
       profit (house-sale-profit price expenses)
       ...]
   ...)

I've done this for some of your functions:

	<http://twinql.com/tmp/rent.clj>

I haven't tried actually using it to compute anything, but it should  
give you an idea of the style I'd use.

I would guess that the whole program, neatly laid out and commented,  
should come to only a couple hundred lines. Each individual function  
is trivially testable and reusable, as is every composition of  
functions that goes into computing the final answer.

If you want to be neater, split `sell-calculator` into two or more  
functions; perhaps one which walks through the rent calculation, and  
another which walks through the house sale calculation. That way each  
individual function remains short and sweet.

Note that I still curry some functions (e.g., inflate), and if I  
bothered to implement the agent fees (which are inflation-linked) I  
might do it by passing in that curried `inflate` function. (Then  
again, I might not, if I can phrase them in terms of constant values  
which are computed elsewhere.) Most of the intermediate values are  
simply computed directly.

Note also that, if you wished, you could completely eliminate the  
`let` form, turning this whole calculation into a single (slightly  
redundant) tree. I don't advocate that as particularly good style, but  
it's possible.

Ultimately, all you're doing here is writing a set of functions and  
combining them together to produce an answer: a simple matter of  
traditional programming. It's not rocket surgery (as they say  
nowadays), and so any solution which requires you to write code to  
detect recursive calls, look up function names at runtime, manage a  
huge intermediate map of results, etc. is probably a sign that you're  
over-engineering things.

I would have used almost the same technique in, say, Pascal: define a  
bunch of functions, and use a bunch of local variables in the calling  
function to store intermediate values; gradually work towards the  
final answer. Clojure can make this simpler (using macros, higher- 
order functions, partial evaluation, and so on), but it doesn't really  
change the nature of the work.

(Of course, traditional imperative languages would have given you a  
mutable global chalkboard on which to play concurrency Hangman, but  
for a one-time calculator that's no real problem.)

Sure, if you had a hundred thousand intermediate results, and a  
thousand inputs, you wouldn't do it this way... but if that were true,  
I'd be advising you to use a tool which is more suited, such as a  
spreadsheet or some other dataflow system.

HTH.

-R

--

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure <at> 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+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en

Alex Osborne | 1 Mar 2010 09:07
Gravatar

Re: Does/will clojure run on ARM based smartbook?

reynard <atsang71 <at> gmail.com> writes:

> Anyone has first hand experience?  Thanks.

I tried it on a cheapo 200Mhz ARM926EJ-S based NAS (WD MyBook World)
under JamVM [1] and it runs but very, very slowly (takes 35 seconds to
start a REPL).  On a more powerful ARM chip (say an OMAP3) it might
be much more usable.

--

-- 
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clojure <at> 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+unsubscribe <at> googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en


Gmane